code import

master
Ondřej Hruška 6 years ago
commit 9f6f2eb198
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 107
      .gitignore
  2. 3
      .gitmodules
  3. 9
      LICENSE
  4. 49
      demo_adc_lightnings.py
  5. 36
      demo_dot_matrix_phat.py
  6. 200
      demo_dot_matrix_phat2.py
  7. 35
      demo_freq_response.py
  8. 23
      demo_i2c_dotmatrix.py
  9. 213
      demo_lora.py
  10. 37
      demo_ndir_leds.py
  11. 18
      demo_ndir_usart.py
  12. 17
      demo_neo2.py
  13. 39
      demo_neo3.py
  14. 11
      demo_neopixel.py
  15. 136
      demo_nrf24.py
  16. 11
      demo_pulse.py
  17. 126
      demo_pymodoro.py
  18. 37
      demo_transient.py
  19. BIN
      file.wav
  20. 1
      gex
  21. BIN
      lightnings/lightning-2018-04-23T22:16:46.261627.npy
  22. BIN
      lightnings/lightning-2018-04-23T22:34:32.534488.npy
  23. BIN
      lightnings/lightning-2018-04-23T22:35:42.852678.npy
  24. BIN
      lightnings/lightning-2018-04-23T22:41:39.330784.npy
  25. BIN
      lightnings/lightning-2018-04-23T22:41:42.047079.npy
  26. BIN
      lightnings/lightning-2018-04-23T22:48:26.142246.npy
  27. BIN
      lightnings/lightning-2018-04-23T22:51:43.018760.npy
  28. BIN
      lightnings/lightning-2018-04-23T22:55:34.559141.npy
  29. BIN
      lightnings/lightning-2018-04-23T22:59:13.545024.npy
  30. BIN
      lightnings/lightning-2018-04-23T23:02:38.393510.npy
  31. BIN
      lightnings/lightning-2018-04-23T23:02:58.074542.npy
  32. BIN
      lightnings/lightning-2018-04-23T23:03:58.234612.npy
  33. BIN
      lightnings/lightning-2018-04-23T23:06:25.165868.npy
  34. BIN
      lightnings/lightning-2018-04-23T23:07:45.789655.npy
  35. BIN
      lightnings/lightning-2018-04-23T23:10:08.713982.npy
  36. BIN
      lightnings/lightning-2018-04-23T23:14:20.084082.npy
  37. BIN
      lightnings/lightning-2018-04-23T23:22:11.489806.npy
  38. 78
      loratest.txt
  39. 24
      mat_sampling.m
  40. 309
      misc.py
  41. 86
      nrf_config.ini
  42. 15
      show_nparray.py
  43. 1109
      sx_fsk.py
  44. 38
      test_adc.py
  45. 17
      test_adc2.py
  46. 49
      test_dac.py
  47. 32
      test_dongle.py
  48. 43
      test_freq_cap.py
  49. 9
      test_ini.py
  50. 81
      test_onewire.py
  51. 7
      test_ping.py
  52. 47
      test_pwmdim_music.py
  53. 17
      test_pwmdim_sweep.py
  54. 21
      test_sipo_omicron.py
  55. 20
      test_touch.py

107
.gitignore vendored

@ -0,0 +1,107 @@
# Byte-compiled / optimized / DLL files
__pycache__/
__javascript__/
*.py[cod]
*$py.class
#*.wav
.idea/
#*.npy
#*.npz
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "gex"]
path = gex
url = https://git.ondrovo.com/gex/gex-client-py.git

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2018 Ondřej Hruška
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,49 @@
#!/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("lightnings/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)

@ -0,0 +1,36 @@
#!/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)

@ -0,0 +1,200 @@
#!/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)

@ -0,0 +1,35 @@
#!/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()

@ -0,0 +1,23 @@
#!/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)

@ -0,0 +1,213 @@
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)

@ -0,0 +1,37 @@
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)

@ -0,0 +1,18 @@
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)

@ -0,0 +1,17 @@
#!/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()

@ -0,0 +1,39 @@
#!/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()

@ -0,0 +1,11 @@
#!/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])

@ -0,0 +1,136 @@
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))

@ -0,0 +1,11 @@
#!/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)

@ -0,0 +1,126 @@
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()

@ -0,0 +1,37 @@
#!/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")

Binary file not shown.

1
gex

@ -0,0 +1 @@
Subproject commit 3a5ac05d9db965f86188929f8f56a68ee994827d

@ -0,0 +1,78 @@
## 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

@ -0,0 +1,24 @@
% 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()

@ -0,0 +1,309 @@
#!/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)

@ -0,0 +1,86 @@
## 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

@ -0,0 +1,15 @@
#!/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

@ -0,0 +1,38 @@
#!/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")

@ -0,0 +1,17 @@
#!/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())

@ -0,0 +1,49 @@
#!/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)

@ -0,0 +1,32 @@
#!/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")

@ -0,0 +1,43 @@
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())

@ -0,0 +1,9 @@
#!/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))

@ -0,0 +1,81 @@
#!/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))

@ -0,0 +1,7 @@
#!/bin/env python3
import time
import gex
with gex.Client(gex.TrxSerialThread(port='/dev/ttyACM0')) as client:
pass

@ -0,0 +1,47 @@
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()

@ -0,0 +1,17 @@
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()

@ -0,0 +1,21 @@
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()

@ -0,0 +1,20 @@
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)
Loading…
Cancel
Save