diff --git a/examples/Units/4-RELAY/docs/_static/u097-to-core.jpg b/examples/Units/4-RELAY/docs/_static/u097-to-core.jpg new file mode 100644 index 00000000..7c849c9e Binary files /dev/null and b/examples/Units/4-RELAY/docs/_static/u097-to-core.jpg differ diff --git a/examples/Units/4-RELAY/docs/_static/u097-to-pico.jpg b/examples/Units/4-RELAY/docs/_static/u097-to-pico.jpg new file mode 100644 index 00000000..864055a4 Binary files /dev/null and b/examples/Units/4-RELAY/docs/_static/u097-to-pico.jpg differ diff --git a/examples/Units/4-RELAY/docs/_static/u097.jpg b/examples/Units/4-RELAY/docs/_static/u097.jpg new file mode 100644 index 00000000..e765ee46 Binary files /dev/null and b/examples/Units/4-RELAY/docs/_static/u097.jpg differ diff --git a/examples/Units/4-RELAY/examples/test_async.py b/examples/Units/4-RELAY/examples/test_async.py new file mode 100644 index 00000000..3f649224 --- /dev/null +++ b/examples/Units/4-RELAY/examples/test_async.py @@ -0,0 +1,47 @@ +""" +Test ASYNC mode the MicroPython driver for M5Stack U097, 4 relays I2C grove unit. + +In ASYNC mode, the LED can be controled independantly from the relays + +* Author(s): + 28 may 2021: Meurisse D. (shop.mchobby.be) - port to MicroPython + https://github.com/m5stack/M5Stack/blob/master/examples/Unit/4-RELAY/4-RELAY.ino +""" + +from machine import I2C +from m4relay import Relays +from time import sleep_ms, sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +rel = Relays(i2c) + +# The LED is controled independantly +rel.synchronize( False ) + +# blink leds +def blink_leds(): + global rel + for count in range( 10 ): + for i in range( 4 ): + rel.led(i,True) + sleep_ms(100) + for i in range( 4 ): + rel.led(i,False) + sleep_ms(100) + + +# Switch all relay ON +for i in range(4): # from 1 to 3 + rel.relay( i, True ) + blink_leds(); + sleep( 1 ) + +# Switch All relay OFF +for i in range(4): # from 1 to 3 + rel.relay( i, False ) + blink_leds() + sleep( 1 ) diff --git a/examples/Units/4-RELAY/examples/test_simple.py b/examples/Units/4-RELAY/examples/test_simple.py new file mode 100644 index 00000000..04b607be --- /dev/null +++ b/examples/Units/4-RELAY/examples/test_simple.py @@ -0,0 +1,32 @@ +""" +Test the MicroPython driver for M5Stack U097, 4 relays I2C grove unit. + +In SYNC mode, the LED is controled by the RELAY state + +* Author(s): + 28 may 2021: Meurisse D. (shop.mchobby.be) - port to MicroPython + https://github.com/m5stack/M5Stack/blob/master/examples/Unit/4-RELAY/4-RELAY.ino +""" + +from machine import I2C +from m4relay import Relays +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +rel = Relays(i2c) + +# The LED is controled with the Relay + +# Switch all relay ON +for i in range(4): # from 1 to 3 + rel.relay( i, True ) + sleep( 1 ) + +# Switch All relay OFF +for i in range(4): # from 1 to 3 + rel.relay( i, False ) + sleep( 1 ) diff --git a/examples/Units/4-RELAY/lib/m4relay.py b/examples/Units/4-RELAY/lib/m4relay.py new file mode 100644 index 00000000..90fc598d --- /dev/null +++ b/examples/Units/4-RELAY/lib/m4relay.py @@ -0,0 +1,56 @@ +""" +m4relay.py : MicroPython driver for M5Stack U097, 4 relays I2C grove unit. +* Author(s): + 28 may 2021: Meurisse D. (shop.mchobby.be) - port to MicroPython + https://github.com/m5stack/M5Stack/blob/master/examples/Unit/4-RELAY/4-RELAY.ino +""" + +__version__ = "0.0.1.0" +__repo__ = "https://github.com/mchobby/esp8266-upy/tree/master/m5stack-u097" + +from micropython import const + + +SYS_CTRL = const(0x10) # System control +IO_CTRL = const(0X11) # Relay_ctrl_mode_reg + + +class Relays: + """ Drive the 4-Relays unit (U097) + :param i2c: the connected i2c bus machine.I2C + :param address: the device address; defaults to 0x26 """ + + def __init__(self, i2c, address=0x26): + self.i2c = i2c + self.address = address + self.io_buf = bytearray(1) # LED & Relay states + self.buf1 = bytearray(1) + + self.synchronize( True ) + self.io_buf[0] = 0x00 # set all off + self.i2c.writeto_mem( self.address, IO_CTRL, self.io_buf ) + + def synchronize( self, synch = True ): + """ Synchronize the Relay and the LED, switch on the relay will also switch the LED """ + self.buf1[0] = 0x01 if synch else 0x00 + self.i2c.writeto_mem( self.address, SYS_CTRL, self.buf1 ) + + def relay( self, index, state ): + """ Change the state of the relay """ + assert 0<= index <=3, 'Invalid relay index' + if state: + self.io_buf[0] |= (1<>> import test_char +e +en +enc +enco +encod +encode +encode +encode u +encode un +encode u +encode +encode a +encode a +encode a s +encode a st +encode a str +encode a stri +encode a strin +encode a string +Return pressed! Blank string + +h +he +hel +hell +hello +``` + +## read_key + +The [`test_readkey.py`](examples/test_readkey.py) example uses the `CardKB.read_key()` method returning a `(keycode, ascii/None, modifier)` tuple with: +* __keycode__ : the code of the pressed key. The `CardKB.is_ctrl()` method detect if the char is a control char Carriage Return, Backspace, Esc, etc. +* __ascii__ : ASCII char (as possible) matching the pressed key. Warning: the return key does return a true Carriage Return char. Note that `test_readkey.py` example substitute the control char with a human readeable string. +* __modifier__ : detect if the SYM (Symbol) key or FN (Function) key is pressed. + +``` +from machine import I2C +from cardkb import * + +# Pyboard : X10=sda, X9=scl +# PYBStick: S3=sda, S5=scl +i2c = I2C(1) +# M5Stack : Connecteur Grove - réduire la vitesse est nécessaire +# i2c = I2C(freq=100000, sda=21, scl=22) + +keyb = CardKB( i2c ) + +MOD_TEXT = { MOD_NONE : 'none', MOD_SYM : 'SYMBOL', MOD_FN : 'FUNCTION'} +CTRL_NAME = {0xB5:'UP',0xB4:'LEFT',0xB6:'DOWN',0xB7:'RIGHT',0x1B:'ESC',0x09:'TAB',0x08:'BS',0x7F:'DEL',0x0D:'CR'} + +print( 'Keycode | Ascii | Modifier' ) +print( '---------------------------') +while True: + keycode,ascii,modifier = keyb.read_key() + + # No key pressed = nothing to display + if keycode == None: + continue + + # The control key can't be displayed safely. + # So try to replace the control char with readable label + if keyb.is_ctrl( keycode ): + if keycode in CTRL_NAME: + ascii = CTRL_NAME[keycode] + else: # we do not know the name for that KeyCode + ascii = 'ctrl' # so we replace it with "ctrl" string + + # Display the Key Code, the char and modifier key (if it applies) + print( " %5s | %5s | %s" %(hex(keycode), ascii, MOD_TEXT[modifier]) ) + +``` + +Which produce the following results: + +``` +>>> import test_readkey +Keycode | Ascii | Modifier +--------------------------- + 0xb5 | UP | none + 0xb6 | DOWN | none + 0xb4 | LEFT | none + 0xb7 | RIGHT | none + 0xb7 | RIGHT | none + 0xb7 | RIGHT | FUNCTION + 0xb7 | RIGHT | none + 0x71 | q | none + 0x77 | w | none + 0x65 | e | none + 0x85 | None | FUNCTION + 0x35 | 5 | none + 0x50 | P | none + 0x22 | " | SYMBOL + 0x1b | ESC | none + 0x1b | ESC | none + 0x1b | ESC | none + 0x80 | None | FUNCTION + 0x8 | BS | none + 0x7f | DEL | none + 0x20 | | none + 0xaf | None | FUNCTION +``` diff --git a/examples/Units/DDS_AD9833/docs/_static/test_saw.jpg b/examples/Units/DDS_AD9833/docs/_static/test_saw.jpg new file mode 100644 index 00000000..7ddd2ab0 Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/test_saw.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/test_simple.jpg b/examples/Units/DDS_AD9833/docs/_static/test_simple.jpg new file mode 100644 index 00000000..cbbbf6e0 Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/test_simple.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/test_waves_0.jpg b/examples/Units/DDS_AD9833/docs/_static/test_waves_0.jpg new file mode 100644 index 00000000..4ec252ca Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/test_waves_0.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/test_waves_1.jpg b/examples/Units/DDS_AD9833/docs/_static/test_waves_1.jpg new file mode 100644 index 00000000..6f065269 Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/test_waves_1.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/u105-to-core.jpg b/examples/Units/DDS_AD9833/docs/_static/u105-to-core.jpg new file mode 100644 index 00000000..c5ebdae0 Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/u105-to-core.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/u105-to-pico.jpg b/examples/Units/DDS_AD9833/docs/_static/u105-to-pico.jpg new file mode 100644 index 00000000..3988c59a Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/u105-to-pico.jpg differ diff --git a/examples/Units/DDS_AD9833/docs/_static/u105.jpg b/examples/Units/DDS_AD9833/docs/_static/u105.jpg new file mode 100644 index 00000000..ec902d36 Binary files /dev/null and b/examples/Units/DDS_AD9833/docs/_static/u105.jpg differ diff --git a/examples/Units/DDS_AD9833/examples/test_freq.py b/examples/Units/DDS_AD9833/examples/test_freq.py new file mode 100644 index 00000000..91337a5c --- /dev/null +++ b/examples/Units/DDS_AD9833/examples/test_freq.py @@ -0,0 +1,29 @@ +""" +Test the MicroPython driver for M5Stack U105, DDS unit (AD9833), I2C grove. + +Set the frequency (optimized) for a Sine signal + +* Author(s): + 29 may 2021: Meurisse D. (shop.mchobby.be) - Initial Writing +""" + +from machine import I2C +from mdds import * +from time import sleep_ms + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + + +dds = DDS(i2c) +# quick_out set & use the freq register 0 & phase register 0 +dds.quick_out( SINUS_MODE, freq=10000, phase=0 ) + +# set_freq() is I2C bus efficient but will reset signal mode to sinus +while True: + for f in range( 10000, 1000000, 10000 ): + print( 'Set freq @ %s KHz' % (f//1000) ) + dds.set_freq( reg=0, freq=f ) + sleep_ms(100) diff --git a/examples/Units/DDS_AD9833/examples/test_freq2.py b/examples/Units/DDS_AD9833/examples/test_freq2.py new file mode 100644 index 00000000..952df5ff --- /dev/null +++ b/examples/Units/DDS_AD9833/examples/test_freq2.py @@ -0,0 +1,33 @@ +""" +Test the MicroPython driver for M5Stack U105, DDS unit (AD9833), I2C grove. + +Set the frequency for any Sine, Square, Triangle signal + +* Author(s): + 29 may 2021: Meurisse D. (shop.mchobby.be) - Initial Writing +""" + +from machine import I2C +from mdds import * +from time import sleep_ms + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + + +dds = DDS(i2c) +# quick_out set & use the freq register 0 & phase register 0 +dds.quick_out( TRIANGLE_MODE, freq=10000, phase=0 ) + +# on not sinusoidal waveform, quick_out() must be used to change the frequency +while True: + for f in range( 10000, 100000, 10000 ): + print( 'Set freq @ %s KHz' % (f//1000) ) + dds.quick_out( TRIANGLE_MODE, freq=f, phase=0 ) + sleep_ms(100) + for f in range( 100000, 10000, -10000 ): + print( 'Set freq @ %s KHz' % (f//1000) ) + dds.quick_out( TRIANGLE_MODE, freq=f, phase=0 ) + sleep_ms(100) diff --git a/examples/Units/DDS_AD9833/examples/test_saw.py b/examples/Units/DDS_AD9833/examples/test_saw.py new file mode 100644 index 00000000..f4472bdc --- /dev/null +++ b/examples/Units/DDS_AD9833/examples/test_saw.py @@ -0,0 +1,22 @@ +""" +Test the MicroPython driver for M5Stack U105, DDS unit (AD9833), I2C grove. + +Set SAWTOOTH signal output (this have fixed frequency) + +* Author(s): + 30 may 2021: Meurisse D. (shop.mchobby.be) - Initial Writing +""" + +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +dds = DDS(i2c) + +# Generates the SAW TOOTH signal at 55.9Hz (fixed frequency) +dds.quick_out( SAWTOOTH_MODE, freq=1, phase=0 ) diff --git a/examples/Units/DDS_AD9833/examples/test_simple.py b/examples/Units/DDS_AD9833/examples/test_simple.py new file mode 100644 index 00000000..39cbb939 --- /dev/null +++ b/examples/Units/DDS_AD9833/examples/test_simple.py @@ -0,0 +1,23 @@ +""" +Test the MicroPython driver for M5Stack U105, DDS unit (AD9833), I2C grove. + +Set a 10 KHz Sinewave + +* Author(s): + 29 may 2021: Meurisse D. (shop.mchobby.be) - Initial Writing +""" + +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +dds = DDS(i2c) + +freq = 10000 # 10 KHz +phase = 0 +dds.quick_out( SINUS_MODE, freq, phase ) diff --git a/examples/Units/DDS_AD9833/examples/test_waves.py b/examples/Units/DDS_AD9833/examples/test_waves.py new file mode 100644 index 00000000..31a3ac24 --- /dev/null +++ b/examples/Units/DDS_AD9833/examples/test_waves.py @@ -0,0 +1,28 @@ +""" +Test the MicroPython driver for M5Stack U105, DDS unit (AD9833), I2C grove. + +Iterate through the common Signal (note that SAWTOOTH have fixed freq of 55.9 Hz) + +* Author(s): + 29 may 2021: Meurisse D. (shop.mchobby.be) - Initial Writing +""" + +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +shapes = ( SINUS_MODE, TRIANGLE_MODE, SQUARE_MODE, SAWTOOTH_MODE ) +shape_names = { SINUS_MODE : "Sinus", TRIANGLE_MODE : "Triangle", + SQUARE_MODE : "Square", SAWTOOTH_MODE : "SawTooth"} +dds = DDS(i2c) + +while True: + for shape in shapes: + print( '%s @ 10 KHz' % shape_names[shape] ) + dds.quick_out( shape, freq=10000, phase=0 ) + sleep( 1 ) diff --git a/examples/Units/DDS_AD9833/lib/mdds.py b/examples/Units/DDS_AD9833/lib/mdds.py new file mode 100644 index 00000000..d2b69de1 --- /dev/null +++ b/examples/Units/DDS_AD9833/lib/mdds.py @@ -0,0 +1,147 @@ +""" +mdds.py : MicroPython driver for M5Stack U105, 4 relays I2C grove unit. +* Author(s): + 28 may 2021: Meurisse D. (shop.mchobby.be) - port to MicroPython + https://github.com/m5stack/M5Stack/tree/master/examples/Unit/DDS_AD9833 +""" + +__version__ = "0.0.1.0" +__repo__ = "https://github.com/mchobby/esp8266-upy/tree/master/m5stack-u105" + +from micropython import const + +#define DDS_UNIT_I2CADDR 0x31 + +DDS_DESC_REG = const(0x10) # Description of interface +DDS_MODE_REG = const(0x20) +DDS_CTRL_REG = const(0x21) +DDS_FREQ_REG = const(0x30) +DDS_PHASE_REG = const(0x34) + +DDS_FMCLK = const(10000000) + +RESERVED_MODE = const(0) +SINUS_MODE = const(1) +TRIANGLE_MODE = const(2) +SQUARE_MODE = const(3) +SAWTOOTH_MODE = const(4) +DC_MODE = const(5) + +DDS_MODES = (RESERVED_MODE, SINUS_MODE, TRIANGLE_MODE, SQUARE_MODE, SAWTOOTH_MODE, DC_MODE) + +class DDS: + """ Drive the DDS AD9833 unit (U105) + :param i2c: the connected i2c bus machine.I2C + :param address: the device address; defaults to 0x26 """ + + # AD9833 have 2 output reg configurable and user code can set the output + # with the data coming from output reg 1 / output reg 2 + + def __init__(self, i2c, address=0x31): + self.i2c = i2c + self.address = address + self.desc_buf = bytearray(6) + self.buf2 = bytearray(2) + self.buf4 = bytearray(4) + self.buf1 = bytearray(1) + self.i2c.readfrom_mem_into( self.address, DDS_DESC_REG, self.desc_buf ) + if self.desc_buf != bytes( 'ad9833', 'ASCII' ): + raise Exception( 'Invalid board description!') + + def set_freq( self, reg, freq ): # uint8_t reg ,uint64_t freq + """ Change the frequency of signal (will switch back signal to SINUS mode!) """ + assert reg in (0,1), 'invalid freq register!' + + freq = int(freq * 268435456 / DDS_FMCLK) + + self.buf4[0] = (( freq >> 24 ) & 0xff ) | (0xC0 if reg == 1 else 0x80 ) + self.buf4[1] = (( freq >> 16 ) & 0xff ) + self.buf4[2] = (( freq >> 8 ) & 0xff ) + self.buf4[3] = ( freq & 0xff ) + # writeDDSReg(DDS_FREQ_ADDR,sendbuff,4); + self.i2c.writeto_mem( self.address, DDS_FREQ_REG, self.buf4 ) + + + def set_phase( self, reg, phase ): # uint8_t reg ,uint32_t phase + """ Change the phase of the signal """ + assert reg in (0,1), 'invalid phase register!' + assert 0<= phase <360 + + phase = int(phase * 2048 / 360) + self.buf2[0] = (( phase >> 8 ) & 0xff ) | ( 0xC0 if reg == 1 else 0x80 ) + self.buf2[1] = ( phase & 0xff ) + + # writeDDSReg(DDS_PHASE_ADDR,sendbuff,2); + self.i2c.writeto_mem( self.address, DDS_PHASE_REG, self.buf2 ) + + def set_freq_and_phase( self, freg, freq, preg, phase ): # uint8_t freg, uint64_t freq, uint8_t preg, uint32_t phase + self.set_freq( freg, freq ) + self.set_phase( preg, phase ) + + def mode( self, dds_mode ): + """ Set the type of WaveForm """ + assert dds_mode in DDS_MODES + self.buf1[0] = 0x80 | dds_mode + self.i2c.writeto_mem( self.address, DDS_MODE_REG, self.buf1 ) + + #def ctrl( self, ctrlbyte ): # uint8_t + # writeDDSReg(DDS_CTRL_ADDR,0x80 | ctrlbyte ); + # pass + + def select_freq_reg( self, num ): # uint8_t + """ Which freq reg to activates as output """ + # uint8_t reg = readDDSReg(DDS_CTRL_ADDR); + self.i2c.readfrom_mem_into( self.address, DDS_CTRL_REG, self.buf1 ) + # reg &= (~0x40); + self.buf1[0] = self.buf1[0] & (0xFF^0x40) + # writeDDSReg(DDS_CTRL_ADDR,reg | 0x80 | ( num == 1 ) ? 0x40 : 0 ); + self.buf1[0] = self.buf1[0] | 0x80 | 0x40 if num==1 else 0x00 + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1 ) + + def select_phase_reg( self, num ): # uint8_t + """ Which freq reg to activates as output """ + assert num in (0,1) + # uint8_t reg = readDDSReg(DDS_CTRL_ADDR); + self.i2c.readfrom_mem_into( self.address, DDS_CTRL_REG, self.buf1 ) + # reg &= (~0x20); + self.buf1[0] = self.buf1[0] & (0xFF^0x20) + # writeDDSReg(DDS_CTRL_ADDR, reg | 0x80 | ( num == 1 ) ? 0x20 : 0 ); + self.buf1[0] = self.buf1[0] | 0x80 | 0x20 if num==1 else 0x00 + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1 ) + + def out( self, freqnum, phasenum): # OUT(uint8_t freqnum,uint8_t phasenum); + """ Which output regs to activate to the output """ + assert freqnum in (0,1), 'Invalid freqnum!' + assert phasenum in (0,1), 'Invalid phasenum!' + #uint8_t reg = readDDSReg(DDS_CTRL_ADDR); + self.i2c.readfrom_mem_into( self.address, DDS_CTRL_REG, self.buf1 ) + self.buf1[0] = self.buf1[0] & (0xFF^0x60) + self.buf1[0] = buf1[0] | 0x80 | ( 0x40 if freqnum == 1 else 0x00 ) | ( 0x20 if phasenum == 1 else 0x00 ) + # writeDDSReg(DDS_CTRL_ADDR, reg | 0x80 | (( freqnum == 1 ) ? 0x40 : 0 ) | (( phasenum == 1 ) ? 0x20 : 0 )); + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1 ) + + def quick_out( self, dds_mode, freq, phase): # uint64_t freq, uint32_t phase + """ Quickly set the reg 0 freq, reg 0 phase and activates it as output """ + if dds_mode <= SQUARE_MODE: + self.set_freq_and_phase( 0,freq, 0,phase ) + self.buf1[0] = 0x80 | dds_mode + self.i2c.writeto_mem( self.address, DDS_MODE_REG, self.buf1 ) + self.buf1[0] = 0x80 | 0x00 + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1 ) + + def set_sleep( self, level ): # uint8_t + assert level in (0,1,2), 'Invalid level!' + # uint8_t reg = readDDSReg(DDS_CTRL_ADDR); + self.i2c.readfrom_mem_into( self.address, DDS_CTRL_REG, self.buf1 ) + #reg &= (~0x18); + self.buf1[0] = self.buf1[0] & (0xFF^0x18) + #reg |= ( level == 1 ) ? 0x10 : 0; + self.buf1[0] = self.buf1[0] | (0x10 if level==1 else 0x00 ) + #reg |= ( level == 2 ) ? 0x08 : 0; + self.buf1[0] = self.buf1[0] | (0x08 if level==2 else 0x00 ) + # writeDDSReg( DDS_CTRL_ADDR, 0x80 | reg ); + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1) + + def reset( self ): + self.buf1[0] = 0x80 | 0x04 + self.i2c.writeto_mem( self.address, DDS_CTRL_REG, self.buf1 ) diff --git a/examples/Units/DDS_AD9833/readme.md b/examples/Units/DDS_AD9833/readme.md new file mode 100644 index 00000000..850fc999 --- /dev/null +++ b/examples/Units/DDS_AD9833/readme.md @@ -0,0 +1,134 @@ +# Use the DDS Unit AD9833 (U105) with I2C Grove under MicroPython + +The "[U105: DDS Unit AD9833](https://shop.mchobby.be/fr/nouveaute/2151-m5stack-generateur-de-signal-dds-stm32f0-ad9833-grove-3232100021518.html)" from M5Stack is an I2C module used to generates sinewave, square wave, triangle ware and sawtooth wave with tuning of frequence and phase. This module does fit a Grove interface used to ease the wiring on compatible microcontroler plateform. + +![U105 - DDS Unit (AD9833), I2C, Grove interface](docs/_static/u105.jpg) + +__Please note:__ +* The AD9833 output signal is around 680mV. +* The SawTooth fequency is fixed at 55.9 Hz. + +__Remarks:__ +This driver is sourced from [esp8266-upy GitHub](https://github.com/mchobby/esp8266-upy) maintained by [MCHobby](http://shop.mchobby.be) + +# Wiring + +## Wire to Pico + +![U105 to pico](docs/_static/u105-to-pico.jpg) + +## Wire to M5Stack Core + +![U105 to Core](docs/_static/u105-to-core.jpg) + +# Testing + +The library [lib/mdds.py](lib/mdds.py) must be copied to the board before running the various examples. + +## test_simple + +The [test_simple.py](examples/test_simple.py) scipt, visible here below, will creates a 10 KHz sine wave. + +``` python +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +dds = DDS(i2c) + +freq = 10000 # 10 KHz +phase = 0 +dds.quick_out( SINUS_MODE, freq, phase ) +``` +![U105 - Sine output](docs/_static/test_simple.jpg) + +## test_waves + +The [test_waves.py](examples/test_waves.py) script change the kind of waveform evey second. + +``` python +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +shapes = ( SINUS_MODE, TRIANGLE_MODE, SQUARE_MODE, SAWTOOTH_MODE ) +shape_names = { SINUS_MODE : "Sinus", TRIANGLE_MODE : "Triangle", + SQUARE_MODE : "Square", SAWTOOTH_MODE : "SawTooth"} +dds = DDS(i2c) + +while True: + for shape in shapes: + print( '%s @ 10 KHz' % shape_names[shape] ) + dds.quick_out( shape, freq=10000, phase=0 ) + sleep( 1 ) +``` + +The screen capture here below shows the triangle and square generated with the module. + +![U105 - triangle output](docs/_static/test_waves_0.jpg) + +![U105 - square output](docs/_static/test_waves_1.jpg) + +## test_freq + +The [test_freq.py](examples/test_freq.py) script change the sinewave frequency from 10 KHz (10 000 Hz) to 1 MHz (1 000 000 Hz). + +See the [test_freq2.py](examples/test_freq2.py) example for Square and Triangle waveform. + +``` python +from machine import I2C +from mdds import * +from time import sleep_ms + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + + +dds = DDS(i2c) +# quick_out set & use the freq register 0 & phase register 0 +dds.quick_out( SINUS_MODE, freq=10000, phase=0 ) + +# set_freq() is I2C bus efficient but will reset signal mode to sinus +while True: + for f in range( 10000, 1000000, 10000 ): + print( 'Set freq @ %s KHz' % (f//1000) ) + dds.set_freq( reg=0, freq=f ) + sleep_ms(100) +``` + +## test_saw + +The [test_saw.py](examples/test_saw.py) script does set the signal output to sawtooth. + +__REMARKS:__ The sawtooth signal is generated at fixed 55.9Hz frequency. + +``` python +from machine import I2C +from mdds import * +from time import sleep + +# Pico - I2C(0) - sda=GP8, scl=GP9 +i2c = I2C(0) +# M5Stack core +# i2c = I2C( sda=Pin(21), scl=Pin(22) ) + +dds = DDS(i2c) + +# Generates the SAW TOOTH signal at 55.9Hz (fixed frequency) +dds.quick_out( SAWTOOTH_MODE, freq=1, phase=0 ) +``` + +![U105 - Saw tooth output](docs/_static/test_saw.jpg) +