forked from dotnet/iot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart-demo.ino
117 lines (101 loc) · 2.86 KB
/
uart-demo.ino
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// COMMANDS:
// DIR - swap direction
// SPIN - start/stop spinning
// COL RRGGBB - set color to RRGGBB where RRGGBB is a hex number representing a color (i.e. COL FF0000 will set color to red)
// RATE N - set rate of spinning (N is delay between "moving" the light), default is 100.
// Low values might effectively have higher delay than expected (there is a delay related to reading from serial port)
//
// NOTE: incorrect numbers will get converted into 0 which will cause the light to turn off
#include <Adafruit_CircuitPlayground.h>
#include <errno.h>
#define NO_LIGHTS 10
#define serport Serial1
int dir = -1;
int color = 0x0000FF;
int spin_rate = 100;
bool spin = true;
int pixel1;
int pixel2;
// dir is +1 or -1
// adding number of lights so that modulo works correctly
// (negative numbers have different modulo rules in C++ than in math)
#define SPIN_PIXEL_ONCE(pix) (pix = (pix + dir + NO_LIGHTS) % NO_LIGHTS)
void setup() {
CircuitPlayground.begin();
serport.begin(9600);
CircuitPlayground.setBrightness(255);
// Can be any two pixels
pixel1 = 0;
pixel2 = 5;
}
// this should be called in a loop
// when there is data available on serial port it will read it and process, specifically
// when line of text is read it will call serial_on_line_read with a line as an argument
void serial_process() {
static const int len = 101;
static char serial_recv_buff[len];
static char* curr = serial_recv_buff;
static char* end = serial_recv_buff + len;
while (serport.available() > 0) {
char c = serport.read();
if (c == '\n' || c == '\r') {
if (curr != serial_recv_buff) {
*curr = '\0';
String line = serial_recv_buff;
serial_on_line_read(line);
}
curr = serial_recv_buff;
}
else {
*curr++ = c;
if (curr == end) {
// overflow detected...
curr = serial_recv_buff;
}
}
}
}
int hex_to_num(const String& hex) {
char* end;
int ret = strtol(hex.c_str(), &end, 16);
if (errno != 0) {
errno = 0;
return 0;
}
return ret;
}
// called by serial_process when line is read over serial port
void serial_on_line_read(const String& line) {
if (line == "DIR") {
dir = -dir;
serport.println("OK");
}
else if (line == "SPIN") {
spin = !spin;
serport.println("OK");
}
else if (line.startsWith("COL ")) {
String hex = line.substring(4);
color = hex_to_num(hex);
serport.println("OK");
}
else if (line.startsWith("RATE ")) {
String rate = line.substring(5);
spin_rate = rate.toInt();
serport.println("OK");
}
else {
serport.println("ERROR");
}
}
void loop() {
serial_process();
CircuitPlayground.clearPixels();
CircuitPlayground.setPixelColor(pixel1, color);
CircuitPlayground.setPixelColor(pixel2, color);
if (spin) {
SPIN_PIXEL_ONCE(pixel1);
SPIN_PIXEL_ONCE(pixel2);
}
delay(spin_rate);
}