Mål: Att sätta på/av en IKEA ljusslinga m.h.a. röstigenkänning på mobiltelefonen.
Material:
- Arduino Uno mikrokontroller
- OneSheeld
- IKEA ljusslinga DIODER
- 4N25 optokopplare
Arduino koden
#define CUSTOM_SETTINGS #define INCLUDE_VOICE_RECOGNIZER_SHIELD #include <OneSheeld.h> const char command1[]="good morning"; const char command2[]="goodnight"; void setup() { OneSheeld.begin(); Serial.begin(115200); pinMode(9, OUTPUT); } void loop() { if(VoiceRecognition.isNewCommandReceived()) { if(!strcmp(command1,VoiceRecognition.getLastCommand())) { digitalWrite(9, HIGH); delay(500); digitalWrite(9, LOW); } else if(!strcmp(command2,VoiceRecognition.getLastCommand())) { digitalWrite(9, HIGH); delay(500); digitalWrite(9, LOW); } } }
Bakgrund
Kontrollern till ljusslingorna har en tryckknapp (on/off) som man vill komma åt. Vi lödde bort knappen och mätte spänningen över benen. 5 Volt. En optokopplare är perfekt on/off knapp till Arduino projekt som inte har för stora krav på spänning och ström. Dessutom är Arduino fysisk bortkopplad från kretskortet i ljusslingan.
Eftersom tryckknappen inte hålls in så måste man i programmeringen pröva sig fram till hur länge optokopplaren ska vara på och av.
Hur allt fungerar
- Användaren säger “good morning” i 1Sheeld appen på mobiltelefonen.
- Kommandot skickas via bluetooth till 1Sheeld modulen som är kopplad till Arduino.
- Koden läser kommandot och sätter pin9 HIGH (5V).
- Optokopplaren aktiveras och kopplar ihop de två kablarna som är lödda till tryckknappens plats i kretskortet från ljusslingan.
- Lysdioderna börjar lysa.
- Då användaren säger good night sätts pin9 HIGH igen och dioderna slocknar.
- Kretskortet i ljusslingan har en egen inbyggd logik som både tänder och släcker dioderna då knappen trycks in.
Utvecklingsidéer
- Det finns ytterligare två tryckknappar och en potentiometer i DIODER kontrollern som kunde styras med 1Sheeld. De två andra knapparna (olika färgprogram) skulle vara enkla att styra medan potentiometern (vilken färg) skulle kräva lite extra tankearbete. Fast det skulle vara häftigt att kunna säga t.ex. “green lights on”.
- En idé skulle vara att skriva ett program i processing (istället för 1sheeld) där man med musen kan välja olika färger och program för att styra dioderna.
- Ett annat alternativ skulle vara att låta musiken styra färgerna. T.ex. så att låga frekvenser skulle motsvaras av röd färg och höga frekvenser blå färg.
- Skulle också vara roligt att styra ljusslingan med tv-fjärrkontrollen så att man kan sätta på/av samt ändra färg på lysdioderna samtidigt som man tittar på tv.
Uppdatering 5.4.2017
Nu är utvecklingsidé 1 klar. Alla tre knappar är ersatta med optokopplare och en digital potentiometer mcp4231 används för att ratta färgen.
Arduino koden
#define CUSTOM_SETTINGS #define INCLUDE_VOICE_RECOGNIZER_SHIELD #include <OneSheeld.h> #include <SPI.h> // pin 11: MOSI by default // pin 12: MISO by default // pin 13: CLK by default const int slave = 10; // Slave select pin 1 const byte REG0=B00000000; // Register 0 - write command int SHDNPin = 4; // chip wiper enable/disable pin 12 int powerPin = 5; // dioder power int discoPin = 6; // dioder disco mode int fadePin = 7; // dioder fade mode // voice commands const char white[]="white"; const char red[]="red"; const char green[]="green"; const char blue[]="blue"; const char on[]="on"; const char off[]="off"; const char fade[]="fade"; const char disco[]="disco"; void setup() { // init. communication protocols OneSheeld.begin(); SPI.begin(); // pin directions pinMode(slave, OUTPUT); pinMode(SHDNPin, OUTPUT); pinMode(powerPin, OUTPUT); pinMode(discoPin, OUTPUT); pinMode(fadePin, OUTPUT); // disable wiper digitalWrite(SHDNPin, LOW); digitalWrite(powerPin, LOW); } void setPotValue(int ss, int reg, int val) // temp. variables { digitalWrite(ss, LOW); // set slave select low SPI.transfer(reg); // choose register SPI.transfer(val); // set pot value (0-128) digitalWrite(ss, HIGH); // set slave select high } void loop() { if(VoiceRecognition.isNewCommandReceived()) { if(!strcmp(on,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, LOW); // disable wiper since it disturbs buttons digitalWrite(powerPin, HIGH); // connect button terminals ... delay(500); // for half a second digitalWrite(powerPin, LOW); // disconnect } else if(!strcmp(off,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, LOW); // disable wiper since it disturbs buttons digitalWrite(powerPin, HIGH); // connect button terminals ... delay(500); // for half a second digitalWrite(powerPin, LOW); // disconnect } else if(!strcmp(disco,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, LOW); // disable wiper since it disturbs buttons digitalWrite(discoPin, HIGH); // connect button terminals ... delay(500); // for half a second digitalWrite(discoPin, LOW); // disconnect } else if(!strcmp(fade,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, LOW); // disable wiper since it disturbs buttons digitalWrite(fadePin, HIGH); // connect button terminals ... delay(500); // for half a second digitalWrite(fadePin, LOW); // disconnect } else if(!strcmp(white,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, 0); // write value to register 0 } else if(!strcmp(green,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, 42); // write value to register 0 } else if(!strcmp(blue,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, 84); // write value to register 0 } else if(!strcmp(red,VoiceRecognition.getLastCommand())) { digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, 127); // write value to register 0 } } }
Uppdatering 22.11.2017
Nu är utvecklingsidé 4 klar. Jag valde att använda mig av endast en knapp till dioder-kontrollern eftersom disco och fade funktionen kändes onödig. IR-mottagaren som jag använde är TSOP31238. Jag var på hugget att se om jag kan använda två fjärrkontroller samtidigt så därför finns både tv-fjärrkontrollen(LG) samt apple remote med i bilden (och koden).
Eftersom spänningen mellan polerna till knappen samt potentiometern i dioder-modulen låg vid 5V så valde jag att förse min arduino med ström rakt från modulen. (En medveten risk.)
Arduino koden
#include <SPI.h> #include <IRremote.h> // pin 11: MOSI by default // pin 12: MISO by default // pin 13: CLK by default const int slave = 10; // Slave select pin 1 const byte REG0=B00000000; // Register 0 - write command int SHDNPin = 4; // chip wiper enable/disable pin 12 int powerPin = 2; // dioder power int RECV_PIN = 9; // TSOP31238 OUT-pin IRrecv irrecv(RECV_PIN); decode_results results; // default values int W = 127; int B = 32; int G = 76; void setup() { // init. communication protocols SPI.begin(); // Serial.begin(9600); // for debugging purposes // pin directions pinMode(slave, OUTPUT); pinMode(SHDNPin, OUTPUT); pinMode(powerPin, OUTPUT); irrecv.enableIRIn(); digitalWrite(SHDNPin, LOW); // disable wiper } void setPotValue(int ss, int reg, int val) // temp. variables { digitalWrite(ss, LOW); // set slave select low SPI.transfer(reg); // choose register SPI.transfer(val); // set pot value (0-128) digitalWrite(ss, HIGH); // set slave select high } void loop() { if(irrecv.decode(&results)) // wait for incoming IR signal { if(results.value == 0x77E15085 || results.value == 0x20DF4EB1) // up/red --> on/off { digitalWrite(SHDNPin, LOW); // disable wiper since it disturbs buttons digitalWrite(powerPin, HIGH); // connect power-button terminals ... delay(500); // for half a second digitalWrite(powerPin, LOW); // disconnect } else if(results.value == 0x77E13085 || results.value == 0x20DF8E71 ) // down/green --> white { if(W == 127){ B = 32; // reset blue G = 76; // reset green digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, W); // write value to register 0 W = 128; // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } else{ if(W <10){W = 132;} digitalWrite(SHDNPin, HIGH); // enable wiper W = W - 5; setPotValue(slave, REG0, W); // write value to register 0 // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } } else if(results.value == 0x77E19085 || results.value == 0x20DFC639 ) // left/yellow --> lightblue { if(B == 32){ W = 127; // reset white G = 76; // reset green digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, B); // write value to register 0 B = 33; // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } else{ if(B > 80){B = 31;} digitalWrite(SHDNPin, HIGH); // enable wiper B = B + 5; setPotValue(slave, REG0, B); // write value to register 0 // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } } else if(results.value == 0x77E16085 || results.value == 0x20DF8679) // right/blue --> green { if(G == 76){ W = 127; // reset white B = 32; // reset green digitalWrite(SHDNPin, HIGH); // enable wiper setPotValue(slave, REG0, G); // write value to register 0 G = 77; // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } else{ if(G > 105){G = 77;} digitalWrite(SHDNPin, HIGH); // enable wiper G = G + 5; setPotValue(slave, REG0, G); // write value to register 0 // Serial.print("white: "); // Serial.print(W); // Serial.print(" green: "); // Serial.print(G); // Serial.print(" blue: "); // Serial.println(B); } } irrecv.resume(); } delay(5); }
adga