parent
666e18c57e
commit
3a5ac05d9d
@ -1,49 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
import datetime |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
# this script captures lightnings and stores them to npy files |
||||
|
||||
# ADC channel 1 -> 100n -> o -> long wire (antenna) |
||||
# | |
||||
# '-> 10k -> GND |
||||
|
||||
led = None |
||||
|
||||
def capture(tr): |
||||
now=datetime.datetime.now() |
||||
now.isoformat() |
||||
data = tr.data |
||||
print("Capture! ") |
||||
print(data) |
||||
np.save("lightning-%s"%now.isoformat(), data) |
||||
led.pulse_ms(1000, confirm=False) |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
adc = gex.ADC(client, 'adc') |
||||
led = gex.DOut(client, 'led') |
||||
|
||||
adc.set_sample_rate(60000) |
||||
|
||||
adc.on_trigger(capture) |
||||
adc.setup_trigger(1, |
||||
level=2600, |
||||
count=5000, |
||||
edge='rising', |
||||
pretrigger=500, |
||||
holdoff=500, |
||||
auto=True) |
||||
|
||||
adc.arm() |
||||
|
||||
sec = 0 |
||||
while True: |
||||
print('%d s' % sec) |
||||
sec += 1 |
||||
time.sleep(1) |
@ -1,36 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
import time |
||||
|
||||
# simple demo with the dot matrix phat |
||||
|
||||
ADDR = 0x61 |
||||
MODE = 0b00011000 |
||||
OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA |
||||
|
||||
CMD_BRIGHTNESS = 0x19 |
||||
CMD_MODE = 0x00 |
||||
CMD_UPDATE = 0x0C |
||||
CMD_OPTIONS = 0x0D |
||||
|
||||
CMD_MATRIX_1 = 0x01 |
||||
CMD_MATRIX_2 = 0x0E |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
bus = gex.I2C(client, 'i2c') |
||||
addr = 0x61 |
||||
bus.write_reg(addr, CMD_MODE, MODE) |
||||
bus.write_reg(addr, CMD_OPTIONS, OPTS) |
||||
bus.write_reg(addr, CMD_BRIGHTNESS, 64) |
||||
|
||||
bus.write(addr, [CMD_MATRIX_1, |
||||
0xAA,0x55,0xAA,0x55, |
||||
0xAA,0x55,0xAA,0x55, |
||||
]) |
||||
|
||||
bus.write(addr, [CMD_MATRIX_2, |
||||
0xFF, 0, 0xFF, 0, |
||||
0xFF, 0, 0xFF, 0, |
||||
]) |
||||
|
||||
bus.write_reg(addr, CMD_UPDATE, 0x01) |
@ -1,200 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import random |
||||
|
||||
import gex |
||||
import time |
||||
|
||||
# This is an adaptation of the micro dot phat library |
||||
# - the only change needed was replacing the smbus class with the GEX unit driver |
||||
|
||||
ADDR = 0x61 |
||||
MODE = 0b00011000 |
||||
OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA |
||||
|
||||
CMD_BRIGHTNESS = 0x19 |
||||
CMD_MODE = 0x00 |
||||
CMD_UPDATE = 0x0C |
||||
CMD_OPTIONS = 0x0D |
||||
|
||||
CMD_MATRIX_1 = 0x01 |
||||
CMD_MATRIX_2 = 0x0E |
||||
|
||||
MATRIX_1 = 0 |
||||
MATRIX_2 = 1 |
||||
|
||||
class NanoMatrix: |
||||
''' |
||||
_BUF_MATRIX_1 = [ # Green |
||||
#Col 1 2 3 4 5 |
||||
0b00000000, # Row 1 |
||||
0b00000000, # Row 2 |
||||
0b00000000, # Row 3 |
||||
0b00000000, # Row 4 |
||||
0b00000000, # Row 5 |
||||
0b00000000, # Row 6 |
||||
0b10000000, # Row 7, bit 8 = decimal place |
||||
0b00000000 |
||||
] |
||||
_BUF_MATRIX_2 = [ # Red |
||||
#Row 8 7 6 5 4 3 2 1 |
||||
0b01111111, # Col 1, bottom to top |
||||
0b01111111, # Col 2 |
||||
0b01111111, # Col 3 |
||||
0b01111111, # Col 4 |
||||
0b01111111, # Col 5 |
||||
0b00000000, |
||||
0b00000000, |
||||
0b01000000 # bit 7, decimal place |
||||
] |
||||
_BUF_MATRIX_1 = [0] * 8 |
||||
_BUF_MATRIX_2 = [0] * 8 |
||||
''' |
||||
|
||||
def __init__(self, bus:gex.I2C, address=ADDR): |
||||
self.address = address |
||||
self._brightness = 127 |
||||
|
||||
self.bus = bus |
||||
|
||||
self.bus.write_byte_data(self.address, CMD_MODE, MODE) |
||||
self.bus.write_byte_data(self.address, CMD_OPTIONS, OPTS) |
||||
self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness) |
||||
|
||||
self._BUF_MATRIX_1 = [0] * 8 |
||||
self._BUF_MATRIX_2 = [0] * 8 |
||||
|
||||
def set_brightness(self, brightness): |
||||
self._brightness = int(brightness * 127) |
||||
if self._brightness > 127: self._brightness = 127 |
||||
|
||||
self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness) |
||||
|
||||
def set_decimal(self, m, c): |
||||
|
||||
if m == MATRIX_1: |
||||
if c == 1: |
||||
self._BUF_MATRIX_1[6] |= 0b10000000 |
||||
else: |
||||
self._BUF_MATRIX_1[6] &= 0b01111111 |
||||
|
||||
elif m == MATRIX_2: |
||||
|
||||
if c == 1: |
||||
self._BUF_MATRIX_2[7] |= 0b01000000 |
||||
else: |
||||
self._BUF_MATRIX_2[7] &= 0b10111111 |
||||
|
||||
#self.update() |
||||
|
||||
def set(self, m, data): |
||||
for y in range(7): |
||||
self.set_row(m, y, data[y]) |
||||
|
||||
def set_row(self, m, r, data): |
||||
for x in range(5): |
||||
self.set_pixel(m, x, r, (data & (1 << (4-x))) > 0) |
||||
|
||||
def set_col(self, m, c, data): |
||||
for y in range(7): |
||||
self.set_pixel(m, c, y, (data & (1 << y)) > 0) |
||||
|
||||
def set_pixel(self, m, x, y, c): |
||||
|
||||
if m == MATRIX_1: |
||||
if c == 1: |
||||
self._BUF_MATRIX_1[y] |= (0b1 << x) |
||||
else: |
||||
self._BUF_MATRIX_1[y] &= ~(0b1 << x) |
||||
elif m == MATRIX_2: |
||||
if c == 1: |
||||
self._BUF_MATRIX_2[x] |= (0b1 << y) |
||||
else: |
||||
self._BUF_MATRIX_2[x] &= ~(0b1 << y) |
||||
|
||||
#self.update() |
||||
|
||||
def clear(self, m): |
||||
if m == MATRIX_1: |
||||
self._BUF_MATRIX_1 = [0] * 8 |
||||
elif m == MATRIX_2: |
||||
self._BUF_MATRIX_2 = [0] * 8 |
||||
|
||||
self.update() |
||||
|
||||
def update(self): |
||||
for x in range(10): |
||||
try: |
||||
self.bus.write_i2c_block_data(self.address, CMD_MATRIX_1, self._BUF_MATRIX_1) |
||||
self.bus.write_i2c_block_data(self.address, CMD_MATRIX_2, self._BUF_MATRIX_2) |
||||
|
||||
self.bus.write_byte_data(self.address, CMD_UPDATE, 0x01) |
||||
break |
||||
except IOError: |
||||
print("IO Error") |
||||
|
||||
|
||||
|
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
bus = gex.I2C(client, 'i2c') |
||||
|
||||
n1 = NanoMatrix(bus, 0x61) |
||||
n2 = NanoMatrix(bus, 0x62) |
||||
n3 = NanoMatrix(bus, 0x63) |
||||
|
||||
n1.set_pixel(0, 0, 0, 1) |
||||
n1.set_pixel(0, 4, 0, 1) |
||||
n1.set_pixel(0, 0, 6, 1) |
||||
n1.set_pixel(0, 4, 6, 1) |
||||
|
||||
n1.set_pixel(1, 0, 0, 1) |
||||
n1.set_pixel(1, 4, 0, 1) |
||||
n1.set_pixel(1, 0, 3, 1) |
||||
n1.set_pixel(1, 4, 3, 1) |
||||
|
||||
n2.set_pixel(0, 0, 2, 1) |
||||
n2.set_pixel(0, 4, 2, 1) |
||||
n2.set_pixel(0, 0, 5, 1) |
||||
n2.set_pixel(0, 4, 5, 1) |
||||
|
||||
n2.set_pixel(1, 0, 0, 1) |
||||
n2.set_pixel(1, 4, 0, 1) |
||||
n2.set_pixel(1, 0, 6, 1) |
||||
n2.set_pixel(1, 4, 6, 1) |
||||
|
||||
|
||||
n3.set_pixel(0, 1, 0, 1) |
||||
n3.set_pixel(0, 3, 0, 1) |
||||
n3.set_pixel(0, 1, 6, 1) |
||||
n3.set_pixel(0, 3, 6, 1) |
||||
|
||||
n3.set_pixel(1, 1, 1, 1) |
||||
n3.set_pixel(1, 3, 1, 1) |
||||
n3.set_pixel(1, 1, 5, 1) |
||||
n3.set_pixel(1, 3, 5, 1) |
||||
|
||||
n1.update() |
||||
n2.update() |
||||
n3.update() |
||||
|
||||
b1 = 64 |
||||
b2 = 64 |
||||
b3 = 64 |
||||
|
||||
while True: |
||||
b1 += random.randint(-20, 15) |
||||
b2 += random.randint(-20, 18) |
||||
b3 += random.randint(-15, 13) |
||||
|
||||
if b1 < 0: b1 = 0 |
||||
if b2 < 0: b2 = 0 |
||||
if b3 < 0: b3 = 0 |
||||
if b1 > 127: b1 = 127 |
||||
if b2 > 127: b2 = 127 |
||||
if b3 > 127: b3 = 127 |
||||
|
||||
n1.set_brightness(b1) |
||||
n2.set_brightness(b2) |
||||
n3.set_brightness(b3) |
||||
|
||||
time.sleep(0.05) |
@ -1,35 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
|
||||
# frequency response measurement |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
dac = gex.DAC(client, 'dac') |
||||
adc = gex.ADC(client, 'adc') |
||||
|
||||
dac.waveform(1, 'SINE') |
||||
adc.set_sample_rate(50000) |
||||
|
||||
table = [] |
||||
|
||||
for i in range(100, 10000, 100): |
||||
dac.set_frequency(1, i) |
||||
data = adc.capture(10000) |
||||
# convert to floats |
||||
samples = data.astype(float) |
||||
amplitude = np.max(samples) - np.min(samples) |
||||
print("%d Hz ... rms %d" % (i, amplitude)) |
||||
table.append(i) |
||||
table.append(amplitude) |
||||
|
||||
dac.dc(1, 0) |
||||
|
||||
t = np.reshape(np.array(table), [int(len(table)/2),2]) |
||||
hz = t[:,0] |
||||
am = t[:,1] |
||||
|
||||
plt.plot(hz, am, 'r-', lw=1) |
||||
plt.grid() |
||||
plt.show() |
@ -1,23 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
|
||||
# experiment with the dot matrix driver |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
bus = gex.I2C(client, 'i2c') |
||||
addr = 0x61 |
||||
bus.write_reg(addr, 0x00, 0b00011000) # dual matrix |
||||
bus.write_reg(addr, 0x0D, 0b00001110) # 34 mA |
||||
bus.write_reg(addr, 0x19, 64) # set brightness |
||||
# matrix 1 |
||||
bus.write_reg(addr, 0x01, [ |
||||
0xAA, 0x55, 0xAA, 0x55, |
||||
0xAA, 0x55, 0xAA, 0x55 |
||||
]) |
||||
# matrix 2 |
||||
bus.write_reg(addr, 0x0E, [ |
||||
0xFF, 0x00, 0xFF, 0x00, |
||||
0xFF, 0x00, 0xFF, 0x00 |
||||
]) |
||||
# update display |
||||
bus.write_reg(addr, 0x0C, 0x01) |
@ -1,213 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
import sx_fsk as sx |
||||
|
||||
|
||||
# we're demonstrating the use of the GFSK mode of the SX1278 |
||||
# this is an example of how GEX can be used to control a peripheral module - in this case evaluating |
||||
# it for use in GEX remote |
||||
|
||||
|
||||
class LoRa: |
||||
def __init__(self, |
||||
rst: gex.DOut, |
||||
spi: gex.SPI, ssnum): |
||||
self.ss = ssnum |
||||
self.rst = rst |
||||
self.spi = spi |
||||
|
||||
def reset(self): |
||||
self.rst.pulse_us(100, active=False) |
||||
time.sleep(0.005) |
||||
|
||||
def rd(self, addr): |
||||
return self.spi.query(self.ss, [addr], 1)[0] |
||||
|
||||
def wr(self, addr, value): |
||||
self.spi.write(self.ss, [addr | 0x80, value]) |
||||
|
||||
def rds(self, start, count=1): |
||||
return self.spi.query(self.ss, [start], count) |
||||
|
||||
def wrs(self, start, values): |
||||
ba = bytearray() |
||||
ba.append(start | 0x80) |
||||
ba.extend(values) |
||||
self.spi.write(self.ss, ba) |
||||
|
||||
def rmw(self, addr, keep, set): |
||||
""" rmw, first and-ing the register with mask and then oring with set """ |
||||
val = self.rd(addr) |
||||
self.wr(addr, (val & keep) | set) |
||||
|
||||
def waitModeSwitch(self): |
||||
while 0 == (self.rd(sx.REG_IRQFLAGS1) & sx.RF_IRQFLAGS1_MODEREADY): |
||||
time.sleep(0.001) |
||||
|
||||
def waitSent(self): |
||||
while 0 == (self.rd(sx.REG_IRQFLAGS2) & sx.RF_IRQFLAGS2_PACKETSENT): |
||||
time.sleep(0.001) |
||||
|
||||
def fsk_set_defaults(self): |
||||
# Set default values (semtech patches: * in DS) |
||||
self.rmw(sx.REG_RXCONFIG, |
||||
sx.RF_RXCONFIG_RXTRIGER_MASK, |
||||
sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT) |
||||
|
||||
self.wr(sx.REG_PREAMBLEDETECT, |
||||
sx.RF_PREAMBLEDETECT_DETECTOR_ON | |
||||
sx.RF_PREAMBLEDETECT_DETECTORSIZE_2 | |
||||
sx.RF_PREAMBLEDETECT_DETECTORTOL_10) |
||||
|
||||
self.rmw(sx.REG_OSC, sx.RF_OSC_CLKOUT_MASK, sx.RF_OSC_CLKOUT_OFF) |
||||
|
||||
self.rmw(sx.REG_FIFOTHRESH, |
||||
sx.RF_FIFOTHRESH_TXSTARTCONDITION_MASK, |
||||
sx.RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY) |
||||
|
||||
self.rmw(sx.REG_IMAGECAL, |
||||
sx.RF_IMAGECAL_AUTOIMAGECAL_MASK, |
||||
sx.RF_IMAGECAL_AUTOIMAGECAL_OFF) |
||||
|
||||
def configure_for_fsk(self, address): |
||||
self.rmw(sx.REG_OPMODE, |
||||
sx.RF_OPMODE_LONGRANGEMODE_MASK & sx.RF_OPMODE_MODULATIONTYPE_MASK & sx.RF_OPMODE_MASK, |
||||
sx.RF_OPMODE_LONGRANGEMODE_OFF | |
||||
sx.RF_OPMODE_MODULATIONTYPE_FSK | |
||||
sx.RF_OPMODE_STANDBY) |
||||
self.waitModeSwitch() |
||||
|
||||
self.fsk_set_defaults() |
||||
self.wr(sx.REG_NODEADRS, address) |
||||
self.wr(sx.REG_BROADCASTADRS, 0xFF) |
||||
# use whitening and force address matching |
||||
self.rmw(sx.REG_PACKETCONFIG1, |
||||
sx.RF_PACKETCONFIG1_DCFREE_MASK & sx.RF_PACKETCONFIG1_ADDRSFILTERING_MASK, |
||||
sx.RF_PACKETCONFIG1_DCFREE_WHITENING | |
||||
sx.RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST) |
||||
|
||||
self.wr(sx.REG_RXCONFIG, |
||||
sx.RF_RXCONFIG_AFCAUTO_ON | |
||||
sx.RF_RXCONFIG_AGCAUTO_ON | |
||||
sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT) |
||||
|
||||
XTAL_FREQ = 32000000 |
||||
FREQ_STEP = 61.03515625 |
||||
FSK_FDEV = 60000 # Hz NOTE: originally: 25000, seems to help increasing |
||||
FSK_DATARATE = 200000 # bps - originally 50000 |
||||
|
||||
MAX_RFPOWER = 0 # 0-7 boost - this doesnt seem to have a huge impact |
||||
|
||||
FSK_PREAMBLE_LENGTH = 5 # Same for Tx and Rx |
||||
|
||||
fdev = round(FSK_FDEV / FREQ_STEP) |
||||
self.wr(sx.REG_FDEVMSB, fdev >> 8) |
||||
self.wr(sx.REG_FDEVLSB, fdev & 0xFF) |
||||
|
||||
datarate = round(XTAL_FREQ / FSK_DATARATE) |
||||
print("dr=%d"%datarate) |
||||
self.wr(sx.REG_BITRATEMSB, datarate >> 8) |
||||
self.wr(sx.REG_BITRATELSB, datarate & 0xFF) |
||||
|
||||
preamblelen = FSK_PREAMBLE_LENGTH |
||||
self.wr(sx.REG_PREAMBLEMSB, preamblelen >> 8) |
||||
self.wr(sx.REG_PREAMBLELSB, preamblelen & 0xFF) |
||||
|
||||
# bandwidths - 1 MHz |
||||
self.wr(sx.REG_RXBW, 0x0A) # FSK_BANDWIDTH |
||||
self.wr(sx.REG_AFCBW, 0x0A) # FSK_AFC_BANDWIDTH |
||||
|
||||
# max payload len to rx |
||||
self.wr(sx.REG_PAYLOADLENGTH, 0xFF) |
||||
|
||||
self.rmw(sx.REG_PARAMP, 0x9F, 0x40) # enable gauss 0.5 |
||||
|
||||
# pick the sync word size |
||||
self.rmw(sx.REG_SYNCCONFIG, |
||||
sx.RF_SYNCCONFIG_SYNCSIZE_MASK, |
||||
sx.RF_SYNCCONFIG_SYNCSIZE_3) |
||||
|
||||
# sync word (network ID) |
||||
self.wrs(sx.REG_SYNCVALUE1, [ |
||||
0xe7, 0x3d, 0xfa, 0x01, 0x5e, 0xa1, 0xc9, 0x98 # something random |
||||
]) |
||||
|
||||
# enable LNA boost (?) |
||||
self.rmw(sx.REG_LNA, |
||||
sx.RF_LNA_BOOST_MASK, |
||||
sx.RF_LNA_BOOST_ON) |
||||
|
||||
# experiments with the pa config |
||||
self.rmw(sx.REG_PACONFIG, |
||||
sx.RF_PACONFIG_PASELECT_MASK|0x8F, # max power mask |
||||
sx.RF_PACONFIG_PASELECT_PABOOST | MAX_RFPOWER<<4) |
||||
|
||||
# we could also possibly adjust the Tx power |
||||
|
||||
|
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
spi = gex.SPI(client, 'spi') |
||||
rst1 = gex.DOut(client, 'rst1') |
||||
rst2 = gex.DOut(client, 'rst2') |
||||
|
||||
a = LoRa(rst1, spi, 0) |
||||
b = LoRa(rst2, spi, 1) |
||||
|
||||
# reset the two transceivers to ensure they start in a defined state |
||||
a.reset() |
||||
b.reset() |
||||
|
||||
# go to sleep mode, select FSK |
||||
a.configure_for_fsk(0x33) |
||||
b.configure_for_fsk(0x44) |
||||
|
||||
print("Devices configured") |
||||
|
||||
for j in range(0, 240): |
||||
if(j>0 and j%60==0): |
||||
print() |
||||
|
||||
# --- Send a message from 1 to 2 --- |
||||
msg = [ |
||||
51, # len |
||||
0x44, # address |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, j |
||||
] |
||||
|
||||
a.wrs(sx.REG_FIFO, msg) |
||||
|
||||
b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_RECEIVER) |
||||
# time.sleep(0.005) |
||||
|
||||
# trigger A |
||||
a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_TRANSMITTER) |
||||
a.waitModeSwitch() |
||||
a.waitSent() |
||||
# time.sleep(0.02) |
||||
|
||||
# print("a irq flags = ", ["0x%02x"%x for x in a.rds(sx.REG_IRQFLAGS1, 2)]) |
||||
# print("b irq flags = ", ["0x%02x"%x for x in b.rds(sx.REG_IRQFLAGS1, 2)]) |
||||
|
||||
rxd = [b.rd(sx.REG_FIFO) for x in range(0,len(msg))] |
||||
if rxd == msg: |
||||
print("\x1b[32;1m+\x1b[0m", end="", flush=True) |
||||
else: |
||||
print("\x1b[31m-\x1b[0m", end="", flush=True) |
||||
# |
||||
# for i in range(0,8): |
||||
# print("0x%02x" % rxd[i],end=" ") |
||||
# print() |
||||
# print() |
||||
print() |
||||
|
||||
# good night |
||||
a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP) |
||||
b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP) |
||||
|
||||
|
@ -1,37 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# NDIR CO2 sensor showing the concentration on a SIPO-based LED display |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
ser = gex.USART(client, 'ser') |
||||
leds = gex.SIPO(client, 'leds') |
||||
|
||||
while True: |
||||
ser.clear_buffer() |
||||
ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79]) |
||||
data = ser.receive(9, decode=None) |
||||
|
||||
pp = gex.PayloadParser(data, endian="big").skip(2) |
||||
ppm = pp.u16() |
||||
|
||||
# The LEDs are connected to two 595's, interleaved R,G,R,G... |
||||
nl = (ppm-300)/1700.0 |
||||
print("%d ppm CO₂, numleds %f" % (ppm, nl*8)) |
||||
|
||||
numb = 0 |
||||
for i in range(0,8): |
||||
if nl >= i*0.125: |
||||
if i < 3: |
||||
numb |= 2<<(i*2) |
||||
elif i < 6: |
||||
numb |= 3<<(i*2) |
||||
else: |
||||
numb |= 1<<(i*2) |
||||
|
||||
leds.load([(numb&0xFF00)>>8,numb&0xFF]) |
||||
|
||||
|
||||
time.sleep(1) |
||||
|
@ -1,18 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# basic NDIR CO2 sensor readout |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
ser = gex.USART(client, 'ser') |
||||
|
||||
while True: |
||||
ser.clear_buffer() |
||||
ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79]) |
||||
data = ser.receive(9, decode=None) |
||||
|
||||
pp = gex.PayloadParser(data, endian="big").skip(2) |
||||
print("%d ppm CO₂" % pp.u16()) |
||||
|
||||
time.sleep(1) |
@ -1,17 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
import time |
||||
|
||||
# play a little neopixel animation as a demo |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
# Neopixel strip |
||||
strip = gex.Neopixel(client, 'npx') |
||||
# Load RGB to the strip |
||||
strip.load([0xFF0000, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF]) |
||||
|
||||
for i in range(0,255): |
||||
strip.load([0xFF0000+i, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF]) |
||||
time.sleep(0.01) |
||||
|
||||
strip.clear() |
@ -1,39 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
import time |
||||
|
||||
# this shows a spinny animation on a 30-pixel strip forming a circle |
||||
|
||||
def draw_comet(buf, index): |
||||
r = 0xFF |
||||
g = 0x22 |
||||
b = 0x00 |
||||
steps = 5 |
||||
fades = [0.05, 1, 0.5, 0.1, 0.05] |
||||
|
||||
for i in range(steps): |
||||
fade = fades[i] |
||||
buf[(len(buf) + index - i)%len(buf)] = \ |
||||
round(r * fade)<<16 | \ |
||||
round(g * fade)<<8 | \ |
||||
round(b * fade) |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
# Neopixel strip |
||||
strip = gex.Neopixel(client, 'npx') |
||||
|
||||
markers = [0, 15] |
||||
for i in range(1000): |
||||
buf = [0]*30 |
||||
for j in range(len(markers)): |
||||
n = markers[j] |
||||
|
||||
draw_comet(buf, n) |
||||
|
||||
n = n + 1 if n < len(buf)-1 else 0 |
||||
markers[j] = n |
||||
|
||||
strip.load(buf) |
||||
time.sleep(0.02) |
||||
|
||||
strip.clear() |
@ -1,11 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
|
||||
# the most basic neopixel demo |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
# Neopixel strip |
||||
strip = gex.Neopixel(client, 'npx') |
||||
# Load RGB to the strip |
||||
strip.load([0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF]) |
||||
|
@ -1,136 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
import sx_fsk as sx |
||||
|
||||
|
||||
# this is a demo with two NRF24L01+ modules connected to SPI and some GPIO. |
||||
|
||||
class Nrf: |
||||
def __init__(self, ce: gex.DOut, irq: gex.DIn, spi: gex.SPI, num): |
||||
self.snum = num |
||||
self.ce = ce |
||||
self.irq = irq |
||||
self.spi = spi |
||||
|
||||
def rd(self, addr, count=1): |
||||
# addr 0-31 |
||||
return self.spi.query(self.snum, [addr&0x1F], rlen=count) |
||||
|
||||
def wr(self, addr, vals): |
||||
if type(vals) == int: |
||||
vals = [vals] |
||||
|
||||
# addr 0-31 |
||||
ba = bytearray() |
||||
ba.append(addr | 0x20) |
||||
ba.extend(vals) |
||||
self.spi.write(self.snum, ba) |
||||
|
||||
def rd_payload(self, count): |
||||
""" Read a received payload """ |
||||
return self.spi.query(self.snum, [0x61], rlen=count) |
||||
|
||||
def wr_payload(self, pld): |
||||
""" Write a payload """ |
||||
ba = bytearray() |
||||
ba.append(0xA0) |
||||
ba.extend(pld) |
||||
self.spi.write(self.snum, ba) |
||||
|
||||
def flush_tx(self): |
||||
self.spi.write(self.snum, [0xE1]) |
||||
|
||||
def flush_rx(self): |
||||
self.spi.write(self.snum, [0xE2]) |
||||
|
||||
def reuse_tx_pld(self): |
||||
self.spi.write(self.snum, [0xE3]) |
||||
|
||||
def get_pld_len(self): |
||||
""" Read length of the first Rx payload in the FIFO - available only if dyn len enabled """ |
||||
return self.spi.query(self.snum, [0x60], rlen=1)[0] |
||||
|
||||
def wr_ack_payload(self, pipe, pld): |
||||
""" Write a payload to be attached to the next sent ACK """ |
||||
ba = bytearray() |
||||
ba.append(0xA8|(pipe&0x7)) |
||||
ba.extend(pld) |
||||
self.spi.write(self.snum, ba) |
||||
|
||||
def wr_payload_noack(self, pld): |
||||
""" Send a payload without ACK """ |
||||
ba = bytearray() |
||||
ba.append(0xB0) |
||||
ba.extend(pld) |
||||
self.spi.write(self.snum, ba) |
||||
|
||||
def status(self): |
||||
""" Send a payload without ACK """ |
||||
return self.spi.query(self.snum, [0xFF], rlen=1, rskip=0)[0] |
||||
|
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
spi = gex.SPI(client, 'spi') |
||||
ce = gex.DOut(client, 'ce') |
||||
irq = gex.DIn(client, 'irq') |
||||
|
||||
a = Nrf(ce, irq, spi, 0) |
||||
b = Nrf(ce, irq, spi, 1) |
||||
a.flush_tx() |
||||
a.flush_rx() |
||||
b.flush_tx() |
||||
b.flush_rx() |
||||
|
||||
# transmit demo |
||||
# a is PTX, b is PRX |
||||
ce.clear(0b11) |
||||
|
||||
# a_adr = [0xA1,0xA2,0xA3,0xA4,0x01] |
||||
b_pipe0_adr = [0xA1, 0xA2, 0xA3, 0xA4, 0x02] |
||||
|
||||
# --- Configure A for Tx of a 32-long payload --- |
||||
|
||||
# PWR DN - simulate reset |
||||
a.wr(0x00, 0) |
||||
b.wr(0x00, 0) |
||||
time.sleep(0.001) |
||||
|
||||
a.wr(0x00, 0b00001010) # set PWR_ON=1, EN_CRC=1, all irq enabled |
||||
a.wr_payload([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]) |
||||
|
||||
chnl = 5 |
||||
|
||||
# Set B's address as target and also pipe 0 Rx (used for ack) |
||||
a.wr(0x10, b_pipe0_adr) # target addr |
||||
a.wr(0x0A, b_pipe0_adr) # pipe 0 rx addr for ACK |
||||
a.wr(0x04, 0b00101111) # configure retransmit |
||||
a.wr(0x05, chnl) |
||||
|
||||
# --- Configure B for Rx --- |
||||
|
||||
b.wr(0x00, 0b00001011) # set PWR_ON=1, PRIM_RX=1, EN_CRC=1, all irq enabled |
||||
b.wr(0x02, 0b000001) # enable pipe 0 |
||||
b.wr(0x11, 32) # set pipe 0 len to 11 |
||||
b.wr(0x0A, b_pipe0_adr) # set pipe 0's address |
||||
b.wr(0x05, chnl) |
||||
|
||||
ce.set(0b10) # CE high for B |
||||
time.sleep(0.01) |
||||
|
||||
ce.pulse_us(us=10, pins=0b01) # Pulse A's CE |
||||
# |
||||
# testing B's FIFO by sending another payload... |
||||
a.wr_payload([0xFF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]) |
||||
ce.pulse_us(us=20, pins=0b01) # Pulse A's CE |
||||
|
||||
time.sleep(0.01) |
||||
|
||||
print("A's status after Tx: %02x" % a.status()) |
||||
print("B's status after Tx: %02x" % b.status()) |
||||
|
||||
ce.clear(0b11) |
||||
|
||||
# read the two payloads |
||||
print(b.rd_payload(32)) |
||||
print(b.rd_payload(32)) |
@ -1,11 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import gex |
||||
import time |
||||
|
||||
# generating a pulse on gpio, test of the unit |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
out = gex.DOut(client, 'out') |
||||
|
||||
out.pulse_us([0], 20) |
||||
out.pulse_us([3], 10) |
@ -1,126 +0,0 @@ |
||||
import time |
||||
import gex |
||||
|
||||
# GEX pomodoro timer |
||||
|
||||
# button btn |
||||
# neopixel neo |
||||
|
||||
# this is an example of using GEX as a user interface. |
||||
# for practical use it would be better to make this into a standalone device with a custom firmware. |
||||
|
||||
WK_TIME = 25 |
||||
BK_TIME = 5 |
||||
LIGHT_CNT = 30 |
||||
|
||||
PH_BREAK = 'Break' |
||||
PH_BREAK_OVER = 'BreakOver' |
||||
PH_WORK = 'Work' |
||||
PH_WORK_OVER = 'WorkOver' |
||||
|
||||
class Pymodoro: |
||||
def __init__(self): |
||||
self.phase = PH_BREAK_OVER |
||||
self.work_s = 0 |
||||
self.break_s = 0 |
||||
self.color = 0x000000 |
||||
self.colors = [0x000000 for _ in range(0, LIGHT_CNT)] |
||||
|
||||
self.client = gex.Client(gex.TrxRawUSB()) |
||||
self.btn = gex.DIn(self.client, 'btn') |
||||
self.neo = gex.Neopixel(self.client, 'neo') |
||||
self.btn.on_trigger([0], self.on_btn) |
||||
|
||||
self.switch(PH_BREAK_OVER) |
||||
self.display() |
||||
|
||||
def display(self): |
||||
self.neo.load(self.colors) |
||||
|
||||
def on_btn(self, snapshot, timestamp): |
||||
if self.phase == PH_BREAK_OVER: |
||||
self.switch(PH_WORK) |
||||
|
||||
elif self.phase == PH_WORK: |
||||
self.switch(PH_WORK) # restart |
||||
|
||||
elif self.phase == PH_WORK_OVER: |
||||
self.switch(PH_BREAK) |
||||
|
||||
def switch(self, phase): |
||||
print("Switch to %s" % phase) |
||||
|
||||
if phase == PH_BREAK: |
||||
self.color = 0x009900 |
||||
self.break_s = BK_TIME * 60 |
||||
|
||||
elif phase == PH_BREAK_OVER: |
||||
self.color = 0x662200 |
||||
|
||||
elif phase == PH_WORK: |
||||
self.color = 0x990000 |
||||
self.work_s = WK_TIME * 60 |
||||
|
||||
elif phase == PH_WORK_OVER: |
||||
self.color = 0x113300 |
||||
|
||||
self.colors = [self.color for _ in range(0, LIGHT_CNT)] |
||||
self.phase = phase |
||||
|
||||
def show_progress(self, dark, total): |
||||
per_light = total / LIGHT_CNT |
||||
lights = dark / per_light |
||||
|
||||
lights /= 2 |
||||
|
||||
remainder = float(lights - int(lights)) |
||||
if remainder == 0: |
||||
remainder = 1 |
||||
|
||||
# print("lights %f, remainder %f" % (lights, remainder)) |
||||
for i in range(0, int(LIGHT_CNT/2)): |
||||
if i < int((LIGHT_CNT/2)-lights): |
||||
c = 0x000000 |
||||
elif i == int((LIGHT_CNT/2)-lights): |
||||
r = (self.color&0xFF0000)>>16 |
||||
g = (self.color&0xFF00)>>8 |
||||
b = self.color&0xFF |
||||
c = (int(r*remainder))<<16 | (int(g*remainder))<<8 | (int(b*remainder)) |
||||
else: |
||||
c = self.color |
||||
|
||||
self.colors[i] = c |
||||
self.colors[LIGHT_CNT - 1 - i] = c |
||||
|
||||
def tick(self, elapsed): |
||||
if self.phase == PH_BREAK: |
||||
self.break_s -= elapsed |
||||
# print("Break remain: %d s" % self.break_s) |
||||
self.show_progress(self.break_s, BK_TIME * 60) |
||||
|
||||
if self.break_s <= 0: |
||||
self.switch(PH_BREAK_OVER) |
||||
|
||||
elif self.phase == PH_WORK: |
||||
self.work_s -= elapsed |
||||
# print("Work remain: %d s" % self.work_s) |
||||
self.show_progress(self.work_s, WK_TIME * 60) |
||||
|
||||
if self.work_s <= 0: |
||||
self.switch(PH_WORK_OVER) |
||||
|
||||
self.display() |
||||
|
||||
def run(self): |
||||
step=0.5 |
||||
try: |
||||
while True: |
||||
time.sleep(step) |
||||
self.tick(step) |
||||
except KeyboardInterrupt: |
||||
self.client.close() |
||||
print() # this puts the ^C on its own line |
||||
|
||||
|
||||
a = Pymodoro() |
||||
a.run() |
@ -1,37 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
# catching a transient |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
adc = gex.ADC(client, 'adc') |
||||
|
||||
rate=50000 |
||||
fs = adc.set_sample_rate(rate) |
||||
|
||||
d = None |
||||
|
||||
def x(report): |
||||
global d |
||||
print("capt") |
||||
d = report |
||||
|
||||
adc.on_trigger(x) |
||||
adc.setup_trigger(0, 50, 600, edge='rising', pretrigger=100) |
||||
adc.arm() |
||||
|
||||
time.sleep(2) |
||||
|
||||
if d is not None: |
||||
plt.plot(d.data, 'r-', lw=1) |
||||
plt.grid() |
||||
plt.show() |
||||
else: |
||||
print("Nothing rx") |
||||
|
@ -1,78 +0,0 @@ |
||||
## UNITS.INI |
||||
## GEX v0.0.1 on STM32F072-HUB |
||||
## built Mar 17 2018 at 17:53:15 |
||||
|
||||
[UNITS] |
||||
# Create units by adding their names next to a type (e.g. DO=A,B), |
||||
# remove the same way. Reload to update the unit sections below. |
||||
|
||||
# Digital output |
||||
DO=rst1,rst2 |
||||
# Digital input with triggers |
||||
DI= |
||||
# Neopixel RGB LED strip |
||||
NPX= |
||||
# I2C master |
||||
I2C= |
||||
# SPI master |
||||
SPI=spi |
||||
# Serial port |
||||
USART= |
||||
# 1-Wire master |
||||
1WIRE= |
||||
# Analog/digital converter |
||||
ADC= |
||||
# Shift register driver (595, 4094) |
||||
SIPO= |
||||
# Frequency and pulse measurement |
||||
FCAP= |
||||
# Capacitive touch sensing |
||||
TOUCH= |
||||
# Simple PWM output |
||||
PWMDIM= |
||||
# Two-channel analog output with waveforms |
||||
DAC= |
||||
|
||||
[DO:rst1@2] |
||||
# Port name |
||||
port=B |
||||
# Pins (comma separated, supports ranges) |
||||
pins=2 |
||||
# Initially high pins |
||||
initial=2 |
||||
# Open-drain pins |
||||
open-drain= |
||||
|
||||
[DO:rst2@3] |
||||
# Port name |
||||
port=B |
||||
# Pins (comma separated, supports ranges) |
||||
pins=6 |
||||
# Initially high pins |
||||
initial=6 |
||||
# Open-drain pins |
||||
open-drain= |
||||
|
||||
[SPI:spi@1] |
||||
# Peripheral number (SPIx) |
||||
device=1 |
||||
# Pin mappings (SCK,MISO,MOSI) |
||||
# SPI1: (0) A5,A6,A7 (1) B3,B4,B5 |
||||
# SPI2: (0) B13,B14,B15 |
||||
remap=1 |
||||
|
||||
# Prescaller: 2,4,8,...,256 |
||||
prescaller=64 |
||||
# Clock polarity: 0,1 (clock idle level) |
||||
cpol=0 |
||||
# Clock phase: 0,1 (active edge, 0-first, 1-second) |
||||
cpha=0 |
||||
# Transmit only, disable MISO |
||||
tx-only=N |
||||
# Bit order (LSB or MSB first) |
||||
first-bit=MSB |
||||
|
||||
# SS port name |
||||
port=B |
||||
# SS pins (comma separated, supports ranges) |
||||
pins=1-0 |
@ -1,309 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
|
||||
import gex |
||||
|
||||
transport = gex.TrxRawUSB(sn='0029002F-42365711-32353530') |
||||
#transport = gex.TrxSerialSync(port='/dev/ttyACM0') |
||||
|
||||
with gex.Client(transport) as client: |
||||
# |
||||
# if True: |
||||
# s = client.ini_read() |
||||
# print(s) |
||||
# client.ini_write(s) |
||||
|
||||
if True: |
||||
sipo = gex.SIPO(client, 'sipo') |
||||
sipo.load([[0xA5], [0xFF]]) |
||||
|
||||
if False: |
||||
adc = gex.ADC(client, 'adc') |
||||
print("Enabled channels:", adc.get_channels()) |
||||
|
||||
adc.set_smoothing_factor(0.9) |
||||
|
||||
while True: |
||||
raw = adc.read_raw() |
||||
smooth = adc.read_smooth() |
||||
print("IN1 = %d (%.2f), Tsens = %d (%.2f), Vrefint = %d (%.2f)" % (raw[1], smooth[1], |
||||
raw[16], smooth[16], |
||||
raw[17], smooth[17])) |
||||
time.sleep(0.5) |
||||
|
||||
if False: |
||||
adc = gex.ADC(client, 'adc') |
||||
|
||||
adc.set_active_channels([1]) |
||||
fs = adc.set_sample_rate(1000) |
||||
|
||||
data = adc.capture(1000) |
||||
|
||||
if data is not None: |
||||
plt.plot(data, 'r-', lw=1) |
||||
plt.show() |
||||
else: |
||||
print("Nothing rx") |
||||
|
||||
|
||||
# for r in range(0,8): |
||||
# adc.set_sample_time(r) |
||||
# data = adc.capture(10000) |
||||
# print("sr = %d" % r) |
||||
# std = np.std(data) |
||||
# print(std) |
||||
|
||||
|
||||
# |
||||
# global data |
||||
# data = None |
||||
# |
||||
# def capture(rpt): |
||||
# global data |
||||
# print("trig'd, %s" % rpt) |
||||
# data = rpt.data |
||||
# # |
||||
# # adc.setup_trigger(channel=1, |
||||
# # level=700, |
||||
# # count=20000, |
||||
# # pretrigger=100, |
||||
# # auto=False, |
||||
# # edge="falling", |
||||
# # holdoff=200, |
||||
# # handler=capture) |
||||
# |
||||
# # adc.arm() |
||||
# |
||||
# data = adc.capture(1000) |
||||
# |
||||
# if data is not None: |
||||
# plt.plot(data, 'r.', lw=1) |
||||
# plt.show() |
||||
# else: |
||||
# print("Nothing rx") |
||||
|
||||
# plt.magnitude_spectrum(data[:,0], Fs=fs, scale='dB', color='C1') |
||||
# plt.show() |
||||
|
||||
# def lst(data): |
||||
# if data is not None: |
||||
# print("Rx OK") #data |
||||
# else: |
||||
# print("Closed.") |
||||
|
||||
# adc.stream_start(lst) |
||||
# time.sleep(3) |
||||
# adc.stream_stop() |
||||
# print("Done.") |
||||
|
||||
|
||||
|
||||
|
||||
# time.sleep(.1) |
||||
# print(adc.get_sample_rate()) |
||||
# time.sleep(.1) |
||||
|
||||
# adc.stream_stop() |
||||
# time.sleep(5) |
||||
|
||||
# print(adc.capture(200, 5)) |
||||
|
||||
# adc.setup_trigger(channel=1, |
||||
# level=700, |
||||
# count=100, |
||||
# pretrigger=15, |
||||
# auto=True, |
||||
# edge="falling", |
||||
# holdoff=200, |
||||
# handler=lambda rpt: print("Report: %s" % rpt)) |
||||
# |
||||
# print("Armed") |
||||
# adc.arm() |
||||
# print("Sleep...") |
||||
# # adc.force() |
||||
# # |
||||
# # # adc.disarm() |
||||
# time.sleep(5) |
||||
# adc.disarm() |
||||
|
||||
# print(adc.capture(200, 50)) |
||||
|
||||
# adc.stream_start(lambda data: print(data)) |
||||
# time.sleep(20) |
||||
# adc.stream_stop() |
||||
|
||||
|
||||
# print(adc.read_raw()) |
||||
|
||||
# time.sleep(1) |
||||
# print("Rx: ", resp) |
||||
# adc.abort() |
||||
|
||||
if False: |
||||
s = client.ini_read() |
||||
print(s) |
||||
client.ini_write(s) |
||||
|
||||
# search the bus |
||||
if False: |
||||
ow = gex.OneWire(client, 'ow') |
||||
print("Devices:", ow.search()) |
||||
|
||||
# search the bus for alarm |
||||
if False: |
||||
ow = gex.OneWire(client, 'ow') |
||||
print("Presence: ", ow.test_presence()) |
||||
print("Devices w alarm:", ow.search(alarm=True)) |
||||
|
||||
# simple 1w check |
||||
if False: |
||||
ow = gex.OneWire(client, 'ow') |
||||
print("Presence: ", ow.test_presence()) |
||||
print("ROM: 0x%016x" % ow.read_address()) |
||||
print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True)) |
||||
|
||||
# testing ds1820 temp meas without polling |
||||
if False: |
||||
ow = gex.OneWire(client, 'ow') |
||||
print("Presence: ", ow.test_presence()) |
||||
print("Starting measure...") |
||||
ow.write([0x44]) |
||||
time.sleep(1) |
||||
print("Scratch:", ow.query([0xBE], 9)) |
||||
|
||||
# testing ds1820 temp meas with polling |
||||
if False: |
||||
ow = gex.OneWire(client, 'ow') |
||||
print("Presence: ", ow.test_presence()) |
||||
print("Starting measure...") |
||||
ow.write([0x44]) |
||||
ow.wait_ready() |
||||
data = ow.query([0xBE], 9) |
||||
|
||||
pp = gex.PayloadParser(data) |
||||
|
||||
temp = pp.i16()/2.0 |
||||
th = pp.i8() |
||||
tl = pp.i8() |
||||
reserved = pp.i16() |
||||
remain = float(pp.u8()) |
||||
perc = float(pp.u8()) |
||||
|
||||
realtemp = temp - 0.25+(perc-remain)/perc |
||||
print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl)) |
||||
|
||||
|
||||
if False: |
||||
buf = client.bulk_read(gex.MSG_INI_READ) |
||||
print(buf.decode('utf-8')) |
||||
|
||||
pb = gex.PayloadBuilder() |
||||
pb.u32(len(buf)) |
||||
|
||||
client.bulk_write(gex.MSG_INI_WRITE, pld=pb.close(), bulk=buf) |
||||
|
||||
if False: |
||||
leds = gex.DOut(client, 'strip') |
||||
|
||||
nn = 3 |
||||
for i in range(0,20): |
||||
leds.write(nn) |
||||
time.sleep(.05) |
||||
nn<<=1 |
||||
nn|=(nn&0x40)>>6 |
||||
nn=nn&0x3F |
||||
leds.clear(0xFF) |
||||
|
||||
if False: |
||||
leds = gex.DOut(client, 'bargraph') |
||||
|
||||
for i in range(0,0x41): |
||||
leds.write(i&0x3F) |
||||
time.sleep(.1) |
||||
|
||||
if False: |
||||
leds = gex.DOut(client, 'TST') |
||||
|
||||
for i in range(0, 0x41): |
||||
#leds.write(i & 0x3F) |
||||
leds.toggle(0xFF) |
||||
time.sleep(.1) |
||||
|
||||
if False: |
||||
btn = gex.DIn(client, 'btn') |
||||
strip = gex.DOut(client, 'strip') |
||||
|
||||
for i in range(0, 10000): |
||||
b = btn.read() |
||||
strip.write((b << 2) | ((~b) & 1)) |
||||
time.sleep(.02) |
||||
|
||||
if False: |
||||
neo = gex.Neopixel(client, 'npx') |
||||
|
||||
print('We have %d neopixels.\n' % neo.get_len()) |
||||
|
||||
#neo.load([0xF0F0F0,0,0,0xFF0000]) |
||||
|
||||
# generate a little animation... |
||||
for i in range(0,512): |
||||
j = i if i < 256 else 255-(i-256) |
||||
neo.load([0x660000+j, 0x3300FF-j, 0xFFFF00-(j<<8), 0x0000FF+(j<<8)-j]) |
||||
time.sleep(.001) |
||||
|
||||
neo.load([0,0,0,0]) |
||||
|
||||
if False: |
||||
i2c = gex.I2C(client, 'i2c') |
||||
|
||||
# i2c.write(0x76, payload=[0xD0]) |
||||
# print(i2c.read(0x76, count=1)) |
||||
|
||||
print(i2c.read_reg(0x76, 0xD0)) |
||||
print("%x" % i2c.read_reg(0x76, 0xF9, width=3, endian='big')) |
||||
|
||||
i2c.write_reg(0x76, 0xF4, 0xFA) |
||||
print(i2c.read_reg(0x76, 0xF4)) |
||||
|
||||
if False: |
||||
spi = gex.SPI(client, 'spi') |
||||
spi.multicast(1, [0xDE, 0xAD, 0xBE, 0xEF]) |
||||
print(spi.query(0, [0xDE, 0xAD, 0xBE, 0xEF], rlen=4, rskip=1))# |
||||
|
||||
if False: |
||||
usart = gex.USART(client, 'serial') |
||||
usart.listen(lambda x: print("RX >%s<" % x)) |
||||
for i in range(0,100): |
||||
# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ac bibendum lectus, ut pellentesque sem. Suspendisse ultrices felis eu laoreet luctus. Nam sollicitudin ultrices leo, ac condimentum enim vulputate quis. Suspendisse cursus tortor nibh, ac consectetur eros dapibus quis. Aliquam erat volutpat. Duis sagittis eget nunc nec condimentum. Aliquam erat volutpat. Phasellus molestie sem vitae quam semper convallis. |
||||
|
||||
usart.write("""_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n""".encode(), sync=True) |
||||
|
||||
# time.sleep(.001) |
||||
|
||||
if False: |
||||
usart = gex.USART(client, 'serial') |
||||
usart.listen(lambda x: print(x, end='',flush=True)) |
||||
while True: |
||||
client.poll() |
||||
|
||||
if False: |
||||
print(client.ini_read()) |
||||
|
||||
trig = gex.DIn(client, 'trig') |
||||
print(trig.read()) |
||||
|
||||
# Two pins are defined, PA10 and PA7. PA10 is the trigger, in the order from smallest to highest number 1 |
||||
trig.arm(0b10) |
||||
trig.on_trigger(0b10, lambda snap,ts: print("snap 0x%X, ts %d" % (snap,ts))) |
||||
|
||||
while True: |
||||
client.poll() |
||||
|
||||
# |
||||
# for n in range(0,100): |
||||
# print(n) |
||||
# s = client.ini_read() |
||||
# client.ini_write(s) |
@ -1,24 +0,0 @@ |
||||
% this is an example of sampling the ADC from Matlab and then plotting a |
||||
% FFT graph. The ADC unit called 'adc' is configured to use PA1 as Ch. 0 |
||||
|
||||
%transport = py.gex.TrxSerialThread(pyargs('port', '/dev/ttyUSB1', 'baud', 57600)); |
||||
transport = py.gex.TrxRawUSB(); |
||||
client = py.gex.Client(transport); |
||||
adc = py.gex.ADC(client, 'adc'); |
||||
|
||||
L=1000; |
||||
Fs=1000; |
||||
|
||||
adc.set_sample_rate(uint32(Fs)); |
||||
data = adc.capture(uint32(L)); |
||||
data = double(py.array.array('f',data)); |
||||
|
||||
Y = fft(data); |
||||
P2 = abs(Y/L); |
||||
P1 = P2(1:L/2+1); |
||||
P1(2:end-1) = 2*P1(2:end-1); |
||||
|
||||
f = Fs*(0:(L/2))/L; |
||||
plot(f,P1) |
||||
|
||||
client.close() |
@ -1,86 +0,0 @@ |
||||
## UNITS.INI |
||||
## GEX v0.1.0 on STM32F072-HUB |
||||
## built Mar 28 2018 at 00:42:03 |
||||
|
||||
[UNITS] |
||||
# Create units by adding their names next to a type (e.g. DO=A,B), |
||||
# remove the same way. Reload to update the unit sections below. |
||||
|
||||
# Digital output |
||||
DO=ce |
||||
# Digital input with triggers |
||||
DI=irq |
||||
# Neopixel RGB LED strip |
||||
NPX= |
||||
# I2C master |
||||
I2C= |
||||
# SPI master |
||||
SPI=spi |
||||
# Serial port |
||||
USART= |
||||
# 1-Wire master |
||||
1WIRE= |
||||
# Analog/digital converter |
||||
ADC= |
||||
# Shift register driver (595, 4094) |
||||
SIPO= |
||||
# Frequency and pulse measurement |
||||
FCAP= |
||||
# Capacitive touch sensing |
||||
TOUCH= |
||||
# Simple PWM output |
||||
PWMDIM= |
||||
# Two-channel analog output with waveforms |
||||
DAC= |
||||
|
||||
[DO:ce@2] |
||||
# Port name |
||||
port=B |
||||
# Pins (comma separated, supports ranges) |
||||
pins=6, 2 |
||||
# Initially high pins |
||||
initial= |
||||
# Open-drain pins |
||||
open-drain= |
||||
|
||||
[DI:irq@3] |
||||
# Port name |
||||
port=B |
||||
# Pins (comma separated, supports ranges) |
||||
pins=8-7 |
||||
# Pins with pull-up |
||||
pull-up= |
||||
# Pins with pull-down |
||||
pull-down= |
||||
|
||||
# Trigger pins activated by rising/falling edge |
||||
trig-rise= |
||||
trig-fall= |
||||
# Trigger pins auto-armed by default |
||||
auto-trigger= |
||||
# Triggers hold-off time (ms) |
||||
hold-off=100 |
||||
|
||||
[SPI:spi@1] |
||||
# Peripheral number (SPIx) |
||||
device=1 |
||||
# Pin mappings (SCK,MISO,MOSI) |
||||
# SPI1: (0) A5,A6,A7 (1) B3,B4,B5 |
||||
# SPI2: (0) B13,B14,B15 |
||||
remap=1 |
||||
|
||||
# Prescaller: 2,4,8,...,256 |
||||
prescaller=64 |
||||
# Clock polarity: 0,1 (clock idle level) |
||||
cpol=0 |
||||
# Clock phase: 0,1 (active edge, 0-first, 1-second) |
||||
cpha=1 |
||||
# Transmit only, disable MISO |
||||
tx-only=N |
||||
# Bit order (LSB or MSB first) |
||||
first-bit=MSB |
||||
|
||||
# SS port name |
||||
port=B |
||||
# SS pins (comma separated, supports ranges) |
||||
pins=1-0 |
@ -1,15 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import sys |
||||
|
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
import datetime |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
data = np.load(sys.argv[1]) |
||||
plt.plot(data, 'r-', lw=1) |
||||
plt.show() |
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
adc = gex.ADC(client, 'adc') |
||||
|
||||
print(adc.get_calibration_data()) |
||||
print(adc.get_channels()) |
||||
|
||||
adc.set_active_channels([1]) |
||||
rate=50000 |
||||
fs = adc.set_sample_rate(rate) |
||||
|
||||
time.sleep(0.1) |
||||
count = 5000 |
||||
data = adc.capture(count) |
||||
|
||||
print("rx, %d samples" % len(data)) |
||||
data = np.add(data / 4096, -0.5) |
||||
|
||||
adc.set_sample_rate(1000) |
||||
|
||||
# |
||||
if data is not None: |
||||
# wavfile.write('file.wav', rate, data) |
||||
# print("Ok") |
||||
|
||||
plt.plot(data, 'r-', lw=1) |
||||
plt.show() |
||||
else: |
||||
print("Nothing rx") |
||||
|
@ -1,17 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
import numpy as np |
||||
from matplotlib import pyplot as plt |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
adc = gex.ADC(client, 'adc') |
||||
|
||||
print(adc.capture(100)) |
||||
|
||||
# for i in range(1000): |
||||
# print(adc.read_raw()) |
||||
|
@ -1,49 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
import math |
||||
|
||||
import gex |
||||
|
||||
from scipy.io import wavfile |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
dac = gex.DAC(client, 'dac') |
||||
|
||||
# dac.set_dither(1, 'TRI', 8) |
||||
# # dac.set_dither(3, 'NONE', 8) |
||||
# # # |
||||
# # # dac.set_frequency(2, 1) |
||||
# # # dac.set_frequency(1, 10.01) |
||||
# dac.set_waveform(1, 'SIN') |
||||
# # dac.set_waveform(2, 'RAMP') |
||||
# |
||||
# dac.rectangle(2, 0.5, 4095, 0) |
||||
# |
||||
# dac.set_frequency(1, 100) |
||||
# dac.set_frequency(2, 50) |
||||
# # |
||||
# dac.sync() |
||||
|
||||
# for i in range(0, 1000): |
||||
# dac.set_frequency(1, i) |
||||
# time.sleep(0.001) |
||||
|
||||
dac.waveform(1, 'SIN') |
||||
dac.set_frequency(1, 1000) |
||||
time.sleep(2) |
||||
dac.dc(1, 2047) |
||||
|
||||
# dac.waveform(1, 'SIN') |
||||
# # dac.set_frequency(1, 1000) |
||||
# # dac.dc(1,1000) |
||||
# dac.dc(2,1000) |
||||
|
||||
# |
||||
# for i in range(0,360*5, 3): |
||||
# dac.dc_dual(round(2047+math.cos(((i*3.01)/180)*math.pi)*1900), |
||||
# round(2047+math.sin(((i*2.01)/180)*math.pi)*1900), |
||||
# confirm=False) |
||||
# time.sleep(0.01) |
||||
# |
||||
# dac.dc_dual(2047,2047) |
||||
|
@ -1,32 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# test with the radio gw |
||||
|
||||
with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport: |
||||
# with gex.TrxRawUSB() as transport: |
||||
|
||||
# connect GEX client library to the remote slave |
||||
client = gex.Client(transport) |
||||
|
||||
while True: |
||||
client.query_raw(type=gex.MSG_PING) |
||||
print("ok") |
||||
time.sleep(0.1) |
||||
|
||||
# do = gex.DOut(client, "led") |
||||
# adc = gex.ADC(client, "adc") |
||||
# |
||||
# while True: |
||||
# do.toggle(confirm=True) |
||||
# print(adc.read_smooth()) |
||||
# time.sleep(0.2) |
||||
|
||||
# adc = gex.ADC(client, "adc") |
||||
# for j in range(10): |
||||
# try: |
||||
# print(adc.read_smooth()) |
||||
# except: |
||||
# print("Failed") |
@ -1,43 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
fcap = gex.FCAP(client, 'fcap') |
||||
|
||||
fcap.stop() |
||||
|
||||
fcap.indirect_start() |
||||
# |
||||
time.sleep(2) |
||||
print(fcap.indirect_read()) |
||||
|
||||
# fcap.stop() |
||||
# #print(fcap.indirect_burst(3, timeout=20)) |
||||
|
||||
# r=fcap.indirect_burst(1000, timeout=5) |
||||
# print(r) |
||||
# print(r.period_raw) |
||||
|
||||
# fcap.configure(filter=0) |
||||
|
||||
# print(fcap.measure_pulse()) |
||||
|
||||
# print(fcap.direct_burst(10)) |
||||
# |
||||
# fcap.direct_start(1000, 0) |
||||
# time.sleep(2) |
||||
# |
||||
# print(fcap.direct_read()) |
||||
# |
||||
# fcap.counter_start() |
||||
# time.sleep(1) |
||||
# print(fcap.counter_clear()) |
||||
# time.sleep(1) |
||||
# print(fcap.counter_read()) |
||||
# time.sleep(1) |
||||
# print(fcap.counter_clear()) |
||||
# time.sleep(1) |
||||
# print(fcap.counter_clear()) |
||||
|
||||
|
@ -1,9 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# with gex.Client(gex.TrxRawUSB()) as client: |
||||
with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport: |
||||
client = gex.Client(transport) |
||||
print(client.ini_read(0)) |
@ -1,81 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
ow = gex.OneWire(client, 'ow') |
||||
# print("Presence: ", ow.test_presence()) |
||||
print("Devices:", ow.search()) |
||||
|
||||
def meas(addr): |
||||
ow.write([0x44], addr=addr) |
||||
ow.wait_ready() |
||||
data = ow.query([0xBE], 9, addr=addr) |
||||
pp = gex.PayloadParser(data) |
||||
return pp.i16() * 0.0625 |
||||
|
||||
def meas2(addr, addr2): |
||||
ow.write([0x44], addr=addr) |
||||
ow.write([0x44], addr=addr2) |
||||
ow.wait_ready() |
||||
|
||||
data = ow.query([0xBE], 9, addr=addr) |
||||
pp = gex.PayloadParser(data) |
||||
a = pp.i16() * 0.0625 |
||||
|
||||
data = ow.query([0xBE], 9, addr=addr2) |
||||
pp = gex.PayloadParser(data) |
||||
b = pp.i16() * 0.0625 |
||||
return a, b |
||||
|
||||
while True: |
||||
(a, b) = meas2(6558392391241695016, 1802309978572980008) |
||||
# a = meas(6558392391241695016) |
||||
# b = meas(1802309978572980008) |
||||
print("in: %.2f °C, out: %f °C" % (a, b)) |
||||
|
||||
|
||||
|
||||
# # search the bus for alarm |
||||
# if False: |
||||
# ow = gex.OneWire(client, 'ow') |
||||
# print("Presence: ", ow.test_presence()) |
||||
# print("Devices w alarm:", ow.search(alarm=True)) |
||||
# |
||||
# # simple 1w check |
||||
# if False: |
||||
# ow = gex.OneWire(client, 'ow') |
||||
# print("Presence: ", ow.test_presence()) |
||||
# print("ROM: 0x%016x" % ow.read_address()) |
||||
# print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True)) |
||||
# |
||||
# # testing ds1820 temp meas without polling |
||||
# if False: |
||||
# ow = gex.OneWire(client, 'ow') |
||||
# print("Presence: ", ow.test_presence()) |
||||
# print("Starting measure...") |
||||
# ow.write([0x44]) |
||||
# time.sleep(1) |
||||
# print("Scratch:", ow.query([0xBE], 9)) |
||||
# |
||||
# # testing ds1820 temp meas with polling |
||||
# if False: |
||||
# ow = gex.OneWire(client, 'ow') |
||||
# print("Presence: ", ow.test_presence()) |
||||
# print("Starting measure...") |
||||
# ow.write([0x44]) |
||||
# ow.wait_ready() |
||||
# data = ow.query([0xBE], 9) |
||||
# |
||||
# pp = gex.PayloadParser(data) |
||||
# |
||||
# temp = pp.i16()/2.0 |
||||
# th = pp.i8() |
||||
# tl = pp.i8() |
||||
# reserved = pp.i16() |
||||
# remain = float(pp.u8()) |
||||
# perc = float(pp.u8()) |
||||
# |
||||
# realtemp = temp - 0.25+(perc-remain)/perc |
||||
# print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl)) |
@ -1,7 +0,0 @@ |
||||
#!/bin/env python3 |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
with gex.Client(gex.TrxSerialThread(port='/dev/ttyACM0')) as client: |
||||
pass |
@ -1,47 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# beeping music with PWM (square wave) |
||||
|
||||
C3 = 130.81; Cx3 = 138.59; D3 = 146.83; Dx3 = 155.56; E3 = 164.81; F3 = 174.61 |
||||
Fx3 = 185.00; G3 = 196.00; Gx3 = 207.65; A3 = 220.00; Ax3 = 233.08; B3 = 246.94 |
||||
C4 = 261.63; Cx4 = 277.18; D4 = 293.66; Dx4 = 311.13; E4 = 329.63; F4 = 349.23 |
||||
Fx4 = 369.99; G4 = 392.00; Gx4 = 415.30; A4 = 440.00; Ax4 = 466.16; B4 = 493.88 |
||||
C5 = 523.25; Cx5 = 554.37; D5 = 587.33; Dx5 = 622.25; E5 = 659.25; F5 = 698.46 |
||||
Fx5 = 739.99; G5 = 783.99; Gx5 = 830.61; A5 = 880.00; Ax5 = 932.33; B5 = 987.77 |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
pwm = gex.PWMDim(client, 'dim') |
||||
|
||||
# O O/ #/ #~ #= |
||||
# 16, 8, 4, 2, 1 |
||||
notes = [ |
||||
(G3, 2), |
||||
(G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2), |
||||
(G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2), |
||||
|
||||
(G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2), |
||||
(G4, 2), (E4, 4), (0, 2), (D4, 2), (A3, 2), (C4, 6), (0, 2), (G3, 2), |
||||
|
||||
#rep |
||||
(G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2), |
||||
(G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2), |
||||
|
||||
(G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2), |
||||
|
||||
(G4, 2), (E4, 6), (D4, 2), (A3, 2), (C4, 6), (0, 2), #(C4, 2), |
||||
] |
||||
|
||||
for p in notes: |
||||
pwm.stop() |
||||
time.sleep(0.01) |
||||
f = round(p[0]) |
||||
print(f) |
||||
if f > 0: |
||||
pwm.set_frequency(f) |
||||
pwm.start() |
||||
time.sleep(0.1*p[1]) |
||||
|
||||
pwm.stop() |
||||
|
@ -1,17 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# pwm frequency sweep |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
pwm = gex.PWMDim(client, 'dim') |
||||
|
||||
pwm.start() |
||||
pwm.set_duty_single(1, 500) |
||||
for i in range(2000, 200, -15): |
||||
pwm.set_frequency(i) |
||||
time.sleep(0.05) |
||||
|
||||
pwm.stop() |
||||
|
@ -1,21 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# sipo example |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
sipo = gex.SIPO(client, 'sipo') |
||||
d4 = gex.DOut(client, 'd4') |
||||
|
||||
# Jort the lights |
||||
sipo.load([ |
||||
[0x0a, 0x0f], |
||||
[0xF8, 0xFC], |
||||
[0x00, 0x00], |
||||
[0x02, 0x00], |
||||
], end=0x04) |
||||
|
||||
d4.write(1) |
||||
# sipo.set_data(0x04) |
||||
# sipo.store() |
@ -1,20 +0,0 @@ |
||||
import time |
||||
|
||||
import gex |
||||
|
||||
# toush sensing test |
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client: |
||||
tsc = gex.TOUCH(client, 'tsc') |
||||
|
||||
print("There are %d touch channels." % tsc.get_channel_count()) |
||||
|
||||
tsc.set_button_thresholds([1225, 1440, 1440]) |
||||
|
||||
tsc.listen(0, lambda state, ts: print("Pad 1: %d" % state)) |
||||
tsc.listen(1, lambda state, ts: print("Pad 2: %d" % state)) |
||||
tsc.listen(2, lambda state, ts: print("Pad 3: %d" % state)) |
||||
|
||||
while True: |
||||
print(tsc.read()) |
||||
time.sleep(0.5) |
@ -1,128 +0,0 @@ |
||||
#!/bin/env python3 |
||||
|
||||
import gex |
||||
|
||||
import sys |
||||
from PyQt4 import QtGui, QtCore |
||||
import ini_syntax |
||||
|
||||
class GexIniEditor(QtGui.QMainWindow): |
||||
""" |
||||
Gexync is a GEX ini file editor. |
||||
The editor loads the INI file through the communication interface |
||||
without having to mount the virtual filesystem, which is unreliable |
||||
on some systems. |
||||
|
||||
This utility allows live editing of the UNITS.INI file. |
||||
|
||||
On save, a new version is loaded with formatting and error messages |
||||
generated by GEX, as if the virtual config filesystem was re-mounted. |
||||
|
||||
The editor does not keep GEX claimed, instead does so only when needed. |
||||
This allows testing of the current configuration without having to close |
||||
and reopen the editor. |
||||
""" |
||||
|
||||
def __init__(self, xferLambda): |
||||
self.xferLambda = xferLambda |
||||
|
||||
self.filenum = int(sys.argv[1]) if len(sys.argv)>1 else 0 |
||||
|
||||
super().__init__() |
||||
self.initUI() |
||||
# TODO let user pick GEX device if multiple |
||||
|
||||
def initToolbar(self): |
||||
icon = self.style().standardIcon(QtGui.QStyle.SP_BrowserReload) |
||||
loadAction = QtGui.QAction(icon, 'Reload', self) |
||||
loadAction.setShortcut('Ctrl+O') |
||||
loadAction.triggered.connect(self.gexLoad) |
||||
|
||||
icon = self.style().standardIcon(QtGui.QStyle.SP_DialogSaveButton) |
||||
syncAction = QtGui.QAction(icon, 'Write Changes', self) |
||||
syncAction.setShortcut('Ctrl+S') |
||||
syncAction.triggered.connect(self.gexSync) |
||||
|
||||
icon = self.style().standardIcon(QtGui.QStyle.SP_DialogOkButton) |
||||
persAction = QtGui.QAction(icon, 'Persist', self) |
||||
persAction.setShortcut('Ctrl+P') |
||||
persAction.triggered.connect(self.gexPersist) |
||||
|
||||
self.toolbar = self.addToolBar('Toolbar') |
||||
self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) |
||||
self.toolbar.addAction(loadAction) |
||||
self.toolbar.addAction(syncAction) |
||||
self.toolbar.addSeparator() |
||||
self.toolbar.addAction(persAction) |
||||
|
||||
def initEditor(self): |
||||
self.editor = QtGui.QPlainTextEdit() |
||||
|
||||
# Editor background and text color |
||||
pal = QtGui.QPalette() |
||||
bgc = QtGui.QColor(0xFFFFF6) |
||||
pal.setColor(QtGui.QPalette.Base, bgc) |
||||
textc = QtGui.QColor(0x000000) |
||||
pal.setColor(QtGui.QPalette.Text, textc) |
||||
self.editor.setPalette(pal) |
||||
# Font |
||||
font = QtGui.QFont('Liberation Mono', 12) |
||||
font.setStyleHint(QtGui.QFont.TypeWriter) |
||||
self.editor.setFont(font) |
||||
# Initial size |
||||
self.highlight = ini_syntax.IniHighlighter(self.editor.document()) |
||||
|
||||
def initUI(self): |
||||
self.setWindowTitle('GEX config file editor') |
||||
self.initToolbar() |
||||
self.initEditor() |
||||
self.setCentralWidget(self.editor) |
||||
self.show() |
||||
|
||||
self.gexLoad() |
||||
|
||||
def gexLoad(self): |
||||
self.editor.setPlainText("") |
||||
self.editor.repaint() |
||||
|
||||
client = gex.Client(self.xferLambda(), load_units=False) |
||||
read_ini = client.ini_read(self.filenum) |
||||
client.close() |
||||
|
||||
self.editor.setPlainText(read_ini) |
||||
self.highlight.rehighlight() |
||||
self.setWindowTitle('GEX config file editor') |
||||
|
||||
def gexSync(self): |
||||
new_txt = self.editor.toPlainText() |
||||
self.editor.setPlainText("") |
||||
self.editor.repaint() |
||||
|
||||
client = gex.Client(self.xferLambda(), load_units=False) |
||||
client.ini_write(new_txt) |
||||
read_ini = client.ini_read(self.filenum) |
||||
client.close() |
||||
|
||||
self.editor.setPlainText(read_ini) |
||||
self.highlight.rehighlight() |
||||
self.setWindowTitle('*GEX config file editor') |
||||
|
||||
def gexPersist(self): |
||||
client = gex.Client(self.xferLambda(), load_units=False) |
||||
client.ini_persist() |
||||
client.close() |
||||
self.setWindowTitle('GEX config file editor') |
||||
|
||||
if __name__ == '__main__': |
||||
app = QtGui.QApplication(sys.argv) |
||||
editor = GexIniEditor(lambda: gex.TrxRawUSB()) |
||||
# editor = GexIniEditor(lambda: gex.TrxSerialThread(port='/dev/ttyUSB1', |
||||
# baud=57600)) |
||||
|
||||
# centered resize |
||||
w = 800 |
||||
h = 900 |
||||
ss = app.desktop().availableGeometry().size() |
||||
editor.setGeometry(int(ss.width() / 2 - w / 2), int(ss.height() / 2 - h / 2), w, h) |
||||
|
||||
sys.exit(app.exec_()) |
@ -1,81 +0,0 @@ |
||||
# syntax.py |
||||
|
||||
# This is a companion file to gexync.py |
||||
|
||||
# based on https://wiki.python.org/moin/PyQt/Python%20syntax%20highlighting |
||||
|
||||
from PyQt4.QtCore import QRegExp |
||||
from PyQt4.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter |
||||
|
||||
def format(color, style=''): |
||||
"""Return a QTextCharFormat with the given attributes. |
||||
""" |
||||
_color = QColor() |
||||
_color.setNamedColor(color) |
||||
|
||||
_format = QTextCharFormat() |
||||
_format.setForeground(_color) |
||||
if 'bold' in style: |
||||
_format.setFontWeight(QFont.Bold) |
||||
if 'italic' in style: |
||||
_format.setFontItalic(True) |
||||
|
||||
return _format |
||||
|
||||
|
||||
# Syntax styles that can be shared by all languages |
||||
STYLES = { |
||||
'operator': format('red'), |
||||
'string': format('magenta'), |
||||
'comment': format('#6C8A70', 'italic'), |
||||
'key': format('#008AFF'), |
||||
'numbers': format('brown'), |
||||
'section': format('black', 'bold'), |
||||
} |
||||
|
||||
class IniHighlighter (QSyntaxHighlighter): |
||||
# Python braces |
||||
def __init__(self, document): |
||||
QSyntaxHighlighter.__init__(self, document) |
||||
|
||||
rules = [ |
||||
(r'=', 0, STYLES['operator']), |
||||
(r'\b[YN]\b', 0, STYLES['numbers']), |
||||
|
||||
# Double-quoted string, possibly containing escape sequences |
||||
(r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']), |
||||
# Single-quoted string, possibly containing escape sequences |
||||
(r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']), |
||||
|
||||
# Numeric literals |
||||
(r'\b[+-]?[0-9]+\b', 0, STYLES['numbers']), |
||||
(r'\b[+-]?0[xX][0-9A-Fa-f]+\b', 0, STYLES['numbers']), |
||||
(r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']), |
||||
|
||||
# From '#' until a newline |
||||
(r'#[^\n]*', 0, STYLES['comment']), |
||||
|
||||
(r'^\[.+\]', 0, STYLES['section']), |
||||
|
||||
(r'^[a-zA-Z0-9_-]+\s?=', 0, STYLES['key']), |
||||
] |
||||
|
||||
# Build a QRegExp for each pattern |
||||
self.rules = [(QRegExp(pat), index, fmt) |
||||
for (pat, index, fmt) in rules] |
||||
|
||||
def highlightBlock(self, text): |
||||
"""Apply syntax highlighting to the given block of text. |
||||
""" |
||||
# Do other syntax formatting |
||||
for expression, nth, format in self.rules: |
||||
index = expression.indexIn(text, 0) |
||||
|
||||
while index >= 0: |
||||
# We actually want the index of the nth match |
||||
index = expression.pos(nth) |
||||
length = len(expression.cap(nth)) |
||||
self.setFormat(index, length, format) |
||||
index = expression.indexIn(text, index + length) |
||||
|
||||
self.setCurrentBlockState(0) |
Loading…
Reference in new issue