Skip to content

Commit 680ff2b

Browse files
committed
Issue: #22 Firmware para arduino
Subo el firmware de arduino que no subí en el anterior commit
1 parent 6611bf9 commit 680ff2b

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

MLC/arduino/Firmware/Firmware.ino

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
2+
#define DEBUG 1
3+
4+
#ifdef DEBUG
5+
#define LOG(x,y) Serial.print(x); Serial.println(y);
6+
#endif
7+
8+
// defines ahorran ROM... aunque nos sobra de eso XD -- Verificar que los const vayan a la rom!
9+
const uint8_t ANALOG_PRECISION_CMD = 0x01;
10+
const uint8_t ADD_ANALOG_INPUT_CMD = 0x02;
11+
const uint8_t ADD_ANALOG_OUTPUT_CMD = 0x03;
12+
const uint8_t SET_PIN_MODE_CMD = 0x04;
13+
const uint8_t SET_REPORT_MODE_CMD = 0x05;
14+
const uint8_t ACTUATE_CMD = 0xF0;
15+
16+
// Commands executor caller -- one vector position == one command
17+
void (*executor[255])(const char*);
18+
19+
void not_implemented(const char* data)
20+
{
21+
//nothing to do...
22+
return;
23+
}
24+
25+
typedef enum ReportModes {average, bulk, rt};
26+
27+
/** ---------------------------------------------------------- **/
28+
/** GLOBAL CONFIG **/
29+
30+
uint8_t REPORT_READ_COUNT = 0;
31+
uint8_t REPORT_READ_DELAY = 0;
32+
ReportModes REPORT_MODE = average;
33+
uint8_t INPUT_PORTS[129]; // Port count in first position
34+
35+
/** ---------------------------------------------------------- **/
36+
37+
const char* ACK = "\xFF\x00";
38+
39+
/**
40+
ANALOG_PRECISION: 0x01 0x01 [BITS]
41+
*/
42+
void set_analog_precision(const char* data)
43+
{
44+
int i = byte(data[2]);
45+
// Tal vez conviene separar estas funciones ya que hay boards con resoluciones distintas...
46+
// Igual, así funciona bien con el due (y con todos, ya que no hay problema en superar el máximo de la resolución)
47+
analogWriteResolution(i);
48+
analogReadResolution(i);
49+
50+
LOG("Resolution changed to: ", i);
51+
}
52+
53+
/**
54+
PIN_MODE: 0x04 0x02 [PIN] [MODE]
55+
*/
56+
void set_pin_mode(const char* data)
57+
{
58+
pinMode(data[2], data[3]);
59+
LOG("Changed pin mode on pin ", data[2]);
60+
LOG("Mode set to ", data[3]);
61+
}
62+
63+
/**
64+
REPORT_MODE: 0x05 0x03 [MODE] [READ_COUNT] [READ_DELAY]
65+
*/
66+
void set_report_mode(const char* data)
67+
{
68+
REPORT_MODE = (ReportModes)(data[2]);
69+
REPORT_READ_COUNT = byte(data[3]);
70+
REPORT_READ_DELAY = byte(data[4]);
71+
LOG("Report mode changed on port ", byte(data[3]));
72+
}
73+
74+
/**
75+
ANALOG_INPUT: 0x02 0x01 [PORT]
76+
*/
77+
void set_analog_input(const char* data)
78+
{
79+
INPUT_PORTS[0] += 1;
80+
INPUT_PORTS[INPUT_PORTS[0]] = byte(data[2]);
81+
LOG("New analog input: ", byte(data[2]));
82+
}
83+
84+
/**
85+
* ANALOG_OUTPUT: 0x03 0x01 [PORT]
86+
*/
87+
void set_analog_output(const char* data)
88+
{
89+
// No se si vale la pena guardar registro de pines de salida...
90+
}
91+
92+
/**
93+
* ACTUATE: 0xF0 [PIN_COUNT] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
94+
*/
95+
void actuate(const char* data)
96+
{
97+
int offset = 0;
98+
int byte_count = byte(data[1]); // Un byte puede llegar a limitar la cantidad de salidas... creo
99+
100+
// ACTUATION ZONE
101+
while (offset > byte_count)
102+
{
103+
//Se aplica la acción a cada puerto indicado
104+
int port = byte(data[2 + offset]);
105+
106+
//Detects an analog port
107+
if ( port >= A0 )
108+
{
109+
int value = (data[3 + offset] << 8) + data[4 + offset];
110+
analogWrite(port, value);
111+
offset += 3;
112+
113+
LOG("Analog pin written", port);
114+
} else
115+
{
116+
int value = data[3 + offset] > 0 ? HIGH : LOW; // Creo que da igual si pongo el entero directamente
117+
digitalWrite(port, value);
118+
offset += 2;
119+
120+
LOG("Digital pin written ", port);
121+
}
122+
}
123+
124+
delayMicroseconds(REPORT_READ_DELAY); // FIXME: Usamos variable de 8 bits cuando la precisión de esta función llega a 16 bits.
125+
126+
char response[130];
127+
response[0] = '\xF1';
128+
byte len = 1; // Inicia en 1 para evitar pisar el id de comando
129+
for (int i = 1; i <= byte(INPUT_PORTS[0]); i++)
130+
{
131+
if ( INPUT_PORTS[i] >= A0 )
132+
{
133+
int data = analogRead(INPUT_PORTS[i]);
134+
response[len + 1] = byte((data & 0xFF00) >> 8); // Se guarda el msb en el buffer
135+
response[len + 2] = byte(data & 0xFF); // Se guarda el lsb en el buffer
136+
137+
len += 2; // Cada lectura de un recurso analógico ocupa dos bytes. FIXME: se puede optimizar con bajas resoluciones
138+
LOG("Analog pin read: ", INPUT_PORTS[i]);
139+
} else
140+
{
141+
int data = digitalRead(INPUT_PORTS[i]);
142+
response[len + 1] = byte(data);
143+
144+
len += 1;
145+
LOG("Digital pin read: ", INPUT_PORTS[i]);
146+
}
147+
}
148+
149+
response[1] = len - 1;
150+
SerialUSB.write(response, len + 2); // 2 bytes extras por el id de comando y la longitud
151+
}
152+
153+
void setup() {
154+
SerialUSB.begin(115200);
155+
156+
#ifdef DEBUG
157+
Serial.begin(57600);
158+
#endif
159+
160+
for (int i = 0; i < 255; i++)
161+
{
162+
executor[i] = &not_implemented;
163+
}
164+
165+
INPUT_PORTS[0] = 0;
166+
167+
/** Commands Callbacks **/
168+
executor[ANALOG_PRECISION_CMD] = &set_analog_precision;
169+
executor[ADD_ANALOG_INPUT_CMD] = &set_analog_input;
170+
executor[ADD_ANALOG_OUTPUT_CMD] = &set_analog_output;
171+
executor[SET_PIN_MODE_CMD] = &set_pin_mode;
172+
executor[SET_REPORT_MODE_CMD] = &set_report_mode;
173+
executor[ACTUATE_CMD] = &actuate;
174+
175+
executor[ANALOG_PRECISION_CMD]("\x01\x01\x12");
176+
executor[ADD_ANALOG_INPUT_CMD]("\x02\x01\x37"); // Configura a A1 como lectura
177+
executor[ADD_ANALOG_INPUT_CMD]("\x02\x01\x38"); // Configura a A2 como lectura
178+
executor[SET_PIN_MODE_CMD]("\x04\x02\x12\x01");
179+
executor[SET_PIN_MODE_CMD]("\x04\x02\x55\x00");
180+
181+
}
182+
183+
void loop() {
184+
LOG("Escribiendo...", " ");
185+
executor[ACTUATE_CMD]("\xF0\x01\x12\x01");
186+
187+
if (SerialUSB.available() > 0)
188+
{
189+
char input[64]; // Esto se reserva en el stack, tal vez hacerlo global consume menos recursos...
190+
191+
while (SerialUSB.available() > 0)
192+
{
193+
SerialUSB.readBytes(input, SerialUSB.available());
194+
}
195+
196+
executor[input[0]](input); // Does the callback for the command
197+
}
198+
199+
delay(5000);
200+
}

0 commit comments

Comments
 (0)