TODOPIC

Otros Microcontroladores / Dispositivos programables => Arduino => Mensaje iniciado por: Picuino en 16 de Mayo de 2016, 13:18:24

Título: Arduino + placa de control PC42 con juego simón
Publicado por: Picuino en 16 de Mayo de 2016, 13:18:24
Hola a todos.
Por fín tengo un pequeño vídeo de la placa de control para Arduino que he desarrollado.
En este caso está ejecutando el juego Simón


Mi intención es venderla por e-bay este verano, cuando consiga tiempo para atar los detalles que aún faltan.

(http://www.picuino.com/_static/img-0086-g.jpg)

Un saludo.
Título: Re:Arduino + placa de control PC42 con juego simón
Publicado por: Picuino en 16 de Mayo de 2016, 13:20:02
Adjunto el programa del juegoSimón.

Código: C
  1. /***************************************************************************
  2.    JUEGO SIMON
  3.  ***************************************************************************/
  4. #include <Wire.h>
  5. #include <PC42.h>
  6.  
  7. /***************************************************************************
  8.    DEFINICIÓN DE DATOS Y CONSTANTES
  9.  ***************************************************************************/
  10.  
  11. // Tones
  12. #define TONE_R    Re_4    // 311.1 Hz  Rojo
  13. #define TONE_Y    Si3     // 246.9 Hz  Amarillo
  14. #define TONE_G    Fa_4    // 370.0 Hz  Verde
  15. #define TONE_B    Fa_3    // 185.0 Hz  Azul
  16. #define TONE_ERR  Si1     // 59 Hz Simón original
  17.  
  18. #define TIME_BETWEEN_SEQUENCES 1060
  19. #define TIME_ERROR_TONE        2540
  20.  
  21. #define SIMON_LEN_MAX 20
  22. typedef struct {
  23.    char data[SIMON_LEN_MAX];
  24.    char len;
  25.    char pos;
  26.    char state;
  27.    char sound;
  28. } simon_t;
  29.  
  30. enum {
  31.   INIT, WAIT_RUN, INIT_RUN, ADD_SEQUENCE,
  32.   PLAY_SEQUENCE, TEST_SEQUENCE,
  33.   RIGHT_SEQUENCE, ERROR_IN_SEQUENCE,
  34.   WIN_GAME, WAIT_INIT,
  35. };
  36.  
  37. simon_t simon;
  38.  
  39.  
  40. /***************************************************************************
  41.    SETUP Y BUCLE PRINCIPAL
  42.  ***************************************************************************/
  43. void setup() {
  44.   pc.begin();
  45.   simon.state = INIT;
  46. }
  47.  
  48. void loop() {
  49.  
  50.   switch(simon.state) {
  51.  
  52.   case INIT:   // Init System
  53.     pc.ledWrite(5, HIGH);
  54.     simon.state = WAIT_RUN;
  55.     break;
  56.  
  57.   case WAIT_RUN:  // Wait Run
  58.     if (pc.keyCount(KEY_ENTER))
  59.       simon.state = INIT_RUN;
  60.     break;
  61.  
  62.   case INIT_RUN:  // Init Run
  63.     simon_init();
  64.     pc.ledWrite(5, LOW);
  65.     randomSeed(millis());
  66.     simon.state = ADD_SEQUENCE;
  67.     break;
  68.    
  69.   case ADD_SEQUENCE:  // Add Sequence
  70.     simon.data[simon.len] = random(1, 4+1);
  71.     simon.len++;
  72.     simon.state = PLAY_SEQUENCE;
  73.     break;
  74.    
  75.   case PLAY_SEQUENCE:  // Play Sequence
  76.     pc.dispNum(simon.len);
  77.     delay(TIME_BETWEEN_SEQUENCES);
  78.     simon_play();
  79.     simon.state = TEST_SEQUENCE;
  80.     break;
  81.    
  82.   case TEST_SEQUENCE:  // Test Sequence
  83.     if (simon_test() == 1)
  84.       simon.state = RIGHT_SEQUENCE;
  85.     else
  86.       simon.state = ERROR_IN_SEQUENCE;
  87.     break;
  88.    
  89.   case RIGHT_SEQUENCE:  // Right Sequence
  90.     if (simon.len >= SIMON_LEN_MAX)
  91.       simon.state = WIN_GAME;
  92.     else
  93.       simon.state = ADD_SEQUENCE;
  94.     break;
  95.    
  96.   case ERROR_IN_SEQUENCE:  // Error in Sequence
  97.       simon_error();
  98.       simon.len = 0;
  99.       simon.state = INIT;
  100.     break;
  101.  
  102.   case WIN_GAME:  // Win Game
  103.     pc.dispWrite(DD_G, DD_A, DD_n, DD_A);
  104.     pc.ledBlink(5, 100, 400);
  105.     simon.state = WAIT_INIT;
  106.     break;
  107.    
  108.   case WAIT_INIT:  // Wait Init
  109.     if (pc.keyCount(KEY_ENTER)) {
  110.       pc.dispBegin();
  111.       pc.ledBegin();
  112.       simon.state = INIT;
  113.     }
  114.     break;
  115.  
  116.   default:
  117.     simon.state = 0;
  118.   }
  119.    
  120. };
  121.  
  122.  
  123. /***************************************************************************
  124.    FUNCIONES
  125.  ***************************************************************************/
  126.  
  127. //
  128. // Inicializar datos de Simón
  129. //
  130. void simon_init(void) {
  131.    uint8_t i;
  132.    for(i=sizeof(simon.data); --i;) {
  133.       simon.data[i] = 0;
  134.    }
  135.    simon.len = 0;
  136.    simon.pos = 0;
  137.    simon.sound = 1;  
  138. }
  139.  
  140.  
  141. //
  142. // Visualizar la secuencia de colores y tonos
  143. //
  144. void simon_play(void) {
  145.   int i;
  146.   for(i=0; i<simon.len; i++) {
  147.      simon_color(simon.data[i]);
  148.   }
  149. }
  150.  
  151.  
  152. //
  153. //  Comprueba si el jugador repite toda la secuencia
  154. //
  155. char simon_test(void) {
  156.   int i;
  157.   char color, key;
  158.  
  159.   i = 0;
  160.   while(1) {
  161.     if (i >= simon.len)
  162.       return 1;  
  163.     color = simon.data[i];
  164.    
  165.     key = key_num();
  166.     if (key == 0)
  167.       continue;
  168.    
  169.     if (key == color) {
  170.       simon_color(color);
  171.       i = i + 1;
  172.     }
  173.     else {
  174.       return 0;
  175.     }
  176.   }
  177. }
  178.  
  179.  
  180. //
  181. // Devuelve el número de tecla pulsado
  182. //
  183. char key_num(void) {
  184.   char keys = pc.keyPressed(0);
  185.   if (keys & (1<<0)) return 1;
  186.   if (keys & (1<<1)) return 2;
  187.   if (keys & (1<<2)) return 3;
  188.   if (keys & (1<<3)) return 4;
  189.   if (keys & (1<<4)) return 5;
  190.   if (keys & (1<<5)) return 6;
  191. }
  192.  
  193.  
  194. //
  195. // Enciende un led y suena un tono
  196. // durante un tiempo determinado
  197. //
  198. void simon_color(char color) {
  199.   char numtone;
  200.   int i;
  201.  
  202.   if (color < 1 || color > 4) return;
  203.   if (simon.sound) {
  204.     switch(color) {
  205.     case 1: numtone = TONE_R;  break;
  206.     case 2: numtone = TONE_Y;  break;
  207.     case 3: numtone = TONE_G;  break;
  208.     case 4: numtone = TONE_B;  break;
  209.     }
  210.   }
  211.   pc.ledWrite(color, HIGH);
  212.   pc.buzzTone(numtone);
  213.   delay(simon_time_tone(simon.len));
  214.   pc.buzzTone(0);
  215.   pc.ledWrite(color, LOW);
  216.   delay(simon_time_silence(simon.len));
  217. }
  218.  
  219. //
  220. // Enciende la señal de error
  221. //
  222. void simon_error(void) {
  223.   if (simon.sound)
  224.     pc.buzzTone(TONE_ERR);
  225.   pc.ledWrite(6, HIGH);
  226.   pc.ledWrite(8, HIGH);
  227.   delay(TIME_ERROR_TONE);
  228.   pc.buzzTone(0);
  229.   pc.ledWrite(6, LOW);
  230.   pc.ledWrite(8, LOW);
  231.   delay(100);
  232. }
  233.  
  234. //
  235. // Devuelve el tiempo que dura un tono dependiendo de
  236. // la longitud de la secuencia de colores
  237. //
  238. int simon_time_tone(char len) {
  239.    if (len <= 1) return 660;
  240.    if (len <= 5) return 475;
  241.    if (len <= 9) return 380;
  242.    if (len <=13) return 317;
  243.    return 272;
  244. }
  245.  
  246. //
  247. // Devuelve el tiempo que dura una pausa entre tonos dependiendo de
  248. // la longitud de la secuencia de colores
  249. //
  250. int simon_time_silence(char len) {
  251.    if (len <= 1) return 132;
  252.    if (len <= 5) return 93;
  253.    if (len <= 9) return 75;
  254.    if (len <=13) return 63;
  255.    return 54;
  256. }
Título: Arduino + placa de control PC42. Temporizador
Publicado por: Picuino en 16 de Mayo de 2016, 15:30:47
En este caso, un video de la placa funcionando como temporizador con cuenta atrás.


En el video puede verse como cuenta hacia atrás y avisa del final de la cuenta.
Con dos pulsadores puede ajustarse el tiempo de cuenta.
Otro pulsador permite memorizar en EEPROM el comienzo de la cuenta atrás.
La cuenta atrás se puede pausar y editar.
Por supuesto, un pin de Arduino se activa durante la cuenta atrás para poder encender una insoladora (es la aplicación para la que he utilizado este programa) o cualquier otro aparato.

El programa de control para Arduino es:
Código: C
  1. /***************************************************************************
  2.    TEMPORIZADOR
  3.  ***************************************************************************/
  4. #include <Wire.h>
  5. #include <PC42.h>
  6. #include <EEPROM.h>
  7.  
  8. #define TONE_ERR     Si1         // 59 Hz Simón original
  9. #define TONE_ALARM   Do6
  10. #define MAX_SECONDS  9999
  11. #define EEPROM_ADDR_SECONDS  4
  12.  
  13. /***************************************************************************
  14.    DATOS GLOBALES
  15.  ***************************************************************************/
  16. typedef struct {
  17.    int total_time;
  18.    int countdown;
  19.    int count_millis;
  20.    long millis;
  21.    long millis_old;
  22.    struct {
  23.      unsigned state:3;
  24.      unsigned alarm:3;
  25.    };
  26. } tempo_t;
  27.  
  28. tempo_t tempo;
  29.  
  30. enum {INIT_STOP, STOP, INIT_COUNTDOWN, COUNTDOWN, INIT_ALARM, ALARM};
  31. enum {OFF, ON };
  32.  
  33.  
  34. /***************************************************************************
  35.    SETUP Y BUCLE PRINCIPAL
  36.  ***************************************************************************/
  37.  
  38. void setup() {
  39.   pc.begin();
  40.   tempo_init();
  41. }
  42.  
  43.  
  44. void loop() {
  45.  
  46.   // Dispatcher
  47.   switch(tempo.state) {
  48.  
  49.   case INIT_STOP:  
  50.     pc.ledBegin();
  51.     pc.ledWrite(1, HIGH);
  52.     power_off();
  53.     tempo.state = STOP;
  54.     break;
  55.  
  56.   case STOP:
  57.     pc.dispNum(tempo.countdown);
  58.     tempo_stop();
  59.     break;
  60.  
  61.   case INIT_COUNTDOWN:
  62.     if (tempo.countdown > 0) {
  63.       pc.ledBegin();
  64.       pc.ledWrite(4, HIGH);
  65.       tempo.millis_old = millis();
  66.       tempo.state = COUNTDOWN;
  67.     }
  68.     else {
  69.       tempo.state = INIT_STOP;
  70.     }
  71.     break;
  72.  
  73.   case COUNTDOWN:  
  74.     tempo_countdown();
  75.     break;
  76.  
  77.   case INIT_ALARM:
  78.     power_off();  
  79.     pc.ledBegin();
  80.     pc.ledWrite(3, HIGH);
  81.     tempo.millis = millis();
  82.     tempo.alarm = 0;
  83.     tempo.state = ALARM;
  84.     break;
  85.  
  86.   case ALARM:
  87.     alarm();
  88.     break;
  89.    
  90.   default:
  91.      tempo.state = INIT_STOP;
  92.   }
  93. }
  94.  
  95.  
  96. /***************************************************************************
  97.    FUNCIONES
  98.  ***************************************************************************/
  99.  
  100. //
  101. // STOP
  102. //
  103. void tempo_stop(void) {
  104.   char keys;
  105.   pc.dispDots(0);
  106.  
  107.   keys = pc.keyCount(KEY_DOWN);
  108.   tempo.countdown -= keys;
  109.   if (tempo.countdown < 0)
  110.     tempo.countdown += MAX_SECONDS + 1;
  111.  
  112.   keys = pc.keyCount(KEY_UP);
  113.   tempo.countdown += keys;
  114.   if (tempo.countdown > MAX_SECONDS)
  115.     tempo.countdown -= MAX_SECONDS + 1;
  116.  
  117.   if (pc.keyPressed(KEY_UP) && pc.keyPressed(KEY_DOWN)) {
  118.      tempo.countdown = tempo.total_time;
  119.      tempo.count_millis = 0;
  120.   }
  121.    
  122.   if (pc.keyEvents(KEY_RIGHT, KEY_PRESSED_TIME2)) {
  123.     tempo.total_time = tempo.countdown;
  124.     pc.dispWrite(0,0,0,0);
  125.     eeprom_write16(EEPROM_ADDR_SECONDS, tempo.total_time);
  126.     delay(100);
  127.   }
  128.  
  129.   if (pc.keyEvents(KEY_ENTER, KEY_PRESSED_TIME1)) {
  130.     tempo.state = INIT_COUNTDOWN;
  131.   }
  132.  
  133.   pc.dispNum(tempo.countdown);
  134. }
  135.  
  136.  
  137. //
  138. // COUNTDOWN
  139. //
  140. void tempo_countdown(void) {
  141.  
  142.   // Activar la salida de potencia
  143.   power_on();
  144.  
  145.   // Actualizar la cuenta atrás
  146.   tempo.millis = millis();
  147.   tempo.count_millis += tempo.millis - tempo.millis_old;
  148.   tempo.millis_old = tempo.millis;
  149.  
  150.   while (tempo.count_millis >= 1000) {
  151.     tempo.countdown--;
  152.     pc.dispNum(tempo.countdown);
  153.     tempo.count_millis -= 1000;
  154.     if (tempo.countdown == 0) break;
  155.   }
  156.  
  157.   if (tempo.count_millis < 500)
  158.     pc.dispDots(0);
  159.   else
  160.     pc.dispDots(1);
  161.  
  162.   if (tempo.countdown == 0) {
  163.     power_off();
  164.     tempo.state = INIT_ALARM;
  165.   }
  166.  
  167.   if (pc.keyEvents(KEY_ENTER, KEY_PRESSED_TIME1)) {
  168.     tempo.state = INIT_STOP;
  169.   }  
  170. }
  171.  
  172.  
  173. //
  174. // ALARM
  175. //
  176. void alarm(void) {
  177.   pc.dispWrite(DD_E, DD_n, DD_d, DD_SP);
  178.  
  179.   switch(tempo.alarm) {
  180.   case 0:
  181.     alarm_sound();
  182.     tempo.alarm = 1;
  183.     break;
  184.   case 1:
  185.     if (millis() > tempo.millis + 1000) {
  186.       alarm_sound();
  187.       tempo.millis += 1000;
  188.       tempo.alarm = 2;
  189.     }
  190.     break;
  191.   case 2:
  192.     if (millis() > tempo.millis + 4000) {
  193.       tempo.millis += 4000;
  194.       pc.buzzPlay(TONE_ALARM, 16);
  195.       pc.buzzPlay(0, 16);
  196.     }
  197.     break;
  198.   }
  199.  
  200.   if (pc.keyEvents(KEY_ENTER, KEY_PRESSED_TIME1)) {
  201.     pc.buzzBegin();
  202.     tempo.countdown = tempo.total_time;
  203.     tempo.count_millis = 0;
  204.     tempo.state = INIT_STOP;
  205.   }
  206. }
  207.  
  208.  
  209. //
  210. // Read integer data from EEPROM
  211. //
  212. int eeprom_read16(int addr) {
  213.   return (EEPROM.read(addr + 1) << 8) | EEPROM.read(addr);
  214. }
  215.  
  216. //
  217. // Write integer data to EEPROM
  218. //
  219. int eeprom_write16(int addr, int data) {
  220.   EEPROM.write(EEPROM_ADDR_SECONDS, tempo.total_time);
  221.   EEPROM.write(EEPROM_ADDR_SECONDS+1, tempo.total_time>>8);
  222. }
  223.  
  224. //
  225. // Inicializar datos del temporizador
  226. //
  227. void tempo_init(void) {
  228.   tempo.total_time = eeprom_read16(EEPROM_ADDR_SECONDS);
  229.   tempo.state = INIT_STOP;  
  230.   tempo.alarm = OFF;
  231.  
  232.   tempo.millis = 0;
  233.   tempo.millis_old = 0;
  234.  
  235.   tempo.countdown = tempo.total_time;
  236.   tempo.count_millis = 0;
  237. }
  238.  
  239. //
  240. // Sound Alarm
  241. //
  242. void alarm_sound(void) {
  243.   pc.buzzPlay(TONE_ALARM, 62);
  244.   pc.buzzPlay(0, 62);
  245.   pc.buzzPlay(TONE_ALARM, 62);
  246.   pc.buzzPlay(0, 62);
  247.   pc.buzzPlay(TONE_ALARM, 62);
  248.   pc.buzzPlay(0, 62);
  249.   pc.buzzPlay(TONE_ALARM, 62);
  250.   pc.buzzPlay(0, 62);
  251. }
  252.  
  253.  
  254. //
  255. // Encender la fuente de alimentación
  256. //
  257. void power_on(void) {
  258.   // Desactivar la salida de potencia
  259.   pinMode(10, OUTPUT);
  260.   digitalWrite(10, HIGH);
  261. }
  262.  
  263.  
  264. //
  265. // Apagar la fuente de alimentación
  266. //
  267. void power_off(void) {
  268.   // Desactivar la salida de potencia
  269.   digitalWrite(10, LOW);
  270.   pinMode(10, INPUT);
  271. }

Saludos.
Título: Re:Arduino + placa de control PC42. Luxometro con LDR
Publicado por: Picuino en 17 de Mayo de 2016, 07:07:35
En este caso, adjunto un vídeo de la placa de control funcionando como luxómetro. Muestra el nivel de luz ambiente que recoge una resistencia LDR conectada al Arduino.


El circuito sólo añade una resistencia LDR entre los pines A0 y A1 del arduino.

El programa de control es bien sencillo:

Código: C
  1. /*
  2.   LDR Input. Lux meter.
  3. */
  4.  
  5. #include <Wire.h>
  6. #include <PC42.h>
  7.  
  8. int sensorPinInput = A0; // Input pin for the LDR
  9. int sensorPinGnd = A1;   // GND reference for the LDR
  10. int sensorValue = 0;     // Store the value coming from the sensor
  11.  
  12. void setup() {
  13.   // Declare inputs and outputs
  14.   pinMode(sensorPinInput, INPUT_PULLUP);
  15.   pinMode(sensorPinGnd, OUTPUT);
  16.   digitalWrite(sensorPinGnd, LOW);
  17.  
  18.   // Inits PC42 board
  19.   pc.begin();
  20. }
  21.  
  22.  
  23. void loop() {
  24.   // Read the value from the sensor:
  25.   sensorValue = 1023 - analogRead(sensorPinInput);    
  26.  
  27.   // Send value to PC42
  28.   pc.dispNum(sensorValue);
  29.  
  30.   // Delay 0.1 seconds
  31.   delay(100);
  32. }