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