Con questo progetto vorrei mostrarvi come usare arduino come presenter multimediale.
Usando un comunissimo telecomando tv e premendo tasti ben definiti (tipo next o back), arduino riceve i comandi e scrive sulla seriale le stringe NEXT e BACK.
Un programma in running sul proprio pc, si mette in ascolto sulla porta seriale dell’arduino e quando intercetta le stringe NEXT e BACK simula pressione dei tasti AVANTI o INDIETRO del proprio pc in modo tale da cambiare le slide durante la vostra presentazione.
Il codice relativo ad arduino è davvero minimale, ora sto scrivendo il programmino che mi permette di simulare la pressione dei tasti sul pc.
Attualmente sto a metà dell’opera, devo solo limare alcune cosette.
Ho usato la stessa pcb della scorsa volta (trasformandola in un modulto/breakout), un ricevitore IR e un led bicolore.
Un pò di foto:
Per il momento il codice relativo ad arduino è il seguente:
/*Arduino presenter receiver By Andrea Esposito Site: blackstufflabs.com For: The Fritzmas challenge - http://fritzing.org 17/12/2011 IRremote.h from: http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html IR Receiver pcb taked from an old divx player TV Remote control Button - INT Next - 16746615 Back - 16750695 NN - 4294967295*/
#include <IRremote.h>
#define next 16746615
#define back 16750695
#define NN 4294967295
#define red 9
#define green 10
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
voidsetup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiverpinMode(green, OUTPUT); // Green ledpinMode(red, OUTPUT); // Red led
irrecv.enableIRIn();
Serial.println (" Arduino Presenter");
Serial.println ("Coding by: ");
Serial.println (" Andrea Esposito");
Serial.println ("blackstufflabs.com");
}
voidloop() {
digitalWrite(green, HIGH);
if (irrecv.decode(&results)) {
if (results.value != NN){
if (results.value == next)
Serial.println("NEXT");
if (results.value == back)
Serial.println("BACK");
digitalWrite(green, LOW);
digitalWrite(red, HIGH); // set the LED ondelay(100); // wait for a seconddigitalWrite(red, LOW); // set the LED offdelay(100);
digitalWrite(green, HIGH);
}
irrecv.resume();
}
delay(200);
}
Non ho MAI partecipato in vita mia ad un contest su internet… ho notato che vanno molto di moda.
Ma la maggior parte si tratta di contest “pro spamming”: vinci se pubblicizzi il loro sito o partecipi assiduamente alle loro iniziative.
Questi tipi di contest non mi piacciono per niente, anzi… preferisco quelli un pò più costruttivi: vinci se hai realizzato un buon progetto.
Fritzing mi ha allettato.
Così mi sono sforzato un pochino e ho realizzato questa cosetta molto semplice ma carina (credo).
In cosa consiste?
Brevemente: ho una cornice digitale con 10 immagini, ogni immagine “racconta” un numero… bisogna indovinare il numero per andare avanti nel gioco.
Ogni immagine è un livello…
Così ho caricato un pò di immagini che raccontassero di un numero: pigreco, sezione aurea, il numero del diavolo e cazzatelle varie.
La cornice digitale non l’ho modificata per niente, nel senso che non ho fatto saldature o aperta: è rimasta intatta.
Come faccio a cambiare immagine per poi andare avanti con i livelli?
Ho usato un pò di led IR. Una tecnologia un pò di cacca.
Ho usato il telecomando della mia TV per inserire il numero misterioso, ho dovuto codificare tutti i tasti per capire che codice corrisponde ad ogni tasto.
Ho usato un IR ricevitore su pcb preso da un vecchio lettore divx con già presaldati resistenze e condensatori, un led ir preso da un vecchio telecomando, 3 led rossi e un buzzer.
Ho collegato la pcb del ricevitore ad arduino e il led ir l’ho ficcato nel buchetto del ir receiver della cornice digitale (niente saldature giuro) per tenerlo fermo e per non fare brutte figure durante il video.
Il tre led rossi indicano se la sequenza dei numeri immessi è corretta, ogni led indica: primo, secondo e terzo numero della sequenza corretta immessa.
Se la sequenza o il numero immesso con il telecomando è errata non avviene nulla: hai sbagliato quindi non vai avanti di livello.
Il buzzer mi è servito per fare un pò “scena”, ho messo qualche canzoncina presa dal google e ho usato la libreria tone.h presa da (mi pare): http://code.google.com/p/rogue-code/
Probabilmente un video può aiutare meglio a capire che cavolo ho combinato.
Vi posto un pò di materiale:
/*Interactive digital frame game By Andrea Esposito Site: blackstufflabs.com For: The Fritzmas challenge - http://fritzing.org 13/12/2011 IRremote.h from: http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html Tone.h & RTTL function from: http://code.google.com/p/rogue-code/ IR Led wiring from: http://www.ladyada.net/make/tvbgone/design.html IR Receiver pcb taked from an old divx player NN = FFFFFFFF = 4294967295 TV Remote control: Button - HEX - INT 1 - FF32CD - 16724685 2 - FF708F - 16740495 3 - FFB24D - 16757325 4 - FFF20D - 16773645 5 - FF728D - 16741005 6 - FFD02F - 16764975 7 - FF52AD - 16732845 8 - FF12ED - 16716525 9 - FF50AF - 16732335 0 - FFB04F - 16756815 Digital Frame remote control: Button - HEX - INT next - 80579867 - 2153224295 power - 805728D7 - 2153195735 Answers: Level - sequence Level 0 - 111 Level 1 - 666 Level 2 - 011 Level 3 - 945 Level 4 - 314 Level 5 - 975 Level 6 - 328 Level 7 - 101 Level 8 - 161 Level 9 - 100 Level 10 - 210 */
#include <IRremote.h>
#include <Tone.h>
#define button_0 16756815
#define button_1 16724685
#define button_2 16740495
#define button_3 16757325
#define button_4 16773645
#define button_5 16741005
#define button_6 16764975
#define button_7 16732845
#define button_8 16716525
#define button_9 16732335
#define button_power 0x805728D7
#define button_next 0x80579867
#define NN 4294967295
Tone tone1;
#define OCTAVE_OFFSET 0
//char *song = "WeWishYou:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,2g,d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,1g,d,g,g,g,2f#,f#,g,f#,e,2d,a,b,8a,8a,8g,8g,d6,d,d,e,a,f#,2g"; char *ending = "WeWishYou:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b";
char *next = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p";
char *wrong = "StarWars:d=4,o=5,b=45:32p,32f#,32f#";
int notes[] = {
0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;
short level=0;
short count=0;
#define isdigit(n) (n >= '0' && n <= '9')
voidsetup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiverpinMode(12, OUTPUT); // IR GREENpinMode(7, OUTPUT); // IR RED pinMode(4, OUTPUT); // 1 redpinMode(5, OUTPUT); // 2 red pinMode(6, OUTPUT); // 3 red
tone1.begin(8); //buzzer on pin 8
irrecv.enableIRIn();
Serial.println ("blackstufflabs.com");
}
voidloop() {
digitalWrite(12, HIGH);
if (irrecv.decode(&results)) {
if (results.value != NN){
Serial.print("Level: ");
Serial.println(level);
Serial.print("Code: ");
Serial.println(results.value);
digitalWrite(12, LOW);
digitalWrite(7, HIGH); // set the LED ondelay(100); // wait for a seconddigitalWrite(7, LOW); // set the LED offdelay(100);
digitalWrite(12, HIGH);
game(results.value);
}
if (level != 0 ) irrecv.enableIRIn();
irrecv.resume(); // Receive the next value
}
delay (200);
}
void game (unsignedlongint code)
{
switch (level)
{
case 0:
if ((code == button_1) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_1) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_1) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 1:
if ((code == button_6) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_6) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_6) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 2:
if ((code == button_1) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_1) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_0) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 3:
if ((code == button_5) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_4) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_9) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 4:
if ((code == button_4) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_1) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_3) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 5:
if ((code == button_5) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_7) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_9) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 6:
if ((code == button_8) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_2) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_3) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 7:
if ((code == button_1) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_0) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_1) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 8:
if ((code == button_1) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_6) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_1) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 9:
if ((code == button_0) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_0) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_1) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("Level done!");
count=0;
level++;
blinky();
play_rtttl(next);
irsend.sendNEC(button_next, 32);
}
break;
case 10:
if ((code == button_0) && (count == 2)) {
digitalWrite(4, HIGH);
count++;
}
if ((code == button_1) && (count == 1)) {
digitalWrite(5, HIGH);
count++;
}
if ((code == button_2) && (count == 0)) {
digitalWrite(6, HIGH);
count++;
}
if (count == 3)
{
Serial.println("THE END");
count=0;
level=0;
irsend.sendNEC(button_next, 32);
blinky();
play_rtttl(ending);
Serial.println("Done.");
blinky();
//songSerial.println("Closing digital frame...");
irsend.sendNEC(button_power, 32);
Serial.println("Bye bye!!!");
Serial.println ("blackstufflabs.com");
}
break;
default:
break;
}
}
void blinky()
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(300);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(300);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(300);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(300);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(300);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(300);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(300);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(300);
}
void play_rtttl(char *p)
{
// Absolutely no error checking in herebyte default_dur = 4;
byte default_oct = 6;
int bpm = 63;
int num;
long wholenote;
long duration;
byte note;
byte scale;
// format: d=N,o=N,b=NNN:// find the start (skip name, etc)while(*p != ':') p++; // ignore name
p++; // skip ':'// get default durationif(*p == 'd')
{
p++;
p++; // skip "d="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num > 0) default_dur = num;
p++; // skip comma
}
//Serial.print("ddur: "); Serial.println(default_dur, 10);// get default octaveif(*p == 'o')
{
p++;
p++; // skip "o="
num = *p++ - '0';
if(num >= 3 && num <=7) default_oct = num;
p++; // skip comma
}
// Serial.print("doct: "); Serial.println(default_oct, 10);// get BPMif(*p == 'b')
{
p++;
p++; // skip "b="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
bpm = num;
p++; // skip colon
}
// Serial.print("bpm: "); Serial.println(bpm, 10);// BPM usually expresses the number of quarter notes per minute
wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds)// Serial.print("wn: "); Serial.println(wholenote, 10);// now begin note loopwhile(*p)
{
// first, get note duration, if available
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num) duration = wholenote / num;
else duration = wholenote / default_dur; // we will need to check if we are a dotted note after// now get the note
note = 0;
switch(*p)
{
case'c':
note = 1;
break;
case'd':
note = 3;
break;
case'e':
note = 5;
break;
case'f':
note = 6;
break;
case'g':
note = 8;
break;
case'a':
note = 10;
break;
case'b':
note = 12;
break;
case'p':
default:
note = 0;
}
p++;
// now, get optional '#' sharpif(*p == '#')
{
note++;
p++;
}
// now, get optional '.' dotted noteif(*p == '.')
{
duration += duration/2;
p++;
}
// now, get scaleif(isdigit(*p))
{
scale = *p - '0';
p++;
}
else
{
scale = default_oct;
}
scale += OCTAVE_OFFSET;
if(*p == ',')
p++; // skip comma for next note (or we may be at the end)// now play the noteif(note)
{
/* Serial.print("Playing: "); Serial.print(scale, 10); Serial.print(' '); Serial.print(note, 10); Serial.print(" ("); Serial.print(notes[(scale - 4) * 12 + note], 10); Serial.print(") "); Serial.println(duration, 10);*/
tone1.play(notes[(scale - 4) * 12 + note]);
delay(duration);
tone1.stop();
}
else
{
/* Serial.print("Pausing: "); Serial.println(duration, 10);*/delay(duration);
}
}
}