├── LICENSE ├── Nano-RP2040-Connect ├── PDMLights │ ├── PDMLights.ino │ └── README.md └── README.md ├── README.md ├── arduino-i2c ├── pico-pi-i2c.py └── sketch_i2c_sub │ └── sketch_i2c_sub.ino ├── blinkenlights ├── README.md └── neo-noise.py ├── esp01-uart ├── Server │ ├── index.html │ └── simple_server.py ├── Wifi │ └── Wifi.ino └── esp01-uart-wifi.py ├── nrf24l01-spi └── button.py ├── pico-adc ├── adc-servos.py └── adc-simple.py ├── pio-steppers ├── test_motor1.py ├── test_motor2.py ├── test_motor3.py └── test_motor4.py ├── pwm-servo └── servo.py └── ssd1306-oled-i2c ├── demo.py └── demo2.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 tinkertechtrove 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Nano-RP2040-Connect/PDMLights/PDMLights.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #define CHANS 1 6 | #define PCM_FREQ 16000; 7 | 8 | // Buffer to read samples into, each sample is 16-bits 9 | short sampleBuffer[512]; 10 | 11 | // Number of audio samples read 12 | volatile int samplesRead; 13 | 14 | 15 | #define LED_PIN 25 16 | #define LED_COUNT 20 17 | #define BRIGHTNESS 50 // Set BRIGHTNESS to about 1/5 (max = 255) 18 | 19 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_RGBW + NEO_KHZ800); 20 | // Argument 1 = Number of pixels in NeoPixel strip 21 | // Argument 2 = Arduino pin number (most are valid) 22 | // Argument 3 = Pixel type flags, add together as needed: 23 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 24 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 25 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 26 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 27 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 28 | 29 | 30 | void setup() { 31 | //pinMode(LED_PIN, OUTPUT); 32 | strip.begin(); 33 | strip.show(); 34 | strip.setBrightness(BRIGHTNESS); 35 | 36 | Serial.begin(9600); 37 | 38 | // Configure the data receive callback 39 | PDM.onReceive(onPDMdata); 40 | PDM.setGain(-20); // Optionally set the gain 41 | 42 | // Initialize PDM with: 43 | if (!PDM.begin(CHANS, PCM_FREQ)) { 44 | Serial.println("Failed to start PDM!"); 45 | while (1); 46 | } 47 | 48 | } 49 | 50 | void loop() { 51 | uint32_t col = strip.Color(0, 0, 0); 52 | for(int i=0; i 3 | 4 | #define UNO_ADDR 9 5 | #define RESP_SIZE 15 6 | 7 | String data = "Hi from Arduino"; 8 | 9 | void setup() 10 | { 11 | Serial.begin(9600); 12 | Wire.begin(UNO_ADDR); 13 | /*Event Handlers*/ 14 | Wire.onReceive(DataReceive); 15 | Wire.onRequest(DataRequest); 16 | } 17 | 18 | void loop() 19 | { 20 | delay(50); 21 | } 22 | 23 | void DataReceive(int numBytes) 24 | { 25 | int i=0; 26 | char data[RESP_SIZE]; 27 | memset(data,0, RESP_SIZE); 28 | while(Wire.available()) 29 | { 30 | data[i++] = Wire.read(); 31 | } 32 | 33 | Serial.println("Recv Event"); 34 | Serial.println(String(data)); 35 | } 36 | 37 | void DataRequest() 38 | { 39 | byte resp[RESP_SIZE]; 40 | for (byte i=0; i> 8) & 0xFF) * brightness) 41 | g = int(((c >> 16) & 0xFF) * brightness) 42 | b = int((c & 0xFF) * brightness) 43 | dimmer_ar[i] = (g<<16) + (r<<8) + b 44 | sm.put(dimmer_ar, 8) 45 | time.sleep_ms(10) 46 | 47 | def pixels_set(i, color): 48 | ar[i] = (color[1]<<16) + (color[0]<<8) + color[2] 49 | 50 | def pixels_fill(color): 51 | for i in range(len(ar)): 52 | pixels_set(i, color) 53 | 54 | def color_chase(color, wait): 55 | for i in range(NUM_LEDS): 56 | pixels_set(i, color) 57 | time.sleep(wait) 58 | pixels_show() 59 | time.sleep(0.2) 60 | 61 | def wheel(pos): 62 | # Input a value 0 to 255 to get a color value. 63 | # The colours are a transition r - g - b - back to r. 64 | if pos < 0 or pos > 255: 65 | return (0, 0, 0) 66 | if pos < 85: 67 | return (255 - pos * 3, pos * 3, 0) 68 | if pos < 170: 69 | pos -= 85 70 | return (0, 255 - pos * 3, pos * 3) 71 | pos -= 170 72 | return (pos * 3, 0, 255 - pos * 3) 73 | 74 | 75 | def rainbow_cycle(wait): 76 | for j in range(255): 77 | for i in range(NUM_LEDS): 78 | rc_index = (i * 256 // NUM_LEDS) + j 79 | pixels_set(i, wheel(rc_index & 255)) 80 | pixels_show() 81 | time.sleep(wait) 82 | 83 | BLACK = (0, 0, 0) 84 | RED = (255, 0, 0) 85 | YELLOW = (255, 150, 0) 86 | GREEN = (0, 255, 0) 87 | CYAN = (0, 255, 255) 88 | BLUE = (0, 0, 255) 89 | PURPLE = (180, 0, 255) 90 | WHITE = (255, 255, 255) 91 | COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE) 92 | 93 | #print("fills") 94 | #for color in COLORS: 95 | # pixels_fill(color) 96 | # pixels_show() 97 | # time.sleep(0.2) 98 | 99 | #print("chases") 100 | #for color in COLORS: 101 | # color_chase(color, 0.01) 102 | 103 | #print("rainbow") 104 | #rainbow_cycle(0) 105 | 106 | 107 | #------- 108 | # Worley Noise Generator 109 | # http://en.wikipedia.org/wiki/Worley_noise 110 | # FB36 - 20130216 111 | import math 112 | import gc 113 | import random 114 | 115 | # ----- 116 | 117 | def HueToRGB(h, s=1, v=1): 118 | h = float(h) 119 | s = float(s) 120 | v = float(v) 121 | h60 = h / 60.0 122 | h60f = math.floor(h60) 123 | hi = int(h60f) % 6 124 | f = h60 - h60f 125 | p = v * (1 - s) 126 | q = v * (1 - f * s) 127 | t = v * (1 - (1 - f) * s) 128 | r, g, b = 0, 0, 0 129 | if hi == 0: 130 | r, g, b = v, t, p 131 | elif hi == 1: 132 | r, g, b = q, v, p 133 | elif hi == 2: 134 | r, g, b = p, v, t 135 | elif hi == 3: 136 | r, g, b = p, q, v 137 | elif hi == 4: 138 | r, g, b = t, p, v 139 | elif hi == 5: 140 | r, g, b = v, p, q 141 | r, g, b = int(r * 255), int(g * 255), int(b * 255) 142 | return r, g, b 143 | 144 | def calculateDistance(x1,y1,x2,y2): 145 | dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) 146 | return dist 147 | 148 | 149 | # --- 150 | 151 | imgx = 32; imgy = 8# image size 152 | 153 | pixels = [(0,0,0) for x in range(imgx*imgy)] 154 | n = 4 # of seed points 155 | m = 0 # random.randint(0, n - 1) # degree (?) 156 | seedsX = [random.randint(0, imgx - 1) for i in range(n)] 157 | seedsY = [random.randint(0, imgy - 1) for i in range(n)] 158 | dirsX = [1 for i in range(n)] 159 | dirsY = [1 for i in range(n)] 160 | 161 | pixels_fill(BLACK) 162 | pixels_show() 163 | 164 | while True: 165 | #time.sleep(0.1) 166 | for i in range(n): 167 | seedsX[i] = seedsX[i] + dirsX[i] 168 | if seedsX[i] >= imgx: 169 | dirsX[i] = -1 170 | if seedsX[i] <= 0: 171 | dirsX[i] = 1 172 | 173 | seedsY[i] = seedsY[i] + dirsY[i] 174 | if seedsY[i] >= imgy: 175 | dirsY[i] = -1 176 | if seedsY[i] <= 0: 177 | dirsY[i] = 1 178 | 179 | # find max distance 180 | maxDist = 0.0 181 | for ky in range(imgy): 182 | for kx in range(imgx): 183 | # create a sorted list of distances to all seed points 184 | dists = [calculateDistance(seedsX[i], seedsY[i], kx, ky) for i in range(n)] 185 | dists.sort() 186 | if dists[m] > maxDist: maxDist = dists[m] 187 | 188 | # paint 189 | for ky in range(imgy): 190 | for kx in range(imgx): 191 | # create a sorted list of distances to all seed points 192 | dists = [calculateDistance(seedsX[i], seedsY[i], kx, ky) for i in range(n)] 193 | dists.sort() 194 | c = int(round(255 * dists[m] / maxDist)) 195 | pixels[ky * imgx + kx] = HueToRGB(c) 196 | dists = None 197 | #gc.collect() 198 | 199 | for y in range(imgy/2): 200 | for x in range(imgx): 201 | #pixels_set((y*2)*imgx+x, RED) 202 | pixels_set((y*2)*imgx+x, pixels[y * imgx + x]) 203 | 204 | for x in range(imgx): 205 | pixels_set((y*2+1)*imgx+x, pixels[y * imgx + (imgx - x - 1)]) 206 | 207 | #else: 208 | # pixels_set(y*imgx+x, BLACK) 209 | 210 | pixels_show() 211 | -------------------------------------------------------------------------------- /esp01-uart/Server/index.html: -------------------------------------------------------------------------------- 1 | Wooo this works :-) 2 | -------------------------------------------------------------------------------- /esp01-uart/Server/simple_server.py: -------------------------------------------------------------------------------- 1 | import http.server 2 | import socketserver 3 | 4 | PORT = 80 5 | Handler = http.server.SimpleHTTPRequestHandler 6 | 7 | with socketserver.TCPServer(("", PORT), Handler) as httpd: 8 | print("serving at port", PORT) 9 | httpd.serve_forever() 10 | -------------------------------------------------------------------------------- /esp01-uart/Wifi/Wifi.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | 6 | #define GPIO_STATUS 2 7 | 8 | // This was tested on an ESP-01s. Users of non-S varient ESP-01 modules have reported 9 | // needing to change "Builtin Led" in the sketch tools menu from "2" to "1" 10 | 11 | 12 | void setup() { 13 | Serial.begin(115200); // Serial UART boardrate 14 | 15 | // status pin GPIO2 16 | pinMode(GPIO_STATUS, OUTPUT); 17 | digitalWrite(GPIO_STATUS, LOW); 18 | pinMode(LED_BUILTIN, OUTPUT); // to flash the LED 19 | 20 | // WiFi details - note this does not handle reconnection 21 | WiFi.mode(WIFI_STA); 22 | WiFi.begin("SSID", "PASSWORD"); 23 | while (WiFi.status() != WL_CONNECTED) { 24 | delay(500); 25 | } 26 | digitalWrite(GPIO_STATUS, HIGH); // set status to say we are online 27 | Serial.flush(); 28 | } 29 | 30 | void send(const char* data) { 31 | if(data){ 32 | unsigned int len = htonl(strlen(data)); 33 | Serial.write("msg"); 34 | Serial.write((char*)&len, 4); 35 | Serial.write(data); 36 | Serial.flush(); 37 | } 38 | } 39 | 40 | void fetch(char* url) { 41 | WiFiClient client; 42 | HTTPClient http; 43 | 44 | digitalWrite(LED_BUILTIN, LOW); // turn on the LED 45 | if (http.begin(url)) { // HTTP 46 | int httpCode = http.GET(); 47 | if (httpCode > 0) { // httpCode will be negative on error 48 | if (httpCode == HTTP_CODE_OK) { 49 | send(http.getString().c_str()); 50 | } 51 | } else { 52 | send(http.errorToString(httpCode).c_str()); 53 | } 54 | http.end(); 55 | } else { 56 | send("[HTTP] Unable to connect\n"); 57 | } 58 | digitalWrite(LED_BUILTIN, HIGH); // turn off the LED 59 | } 60 | 61 | char buf[128]; 62 | char* read_message() { 63 | if(!Serial.available()) { 64 | return NULL; 65 | } 66 | 67 | int idx = 0; 68 | memset(buf, 0, 128); 69 | while(idx < 7) { 70 | while(Serial.available() > 0) { // Checks is there any data in buffer (holds 64 bytes max) 71 | buf[idx++] = char(Serial.read()); // Read serial data byte 72 | } 73 | } 74 | 75 | if(memcmp(buf, "msg", 3) == 0) { 76 | unsigned int size = ntohl(*(unsigned int*)(buf + 3)); 77 | while(idx < size + 7 && idx < 120) { 78 | while(Serial.available() > 0) { 79 | buf[idx++] = char(Serial.read()); 80 | } 81 | } 82 | } else { 83 | return NULL; 84 | } 85 | 86 | return buf + 7; 87 | } 88 | 89 | 90 | void loop() { 91 | char* msg = read_message(); 92 | if(msg) { 93 | if(memcmp(msg, "sleep", 5) == 0) { 94 | send("ok"); 95 | digitalWrite(2, LOW); 96 | ESP.deepSleep(0, WAKE_RF_DEFAULT); // go to sleep 97 | } else { 98 | fetch(msg); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /esp01-uart/esp01-uart-wifi.py: -------------------------------------------------------------------------------- 1 | from machine import UART, Pin 2 | from time import sleep 3 | import struct 4 | 5 | uart0 = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1)) # UART tx/rx 6 | ready = Pin(3, Pin.IN, Pin.PULL_DOWN) # used to check the ESP01 status 7 | reset = Pin(2, Pin.OUT) # used to wake the ESP01 from deep sleep 8 | 9 | reset.value(1) # ESP01 reset pin, high in normal mode, low to reset 10 | 11 | 12 | def send_message(msg): 13 | print("Send msg ....") 14 | uart0.write(b'msg') 15 | uart0.write(struct.pack('!I', len(msg))) 16 | uart0.write(msg) 17 | 18 | # read the header 19 | rxData = bytes() 20 | while len(rxData) < 7: # add timeout ... 21 | while uart0.any() > 0: 22 | rxData += uart0.read(1) 23 | 24 | # decode the header 25 | if rxData[0:3] == b'msg': 26 | size = struct.unpack_from('!I', rxData, 3)[0] 27 | else: 28 | return '' # we dont understand the message 29 | 30 | # read the full message 31 | while len(rxData) < size + 7: 32 | while uart0.any() > 0: 33 | rxData += uart0.read(1) 34 | 35 | return rxData[7:].decode('utf-8') 36 | 37 | def esp01_ready(): 38 | while ready.value() == 0: 39 | print('.', end ="") 40 | sleep(0.1) 41 | 42 | for i in range(4): 43 | while uart0.any(): 44 | uart0.read(1) # empty any boot up data 45 | sleep(0.1) 46 | 47 | print("Ready") 48 | 49 | 50 | def esp01_sleep(): 51 | print('sleep') 52 | send_message('sleep') 53 | while ready.value() == 1: 54 | print('.', end="") 55 | sleep(0.1) 56 | print('ok') 57 | 58 | 59 | def esp01_wake(): 60 | print("wake") 61 | reset.value(0) 62 | sleep(0.1) 63 | reset.value(1) 64 | esp01_ready() 65 | 66 | 67 | 68 | esp01_ready() 69 | while True: 70 | sleep(10) 71 | print("Message:", send_message('http://192.168.1.237')) 72 | esp01_sleep() 73 | sleep(10) 74 | esp01_wake() 75 | 76 | 77 | -------------------------------------------------------------------------------- /nrf24l01-spi/button.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, SPI 2 | import struct 3 | 4 | from nrf24l01 import NRF24L01 5 | 6 | led = Pin(25, Pin.OUT) # LED 7 | btn = Pin(28, Pin.IN, Pin.PULL_DOWN) # button press 8 | csn = Pin(15, mode=Pin.OUT, value=1) # chip select not 9 | ce = Pin(14, mode=Pin.OUT, value=0) # chip enable 10 | 11 | # Addresses are in little-endian format. They correspond to big-endian 12 | # 0xf0f0f0f0e1, 0xf0f0f0f0d2 - swap these on the other Pico! 13 | pipes = (b"\xe1\xf0\xf0\xf0\xf0", b"\xd2\xf0\xf0\xf0\xf0") 14 | 15 | def setup(): 16 | nrf = NRF24L01(SPI(0), csn, ce, payload_size=4) 17 | 18 | nrf.open_tx_pipe(pipes[0]) 19 | nrf.open_rx_pipe(1, pipes[1]) 20 | nrf.start_listening() 21 | 22 | led.value(0) 23 | return nrf 24 | 25 | def demo(nrf): 26 | state = 0 27 | while True: 28 | if state != btn.value(): 29 | state = btn.value() 30 | led.value(state) 31 | 32 | print("tx", state) 33 | nrf.stop_listening() 34 | try: 35 | nrf.send(struct.pack("i", state)) 36 | except OSError: 37 | print('message lost') 38 | nrf.start_listening() 39 | 40 | if nrf.any(): 41 | buf = nrf.recv() 42 | got = struct.unpack("i", buf)[0] 43 | print("rx", got) 44 | led.value(got) 45 | 46 | def auto_ack(nrf): 47 | nrf.reg_write(0x01, 0b11111000) # enable auto-ack on all pipes 48 | 49 | 50 | nrf = setup() 51 | auto_ack(nrf) 52 | demo(nrf) 53 | -------------------------------------------------------------------------------- /pico-adc/adc-servos.py: -------------------------------------------------------------------------------- 1 | from machine import ADC, PWM, Pin 2 | from time import sleep 3 | 4 | 5 | MIN_DUTY = 3000 # 5 percent of 65025 = 3251.25 6 | MAX_DUTY = 6000 # 10 percent of 65025 = 6502.5 7 | 8 | pwmX = PWM(Pin(0)) 9 | pwmX.freq(50) 10 | 11 | pwmY = PWM(Pin(1)) 12 | pwmY.freq(50) 13 | 14 | adcX = ADC(0) 15 | adcY = ADC(1) 16 | oldX = 0 17 | oldY = 0 18 | 19 | while True: 20 | valX = adcX.read_u16() 21 | valY = adcY.read_u16() 22 | if valX != oldX or valY != oldY: 23 | #print(MIN_DUTY + int((valX/65535) * MAX_DUTY)) 24 | pwmX.duty_u16(MIN_DUTY + int((valX/65535) * MAX_DUTY)) 25 | pwmY.duty_u16(MIN_DUTY + int((valY/65535) * MAX_DUTY)) 26 | sleep(0.1) 27 | oldX = valX 28 | oldY = valY 29 | -------------------------------------------------------------------------------- /pico-adc/adc-simple.py: -------------------------------------------------------------------------------- 1 | from machine import ADC, Pin 2 | from time import sleep 3 | 4 | adcX = ADC(0) 5 | adcY = ADC(1) 6 | oldX = 0 7 | oldY = 0 8 | 9 | while True: 10 | valX = adcX.read_u16() 11 | valY = adcY.read_u16() 12 | sleep(0.5) 13 | if valX != oldX or valY != oldY: 14 | print("X:", valX, " Y:", valY) 15 | oldX = valX 16 | oldY = valY -------------------------------------------------------------------------------- /pio-steppers/test_motor1.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from rp2 import PIO, StateMachine, asm_pio 3 | from time import sleep 4 | import sys 5 | 6 | @asm_pio(set_init=(PIO.OUT_LOW,) * 4) 7 | def prog(): 8 | wrap_target() 9 | set(pins, 8) [31] # 8 10 | nop() [31] 11 | nop() [31] 12 | nop() [31] 13 | nop() [31] 14 | nop() [31] 15 | nop() [31] 16 | set(pins, 4) [31] # 4 17 | nop() [31] 18 | nop() [31] 19 | nop() [31] 20 | nop() [31] 21 | nop() [31] 22 | nop() [31] 23 | set(pins, 2) [31] # 2 24 | nop() [31] 25 | nop() [31] 26 | nop() [31] 27 | nop() [31] 28 | nop() [31] 29 | nop() [31] 30 | set(pins, 1) [31] # 1 31 | nop() [31] 32 | nop() [31] 33 | nop() [31] 34 | nop() [31] 35 | nop() [31] 36 | nop() [31] 37 | wrap() 38 | 39 | 40 | sm = StateMachine(0, prog, freq=100000, set_base=Pin(2)) 41 | 42 | 43 | sm.active(1) 44 | sleep(50) 45 | sm.active(0) 46 | sm.exec("set(pins,0)") 47 | -------------------------------------------------------------------------------- /pio-steppers/test_motor2.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from rp2 import PIO, StateMachine, asm_pio 3 | from time import sleep 4 | import sys 5 | 6 | @asm_pio(set_init=(PIO.OUT_LOW,) * 4, 7 | out_init=(PIO.OUT_HIGH,) * 4, 8 | out_shiftdir=PIO.SHIFT_LEFT) 9 | def prog(): 10 | pull() 11 | mov(y, osr) # step pattern 12 | 13 | pull() 14 | mov(x, osr) # num steps 15 | 16 | jmp(not_x, "end") 17 | 18 | label("loop") 19 | jmp(not_osre, "step") # loop pattern if exhausted 20 | mov(osr, y) 21 | 22 | label("step") 23 | out(pins, 4) [31] 24 | nop() [31] 25 | nop() [31] 26 | nop() [31] 27 | 28 | jmp(x_dec,"loop") 29 | label("end") 30 | set(pins, 8) [31] # 8 31 | 32 | 33 | 34 | sm = StateMachine(0, prog, freq=10000, set_base=Pin(2), out_base=Pin(2)) 35 | 36 | sm.active(1) 37 | sm.put(2216789025) #1000 0100 0010 0001 1000010000100001 38 | sm.put(1000) 39 | sleep(5) 40 | sm.active(0) 41 | sm.exec("set(pins,0)") 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /pio-steppers/test_motor3.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from rp2 import PIO, StateMachine, asm_pio 3 | from time import sleep 4 | import sys 5 | 6 | @asm_pio(set_init=(PIO.OUT_LOW,) * 4, 7 | out_init=(PIO.OUT_LOW,) * 4, 8 | out_shiftdir=PIO.SHIFT_RIGHT, 9 | in_shiftdir=PIO.SHIFT_LEFT) 10 | def prog(): 11 | pull() 12 | mov(y, osr) # step pattern 13 | 14 | wrap_target() 15 | 16 | pull() 17 | mov(x, osr) # num steps 18 | 19 | mov(osr, y) # restore osr 20 | jmp(not_x, "end") 21 | 22 | label("loop") 23 | jmp(not_osre, "step") # loop pattern if exhausted 24 | mov(osr, y) 25 | 26 | label("step") 27 | out(pins, 4) [31] 28 | nop() [31] 29 | nop() [31] 30 | nop() [31] 31 | nop() [31] 32 | nop() [31] 33 | nop() [31] 34 | nop() [31] 35 | nop() [31] 36 | nop() [31] 37 | nop() [31] 38 | nop() [31] 39 | nop() [31] 40 | nop() [31] 41 | 42 | 43 | 44 | jmp(x_dec,"loop") 45 | label("end") 46 | 47 | 48 | # backup osr - this is broken 49 | #mov(isr, y) 50 | in_(y,32) 51 | label("bu_jump") 52 | in_(osr, 1) 53 | out(null, 1) 54 | jmp(not_osre, "bu_jump") 55 | mov(y, isr) 56 | 57 | irq(rel(0)) 58 | push() 59 | 60 | 61 | sm = StateMachine(0, prog, freq=0, set_base=Pin(2), out_base=Pin(2)) 62 | 63 | def turn(sm): 64 | a = sm.get() 65 | print("{0:b}".format(a)) 66 | sleep(1) 67 | sm.put(1) 68 | print("irq") 69 | 70 | sm.irq(turn) 71 | sm.active(1) 72 | sm.put(2216789025) #1000 0100 0010 0001 1000 0100 0010 0001 73 | #1000 0100 0010 0001 1000 0100 1000 0100 74 | #1000 0100 0010 0001 1000 0100 1000 0100 75 | sm.put(1) 76 | 77 | sleep(50) 78 | print("done") 79 | sm.active(0) 80 | sm.exec("set(pins,0)") 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /pio-steppers/test_motor4.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from rp2 import PIO, StateMachine, asm_pio 3 | from time import sleep 4 | import sys 5 | 6 | @asm_pio(set_init=(PIO.OUT_LOW,) * 4, 7 | out_init=(PIO.OUT_LOW,) * 4, 8 | out_shiftdir=PIO.SHIFT_RIGHT, 9 | in_shiftdir=PIO.SHIFT_LEFT) 10 | def prog(): 11 | pull() 12 | mov(x, osr) # num steps 13 | 14 | pull() 15 | mov(y, osr) # step pattern 16 | 17 | jmp(not_x, "end") 18 | 19 | label("loop") 20 | jmp(not_osre, "step") # loop pattern if exhausted 21 | mov(osr, y) 22 | 23 | label("step") 24 | out(pins, 4) [31] 25 | 26 | jmp(x_dec,"loop") 27 | label("end") 28 | 29 | irq(rel(0)) 30 | 31 | 32 | sm = StateMachine(0, prog, freq=10000, set_base=Pin(2), out_base=Pin(2)) 33 | data = [(1,2,4,8),(2,4,8,1),(4,8,1,2),(8,1,2,4)] 34 | steps = 0 35 | 36 | def turn(sm): 37 | global steps 38 | global data 39 | 40 | idx = steps % 4 41 | a = data[idx][0] | (data[idx][1] << 4) | (data[idx][2] << 8) | (data[idx][3] << 12) 42 | a = a << 16 | a 43 | 44 | #print("{0:b}".format(a)) 45 | sleep(1) 46 | 47 | sm.put(500) 48 | sm.put(a) 49 | 50 | steps += 500 51 | 52 | sm.irq(turn) 53 | sm.active(1) 54 | turn(sm) 55 | 56 | sleep(50) 57 | print("done") 58 | sm.active(0) 59 | sm.exec("set(pins,0)") 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /pwm-servo/servo.py: -------------------------------------------------------------------------------- 1 | import time 2 | from machine import Pin, PWM 3 | 4 | MIN_DUTY = 1000 # 5 percent of 65025 = 3251.25 5 | MAX_DUTY = 9000 # 10 percent of 65025 = 6502.5 6 | 7 | pwm = PWM(Pin(0)) 8 | pwm.freq(50) 9 | 10 | duty = MIN_DUTY 11 | direction = 1 12 | 13 | while True: 14 | for _ in range(1024): 15 | duty += direction 16 | if duty > MAX_DUTY: 17 | duty = MAX_DUTY 18 | direction = -direction 19 | elif duty < MIN_DUTY: 20 | duty= MIN_DUTY 21 | direction = -direction 22 | pwm.duty_u16(duty) -------------------------------------------------------------------------------- /ssd1306-oled-i2c/demo.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C 2 | from ssd1306 import SSD1306_I2C 3 | 4 | w = 128 5 | h = 32 6 | 7 | i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=200000) 8 | addr = i2c.scan()[0] 9 | oled = SSD1306_I2C(w, h, i2c, addr) 10 | 11 | # Add some text 12 | oled.fill(0) 13 | oled.text("Raspberry Pi ", 5, 5) 14 | oled.text("Pico ssd1306", 5, 15) 15 | oled.show() 16 | 17 | 18 | -------------------------------------------------------------------------------- /ssd1306-oled-i2c/demo2.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C, ADC 2 | from ssd1306 import SSD1306_I2C 3 | 4 | w = 128 5 | h = 32 6 | 7 | i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=200000) 8 | addr = i2c.scan()[0] 9 | oled = SSD1306_I2C(w, h, i2c, addr) 10 | 11 | adcX = ADC(1) 12 | adcY = ADC(2) 13 | 14 | while True: 15 | valX = adcX.read_u16() 16 | valY = adcY.read_u16() 17 | 18 | x = (5 + (valX/65535) * (w-10)); 19 | y = (5 + (valY/65535) * (h-10)); 20 | 21 | oled.fill(0) 22 | oled.text("*", int(x), int(y)) 23 | oled.show() 24 | 25 | 26 | --------------------------------------------------------------------------------