Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding arduino uno serial support #300

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,15 @@ Temporary Items
.apdisk
*.pyc
*.pdf

# VirtualEnv
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json
54 changes: 54 additions & 0 deletions arduino/arduino_uno_serial/arduino_uno_serial.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <Arduino.h>
//#include <ESP8266WiFi.h>
//#include <WiFiUdp.h>
#include <NeoPixelBus.h>

// Set to the number of LEDs in your LED strip
#define NUM_LEDS 240
// Maximum number of packets to hold in the buffer. Don't change this.
#define BUFFER_LEN 64
// Toggles FPS output (1 = print FPS over serial, 0 = disable output)
#define PRINT_FPS 1

//NeoPixelBus settings
const uint8_t PixelPin = 7; // make sure to set this to the correct pin, ignored for Esp8266(set to 3 by default for DMA)

char packetBuffer[BUFFER_LEN];

// LED strip
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> ledstrip(NUM_LEDS, PixelPin);


void setup() {
Serial.begin(115200);
ledstrip.Begin();//Begin output
ledstrip.Show();//Clear the strip for use
}

uint8_t N = 0;
#if PRINT_FPS
uint16_t fpsCounter = 0;
uint32_t secondTimer = 0;
#endif

void loop() {
int bytes_read = 0;

while(bytes_read < BUFFER_LEN) {
if (Serial.available() > 0) {
packetBuffer[bytes_read] = Serial.read();
bytes_read++;
}
}
bytes_read = 0;


for (int i = 0; i < BUFFER_LEN; i+=4) {
packetBuffer[BUFFER_LEN] = 0;
N = packetBuffer[i];
RgbColor pixel((uint8_t)packetBuffer[i+1], (uint8_t)packetBuffer[i+2], (uint8_t)packetBuffer[i+3]);
ledstrip.SetPixelColor(N, pixel);
}

ledstrip.Show();
}
5 changes: 3 additions & 2 deletions python/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
'blinkstick' means that a BlinkstickPro is connected to this PC which will be used
to control the leds connected to it.
"""

if DEVICE == 'esp8266':
UDP_IP = '192.168.0.150'
"""IP address of the ESP8266. Must match IP in ws2812_controller.ino"""
UDP_PORT = 7777
"""Port number used for socket communication between Python and ESP8266"""
SOFTWARE_GAMMA_CORRECTION = False
"""Set to False because the firmware handles gamma correction + dither"""

if DEVICE == 'arduino_serial':
SOFTWARE_GAMMA_CORRECTION = False
"""Set to False because the firmware handles gamma correction + dither"""
if DEVICE == 'pi':
LED_PIN = 18
"""GPIO pin connected to the LED strip pixels (must support PWM)"""
Expand Down
54 changes: 54 additions & 0 deletions python/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
if config.DEVICE == 'esp8266':
import socket
_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
elif config.DEVICE == 'arduino_serial':
import serial
_serial = serial.Serial('COM5', baudrate=115200)
# _serial = serial.Serial('COM5', baudrate=9600)

# Raspberry Pi controls the LED strip directly
elif config.DEVICE == 'pi':
import neopixel
Expand Down Expand Up @@ -42,6 +47,53 @@ def signal_handler(signal, frame):

_is_python_2 = int(platform.python_version_tuple()[0]) == 2

def _update_arduino_serial():
"""Sends UDP packets to ESP8266 to update LED strip values

The ESP8266 will receive and decode the packets to determine what values
to display on the LED strip. The communication protocol supports LED strips
with a maximum of 256 LEDs.

The packet encoding scheme is:
|i|r|g|b|
where
i (0 to 255): Index of LED to change (zero-based)
r (0 to 255): Red value of LED
g (0 to 255): Green value of LED
b (0 to 255): Blue value of LED
"""
global pixels, _prev_pixels
# Truncate values and cast to integer
pixels = np.clip(pixels, 0, 255).astype(int)
# Optionally apply gamma correc tio
p = _gamma[pixels] if config.SOFTWARE_GAMMA_CORRECTION else np.copy(pixels)
MAX_PIXELS_PER_PACKET = 126
# Pixel indices
idx = range(pixels.shape[1])
idx = [i for i in idx if not np.array_equal(p[:, i], _prev_pixels[:, i])]
n_packets = len(idx) // MAX_PIXELS_PER_PACKET + 1
idx = np.array_split(idx, n_packets)
for packet_indices in idx:
m = '' if _is_python_2 else []
for i in packet_indices:
if _is_python_2:
m += chr(i) + chr(p[0][i]) + chr(p[1][i]) + chr(p[2][i])
else:
m.append(i) # Index of pixel to change
m.append(p[0][i]) # Pixel red value
m.append(p[1][i]) # Pixel green value
m.append(p[2][i]) # Pixel blue value
# print(m)
# msg = m if _is_python_2 else bytes(m)
# _serial.write(m)

# print(m)
m = m if _is_python_2 else bytes(m)
# print(len(m))
# _sock.sendto(m, (config.UDP_IP, config.UDP_PORT))
_serial.write(m)
_prev_pixels = np.copy(p)

def _update_esp8266():
"""Sends UDP packets to ESP8266 to update LED strip values

Expand Down Expand Up @@ -140,6 +192,8 @@ def update():
"""Updates the LED strip values"""
if config.DEVICE == 'esp8266':
_update_esp8266()
elif config.DEVICE == 'arduino_serial':
_update_arduino_serial()
elif config.DEVICE == 'pi':
_update_pi()
elif config.DEVICE == 'blinkstick':
Expand Down