Diseño robusto de aplicaciones Arduino




Unidad

by Sebastián Tabares Amaya
Debugging
Validación
Plugins
Tiempo Real
Sentencias de ATMEL directas
Arduino Due
Arduino M0
Tiva C
ST Nucleo
Herramientas externas
...
Arduino solo es hardware o una plataforma?

Vscode, Átom, ...
Los dos IDEs muy buenos para reemplazar el IDE de Arduino, ambos libres (vscode OSS).
Mi preferencia es VScode por la integracion con Git, herramientas de autocompletado, etc.




...


Extenciones útiles:
- Booksmarks
- C/C++
- Cortex-Debug
- PlatformIO
- Rust (siguiente gran paso del IoT con Arduino)
- Arduino Snippets
- GIT
- ...

Multi-
plata-
forma.
Compiling .pioenvs/tiva/FrameworkEnergia/wiring_pulse.c.o
Compiling .pioenvs/tiva/FrameworkEnergia/wiring_shift.c.o
Archiving .pioenvs/tiva/libFrameworkEnergia.a
Indexing .pioenvs/tiva/libFrameworkEnergia.a
Linking .pioenvs/tiva/firmware.elf
Checking size .pioenvs/tiva/firmware.elf
Building .pioenvs/tiva/firmware.bin
Memory Usage -> http://bit.ly/pio-memory-usage
DATA: [= ] 13.1% (used 4288 bytes from 32768 bytes)
PROGRAM: [==== ] 42.1% (used 110448 bytes from 262144 bytes)
============================ [SUCCESS] Took 15.59 seconds ============================
====================================== [SUMMARY] ======================================
Environment mega [SKIP]
Environment nano [SKIP]
Environment tiva [SUCCESS]
============================ [SUCCESS] Took 15.59 seconds ============================
[platformio]
env_default = tiva
[common_env_data]
lib_deps =
AsharaStudios/GuruxDLMS.c
build_flags =
-g3
-ggdb
-DDEBUG_MSG
; -DSERIAL_MODE
; -DGX_DLMS_MICROCONTROLLER
[env:mega]
platform = atmelavr
board = megaatmega1280
framework = arduino
lib_deps =
${common_env_data.lib_deps}
build_flags =
${common_env_data.build_flags}
-DMEGAboard[env:nano]
board = nanoatmega328
platform = atmelavr
framework = arduino
lib_deps =
${common_env_data.lib_deps}
build_flags =
${common_env_data.build_flags}
-DNANOboard
[env:tiva]
platform = titiva
board = lptm4c1230c3pm
framework = energia
lib_deps =
${common_env_data.lib_deps}
AsharaStudios/DateTime_Library
build_flags =
${common_env_data.build_flags}
-DTIVAboard
extra_scripts =
post:.prepareDebug.py

Validación y autocompletado




Debugging

OpenOCD, ST-Link, J-Link, Atmel ICE, JTAG, ...

Ejemplo aplicación en Tiempo Real Arduino
pero con:


Attiny85
Attiny861A
PicoPower®


Se trata de que mediante "superposición" de señales cuadradas generar una señal PWM que se transformará en una señal sinusoidal con filtros.



Inversor (DC a AC)

Un poco de Código...

#include <Arduino.h>
#include <avr/interrupt.h>
#include "lookup_tables.h"
#ifdef ATTINYx5
#define SD PIN_B4 //TODO: support for shutdown
#define H1 PIN_B0
#define L1 PIN_B1
#define H2 PIN_B3
#define L2 PIN_B4
#elif ATTINYX61
#define POT1 A5 //debug pins
#define SEL1 A6 //debug pins
#define SD PIN_B4 //TODO: support for shutdown
#define H1 PIN_B0
#define L1 PIN_B1
#define H2 PIN_B2
#define L2 PIN_B3
#endif
//#define DEADRISING 5
//#define DEADFALLING 5
volatile uint8_t pwmValue1 = 0;
volatile uint8_t pwmValue2 = 0;
volatile uint8_t index = 0;
#define MAX_COUNTER 1
uint16_t counter = 0;
/* UPDATE PWM
// f_wave := f_PCK / (prescaler * (OCR1C+1) * ARRAY_LEN * (MAX_COUNTER+1)) ~= 60.24Hz
// f_PCK := 32Mhz
// prescaler := 8
// OCR1C := 199
// ARRAY_LEN := 166
// MAX_COUNTER := 1
*/
ISR(TIMER1_OVF_vect) {
if (counter++ >= MAX_COUNTER){
counter = 0;
index++;
index %= ARRAY_LEN;
OCR1A = pwmValue1;
OCR1B = pwmValue2;
}
}
void setup() {
#ifdef ATTINYX61
pinMode(POT1, INPUT);
pinMode(SEL1, INPUT);
#endif
pinMode(SD, OUTPUT);
pinMode(H1, OUTPUT); // OC1A
pinMode(L1, OUTPUT); // not OC1A
pinMode(H2, OUTPUT); // OC1B
pinMode(L2, OUTPUT);
digitalWrite(SD,LOW); // IR2112 active
SREG = _BV(7); // Global interruption enabled
/*timer1 conf*/
PLLCSR = _BV(LSM) | _BV(PLLE); //activates Low Speed Mode in PCK and enables it.
delay(1);
while(!(PLLCSR & _BV(PLOCK))); //wait until PLL is in steady state.
PLLCSR |= _BV(PCKE); //enable PCK source for timer1 (asynchronous mode).
//PWM freq = 20khz, page 88 in datasheet (PCK = 32Mhz)
TIMSK = _BV(TOIE1); // interrupt enable when TCNT1 overflows (TCNT1 == OCR1A).
OCR1C = 199; // top value for TCNT1 for PWM freq = 20khz, R = 7.6
OCR1A = 100; // initial value of comparation
#ifdef ATTINYx5
TCCR1 = _BV(PWM1A) | _BV(COM1A0) | _BV(CS12); //activates complementary mode in A and 1:8 prescaler
GTCCR = _BV(PWM1B) | _BV(COM1B0);
//DT1A = (0xF0 & (DEADRISING << 4)) | (0x0F & DEADFALLING);
#elif ATTINYX61
TCCR1A = _BV(PWM1A) | _BV(PWM1B) | _BV(COM1A0) | _BV(COM1B0); //activates PMW complementary mode in A and B
TCCR1B = _BV(CS11) | _BV(CS10); //1:4 prescaler
//DT1 = (0xF0 & (DEADRISING << 4)) | (0x0F & DEADFALLING);
#endif
//DTPS1 = _BV(DTPS10); //prescaler 1:1
}
uint16_t tmp = 0;
void loop() {
Serial.println(tmp);
#ifdef ATTINYX61
tmp = analogRead(SEL1);
if (tmp <= 512) {
pwmValue1 = analogRead(POT1) >> 2;
pwmValue2 = ~pwmValue1;
} else {
#endif
pwmValue1 = pgm_read_byte(&(D[index]));
//WARNING: if 0 > 255 use other index or index type
pwmValue2 = pgm_read_byte(&(D[(index+PHASE180)%ARRAY_LEN]));
#ifdef ATTINYX61
}
#endif
}
main.cpp
#ifndef LOOKUP_TABLES_H
#define LOOKUP_TABLES_H
#include <Arduino.h>
/*
Document for value calculus:
https://docs.google.com/spreadsheets/d/1UtXzdGsx8a0OHYvLXqKkCJ48qxz2pVwkHPIFW54Rmx0/edit?usp=sharing
*/
#define ARRAY_LEN 166
#if ARRAY_LEN%2 != 0
error("ARRAY_LEN must be divisible in 2")
#endif
#define PHASE180 ARRAY_LEN/2
#if ARRAY_LEN+PHASE180 > 255
error("define other index for second PWM and remove this error")
#endif
// D(t) = (1 + sin(2*pi*60*t)) / 2
static const uint8_t D[ARRAY_LEN] PROGMEM = {
128,
132,
137,
142,
147,
151,
156,
161,
166,
170,
175,
179,
183,
188,
192,
196,
200,
204,
208,
211,
215,
219,
222,
225,
228,
231,
234,
236,
239,
241,
243,
245,
247,
248,
250,
251,
252,
253,
254,
254,
255,
255,
255,
255,
254,
254,
253,
252,
251,
250,
248,
247,
245,
243,
241,
239,
236,
234,
231,
228,
225,
222,
219,
215,
211,
208,
204,
200,
196,
192,
188,
183,
179,
175,
170,
166,
161,
156,
151,
147,
142,
137,
132,
128,
123,
118,
113,
108,
104,
99,
94,
89,
85,
80,
76,
72,
67,
63,
59,
55,
51,
47,
44,
40,
36,
33,
30,
27,
24,
21,
19,
16,
14,
12,
10,
8,
7,
5,
4,
3,
2,
1,
1,
0,
0,
0,
0,
1,
1,
2,
3,
4,
5,
7,
8,
10,
12,
14,
16,
19,
21,
24,
27,
30,
33,
36,
40,
44,
47,
51,
55,
59,
63,
67,
72,
76,
80,
85,
89,
94,
99,
104,
108,
113,
118,
123
};
#endif
lookup_tables.h
Gracias
Sebastian Y. Tabares Amaya






Diseño robusto para aplicaciones de Arduino
By Sebastian Yesid Tabares Amaya
Diseño robusto para aplicaciones de Arduino
En esta presentacion se explica ciertas herramientas orientadas a hacer el diseño de aplicaciones en Arduino más robusta. Test, tipado extricto, debugging y tiempo real usando herramientas del ecosistema para crear soluciones mejor probadas y elaboradas
- 1,744