Ik wil graag zelf stuurbediening maken. ik heb inmiddels het protocool op internet gevonden wat zou moeten werken.
Maar ik weet niet goed hoe ik dit practisch in een code kan zetten. Want ik wil liever geen delays gebruiken. Ik heb er ook nog aan gedacht om elk gedeelte uit te schrijven met if functies met tijd als functie, alleen dat lijkt mij veel overbodig werk.
bijvoorbeeld volume harder is
9ms puls
4,5ms pauze
vervolgens
13112214 424122111 als puls code
De 3 staat voor 3 pulsjes van 0,5ms en de tusenliggen periode is 0,5ms uit, tussen de 1 en 3 zit een 1ms pauze
dit is uitgeschreven:
0,5ms puls
1ms uit
0,5ms puls
0,5ms uit
o,5ms puls
o,5ms uit
0,5ms puls
1ms uit
0,5ms puls
1ms uit
0,5ms puls
1ms uit
0,5ms puls
o,5ms uit
0,5ms puls
1ms uit
enz...
Er zijn 8 toetsen en deze hebben allemaal 33 pulsen (excl. de start puls)
Je hebt gelijk, als je kan moet je altijd het gebruik van delay() proberen te voorkomen.
Maar jouw probleem is vermoedelijk al een tijdje opgelost.
Want dit zijn infrarood afstandbediening signalen.
En daar zijn meerdere oplossingen voor te vinden.
Let er op dat deze link naar een oplossing leidt die in 2009 is gemaakt, en daarmee voor IDE 1.0.
Dat betekent dat als deze niet is bijgewerkt, die mogelijk niet meer goed zal werken (compile errors gaat geven).
Ik zal nog ff kijken of ik iets recenters kan vinden.
de delays zijn allemaal in de orde van 0.5-1 millis. dat betekent dat een hele reeks pulsen ind e orde van 35 millis bedraagt.
Ik zou voor een eerste versie met delay werken, omdat de pulsen zo snel gegeven kunnen, sneller dan de mesnselijke interactie. Indien het niet "smooth" blijkt te werken kan er nog altijd 'clock-driven' gecodeerd worden.
Verder heb ik ooit wat gespeeld met pulse patterns versturen middels een timer op de achtergrond.
Arduino Playground - PulsePattern -
De state machine is niet compleet geimplementeerd (o.a. state==INIT missing)
Verder moet er nog een flag toegevoegd worden ONESHOT - CONTINUOUS
so use at own risk
dank voor de reactie's ik zal me er eens verder in verdiepen.
Betreffende de delays.
Die wil ik liever niet gebruiken omdat ik maximaal 1 arduino in de auto wil hebben.
ik heb verder nog 2 temperatuur sensoren, 1 druksensor en een transistor aansturing die moet blijven werken.
In de toekomst komen er nog 3 hallsensoren bij, nog een transistor en misschien een motor aansturing.
maar het is inderdaad makkelijk om te testen of uberhaupt het protocool juist is.
#include <IRremote.h>
int harder =7;
int zachter =8;
int source =5;
int omhoog =6;
int omlaag =4;
int Harder;
int Zachter;
int Source;
int Omhoog;
int Omlaag;
unsigned long tijd=0;
unsigned long tijdomhoog=0;
unsigned long tijdomlaag=0;
IRsend irsend;
void setup(){
pinMode (harder,INPUT);
pinMode (zachter,INPUT);
pinMode (source,INPUT);
pinMode (omhoog,INPUT);
pinMode (omlaag,INPUT);
}
void loop(){
Harder=digitalRead(harder);
Zachter=digitalRead(zachter);
Source=digitalRead(source);
Omhoog=digitalRead(omhoog);
Omlaag=digitalRead(omlaag);
tijd=millis();
if (Harder == HIGH && Zachter==LOW){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D6228D7, 32);} }
if (Harder == LOW && Zachter==HIGH){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D62A857, 32);} }
if (Harder == HIGH && Zachter==HIGH){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D6249B6, 32);} }
if (Source == HIGH){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D62C837, 32);} }
if (Omhoog == HIGH){
delay(500);
if (tijd-tijdomhoog<=500){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D62D02F, 32); }
tijdomhoog=tijd;}
if (tijd-tijdomhoog>500){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D62B04F, 32);}
tijdomhoog=tijd;}
}
if (Omhoog==LOW){
tijdomhoog = tijd;}
if (Omlaag == HIGH){
delay(500);
if (tijd-tijdomlaag<=500){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D6250AF, 32); }
tijdomlaag=tijd;}
if (tijd-tijdomlaag>500){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x9D6230CF, 32); }
tijdomlaag=tijd;}
}
if (Omlaag==LOW){
tijdomlaag = tijd;}
}
Als je meer dan 1 Arduino hebt, kun je testen wat je zendt.
Dan kun je dus zien of je wel weer die NEC code uitzendt.
Weet je overigens zeker dat je de zend LED correct hebt aangesloten ?
Als je 'm verkeerd zou aansluiten, dan zend je niet of misschien geïnverteerd uit.
Wellicht dat je dat kunt zien door tijdelijk een rode LED (met bijbehorende weerstand) aansluit in plaats van de IR LED, als je geen 2 Arduino's hebt.
Inmiddels krijg ik de led zendend en klopt de uitgezonden informatie ook (mijn radio reageert erop)
Alleen als ik een knopje indruk dan blijft hij aan de voorwaarden voldoen en dus gaat de radio bijvoorbeeld ipv 1 streepje harder 10 streepjes harder.
Hoe kan ik ervoor zorgen dat hij bij de juiste volgorde de code 1x doorloopt?
/*
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
* An IR LED must be connected to Arduino PWM pin 3.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/
#include <IRremote.h>
int harder =7;
int zachter =8;
int source =5;
int omhoog =6;
int omlaag =4;
int Harder;
int Zachter;
int Source;
int Omhoog;
int Omlaag;
int omhoog_delay=0;
int omlaag_delay=0;
IRsend irsend;
void setup(){
pinMode (harder,INPUT);
pinMode (zachter,INPUT);
pinMode (source,INPUT);
pinMode (omhoog,INPUT);
pinMode (omlaag,INPUT);
Serial.begin(9600);
}
void loop(){
Harder=digitalRead(harder);
Zachter=digitalRead(zachter);
Source=digitalRead(source);
Omhoog=digitalRead(omhoog);
Omlaag=digitalRead(omlaag);
if (Harder == HIGH && Zachter==LOW){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0X9D6228D7,32);}
Serial.println("Vol+");
}
if (Harder == LOW && Zachter==HIGH){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D62A857,32);}
Serial.println("Vol-"); }
if (Harder == HIGH && Zachter==HIGH){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D6249B6, 32);}
Serial.println("telefoon");}
if (Source == HIGH){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D62C837, 32);}
Serial.println("Source"); }
if (Omhoog ==LOW){
omhoog_delay=0;
}
while (Omhoog == HIGH){
omhoog_delay++;
Omhoog=digitalRead(omhoog);
if (omhoog_delay <10){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D62D02F, 32); }
Serial.println("nummer+");
Serial.println(omhoog_delay);
}
if (omhoog_delay>=10){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D62B04F, 32);}
Serial.println("map+");
}
}
if (Omlaag == LOW){
omlaag_delay=0;}
while (Omlaag == HIGH){
omlaag_delay++;
Omlaag=digitalRead(omlaag);
if (omlaag_delay<10){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D6250AF, 32); }
Serial.println("nummer-");
Serial.println(omlaag_delay);
}
if (omlaag_delay>=10){
for (int i = 0; i < 1; i++) {
irsend.sendNEC(0x9D6230CF, 32); }
Serial.println("map-");
}
}
}
Je kijkt nu of er een knop word ingedrukt, en als dat het geval is ga je de code uitzenden.
Daarmee ga je die code dus heel vaak uitzenden, terwijl je dat waarschijnlijk niet wil.
Daarom is het slimmer om te kijken welke knop er word ingedrukt, en dat sla je dan even op.
Dan kijk je nog een keer welke knop er word ingedrukt, en als dat dezelfde knop als daarnet was, zend je de code die daarbij hoort uit.
Op die manier heb je dus een debounce functie gecreëerd.
Wanneer je de code hebt uitgezonden, komt er een nieuwe voorwaarde bij.
Die voorwaarde is dat er iets anders geregistreerd moet worden dan die knop van daarnet.
Iets anders is dus een andere knop die heel kort werd gedrukt, of geen knop.
Als aan die andere voorwaarde werd voldaan, kun je de code nog een keer uitzenden.
Alleen wil je dit gedrag wel hebben bij bijvoorbeeld een cijfer toets, maar niet bij de volume knop.
Daarom kun je als je het hierboven staande hebt uitgewerkt, knoppen als volume anders doen.
Daar kun je dan gaan kijken hoe lang die knop ingedrukt blijft.
Daarvoor houd je dus de tijd in de gaten.
En dan kun je bijvoorbeeld elke halve seconde die volume up of down uitzenden.
Er gelden natuurlijk nog andere knoppen waar dit ook wenselijk voor zal zijn.
Dit is een gevalletje "blink without delay", die je als leidlijn kunt gebruiken om dit laatste te bereiken.
Ik heb zelf wel eens met die remotes gewerkt. Het blijkt dat als je de knop ingedrukt houdt, dat hij dan alleen een code 65536 geeft en niet de feitelijke toets zelf.
Ik had het toen zo opgelost met een functie die de ingedrukte toets verder verwerkt
/**
* @name doResponse(int key)
* @param key
*
* respond to specific remote-control keys with different behaviors.
* On any key defined below you may add your own function calls
*/
void doResponse(unsigned int key)
{
unsigned int keyToProcess;
//
// Check if this is a repeat function
//
if (key == 65535) {
//
// yes so give the last key for processing
//
keyToProcess = lastKey;
} else {
//
// this is a valid key so use it and save it for the next time
//
keyToProcess = key;
lastKey = key;
}
//
// if we want to verify the control switch output_key on. the data
// will be send to the serial terminal
//
if (OUTPUT_KEY == 1)
{
Serial.print("\nKey ");
Serial.println(key);
}
//
// determine which key was pressed and send it to the terminal
//
switch (keyToProcess)
{
case 255: // turns on UUT power
Serial.println("\nPOWER");
break;
case 16575: // FUNC/STOP turns off UUT power
Serial.println("\nFUNC/STOP");
break;
case 8415: // |<< ReTest failed Test
Serial.println("\n|<<");
lightsOff();
break;
case 41055: // >|| Test
Serial.println("\n>||");
break;
case 24735: // >>| perform selected test number
Serial.println("\n>>|");
lightsOn();
break;
case 32895: // VOL+ turns on individual test beeper
Serial.println("\nVOL+");
break;
case 36975: // VOL- turns off individual test beeper
Serial.println("\nVOL-");
break;
case 4335: // v scroll down tests
Serial.println("\nv");
moveDown();
break;
case 20655: // ^ scroll up tests
Serial.println("\n^");
moveUp();
break;
case 45135: // EQ negative tests internal setup
Serial.println("\nEQ");
break;
case 28815: // ST/REPT Positive tests Select
// Test and Repeat Test
Serial.println("\nST/REPT");
break;
case 12495: // 0
Serial.println("\n0");
break;
case 2295: // 1
Serial.println("\n1");
break;
case 35063: // 2
Serial.println("\n2");
break;
case 18615: // 3
Serial.println("\n3");
break;
case 10455: // 4
Serial.println("\n4");
break;
case 43095: // 5
Serial.println("\n5");
break;
case 26775: // 6
Serial.println("\n6");
break;
case 6375: // 7
Serial.println("\n7");
break;
case 39015: // 8
Serial.println("\n8");
break;
case 22695: // 9
Serial.println("\n9");
break;
default:
// error
Serial.print("\nKey ");
Serial.print(key);
Serial.println(" not programmed");
//
// remove power from the motor
//
digitalWrite(MOTOR_POWER, RELAY_OFF);
delayCtr = 0L;
break;
}
}