what happens is that, when i press # (0xFF52AD) the program doesn't wait and goes immediately at the else statement, i think i'm misunderstanding the use of irrecv.resume, i searched a lot on the forum and i tried to put them in various places in the program, but it still doesn't work. What's wrong?
In order to update results, you need to call irrecv.decode(&results). But you are only giving the user 100 ms to press the button so they would need to be extremely fast. irrecv.decode(&results) returns true when a new code was received so there is no need to use an arbitrary delay that the user needs to manage to press the button within. The naive implementation would be to just sit in a while loop until the code is received:
while(!irrecv.decode(&results)) {}
but that blocks anything else from happening in your program, so it might be a problem if you later wanted to add other functionality to the code. Better would to set a state variable after receive 0xFF52AD and then just let loop() run until the next code is received, then act accordingly based on the value of the state variable.
caesar753:
i think i'm misunderstanding the use of irrecv.resume, i searched a lot on the forum and i tried to put them in various places in the program
I don't understand the point of that function, but the use of it is clear if you read the IRremote library documentation:
irrecv.resume()
This must be called after irrecv.decode() to resume listening for a code.
I'd think that it would be obvious that the user wanted to start listening again after calling irrecv.decode(&results) and that would be done automatically, but maybe there's some use case I don't know about where being able to separately control listening is useful.
I could be wrong, but as I understand it resume() is needed because there is only one receive buffer (to save memory).
Once the library has identified the end of an IR transmission, the user has to decode the raw data using decode() which runs through the configured protocols. If the library was to start receiving the next IR signal before this happens, the internal buffer would be overwritten. resume() tells the library it is safe to start receiving again.
Thanks a lot, i understood the use of .decode and .resume in ir library, but now i have another trouble: i'd like to insert a multiple digit number, i googled and found something that i managed to use, but now i'd like to start the insertion of the number after a key is pressed (0xFF42BD)
This is my code
#include <IRremote.h>
/*
Variables
*/
int RECV_PIN = 6;
const int MaxChars = 2;
char ch;
int index = 0;
int accumulVal = 0;
char strValue[3];
int i = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
// In case the interrupt driver crashes on setup, give a clue
// to the user what's going on.
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
}
void loop() {
if (irrecv.decode(&results)){
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
delay(150);
if (results.value == 0xFF42BD){ //* key on remote
Serial.println("Insert value");
if (irrecv.decode(&results)){
irrecv.resume();
delay(2500);
// switch / case function
switch (results.value)
{
case 0xFF6897 : // Button '1' on my remote
strValue[index++] = '1';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break; // assign number to button press
case 0xFF9867: // Button '2' on my remote
//index++;
strValue[index++] = '2';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFFB04F : // Button '3' on my remote
//index++;
strValue[index++] = '3';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF30CF : // Button '4' on my remote
strValue[index++] = '4';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF18E7 : // Button '5' on my remote
strValue[index++] = '5';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF7A85 : // Button '6' on my remote
strValue[index++] = '6';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF10EF : // Button '7' on my remote
strValue[index++] = '7';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0x2FF38C7 : // Button '8' on my remote
strValue[index++] = '8';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF5AA5 : // Button '9' on my remote
strValue[index++] = '9';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFF4AB5 : // Button '0' on my remote
strValue[index++] = '0';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
delay(2000);
break;
case 0xFFFFFFFF : // Key depressed long
prevKey = 0; // clear
break;
case 0xFF02FD : // OK button
//strValue[index] = 0; // terminate the string with a 0
accumulVal = atoi(strValue); // use atoi to convert string to an int
Serial.print("Accumulated value: ");
Serial.println(accumulVal, DEC);
Serial.print("Serial print value: ");
for (i = 0; i < 3; i++){
Serial.print(strValue[i]);
}
Serial.println();
index = 0; // reset index to receive other data
i = 0;
accumulVal = 0;
memset(strValue, 0, 3);
strValue[index] = 0;
delay (2000);
} // end of cases
}
}
} // loop end
so, if i press 0xFF42BD on remote i enter in if statement, but when i insert a digit the program exit from the if, so i have to press again 0xFF42BD to re-enter and insert another digit, how can i stay inside the if till i put in the array 3 digits?
You don't do it that way because nothing else will run properly while you are 'waiting' for the next digit to arrive. What happens if the user only enters 2 digits, or if one of the 'digits' is not a number?
The standard way to handle this is to implement a Finite State Machine (or FSM) that recognises each digit as it arrives and builds up the number with each key press. This is not difficult but you will need to learn some new concepts if you have not seen this before.
Thanks for your reply. I googled a little, andthe only "readable" thing i found is this article https://www.instructables.com/id/Finite-State-Machine-on-an-Arduino/
So is it supposed that i have to use graphical software (as yakindu) or can write directly the code?
I found some code online of FSM but it's quite difficult, and found no tutorial which introduces basically FSM.
The easiest way to code simple state machines is using a switch/case statement (my prerefence) or an equivalent sequence of if/else statements. No external tools or libraries required.
The thing that i can notice is that there is a very poor response from the ir input: many times i get 0xFFFFFF (key pressed to long) or for the same button different code (one with 5 hexadecimal digits, which i have yet mapped, and one with 7 hexadecimal digits), has anyone any idea about this strange behaviour?
Yes, It has but only after irrecv.resume because if I delete the delay the code registers only the first digit three times. I diminished the delay till 50ms buy glitches are still present
So, i remapped the ir codes assignign to each button two possible hexadecimal values and use the accumulated integer to drive a stepper motor, this is my code
#include <IRremote.h>
#include <Stepper.h>
#include <IRremote.h>
// Number of steps per revolution of INTERNAL motor in 4-step mode
#define STEPS_PER_MOTOR_REVOLUTION 32
// Number of steps per revolution of OUTPUT SHAFT (= gear reduction; 2048 steps)
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64
// Declare 'small_stepper' variable
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);
// Declare 'Steps2Take' variable
int Steps2Take;
/*
Variables
*/
int RECV_PIN = 6;
const int MaxChars = 5;
char strValue[MaxChars]; // String for 4 digits + null char
char ch;
int index = 1;
int accumulVal = 0;
//int newKey = 0;
//int prevKey = 0;
int i = 0;
int state = 1;
char sign; // senso in cui girerà il motore
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
// In case the interrupt driver crashes on setup, give a clue
// to the user what's going on.
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
}
void loop() {
if (results.value == 0xFF42BD){ //tasto * sul telecomando
state = 2;
}
else if (results.value == 0xFF52AD){
state = 1;
}
/*if (irrecv.decode(&results)){
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
delay(150);}*/
if (state == 1) {
Serial.println("Inserire segno utilizzando i tasti destro/sinistro");
if (irrecv.decode(&results)){
irrecv.resume();
delay(500);
switch (results.value){
case 0xFF22DD: //left button:
case 0x52A3D41F:
sign = '-';
strValue[0] = '-';
Serial.println(sign);
delay (1000);
state = 2;
break;
case 0xFFC23D: //right button:
case 0x20FE4DBB:
sign = '+';
strValue[0] = '+';
Serial.println(sign);
delay (1000);
state = 2;
break;
case 0xFF6897:
state = 2;
break;
default:
Serial.println("nessuna scelta effettuata");
break;
}
}
}
if (state == 2){
Serial.println("Inserire valore");
if (irrecv.decode(&results)){
irrecv.resume();
delay(150);
switch (results.value){
case 0xFF6897:
case 0xC101E57B: // Button '1' on my remote
strValue[index++] = '1';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break; // assign number to button press
//case 0xC101E57B
case 0xFF9867:
case 0x97483BFB: // Button '2' on my remote
//index++;
strValue[index++] = '2';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFFB04F:
case 0xF0C41643: // Button '3' on my remote
//index++;
strValue[index++] = '3';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF30CF:
case 0x9716BE3F: // Button '4' on my remote
strValue[index++] = '4';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF18E7:
case 0x3D9AE3F7: // Button '5' on my remote
strValue[index++] = '5';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF7A85:
case 0x6182021B: // Button '6' on my remote
strValue[index++] = '6';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF10EF:
case 0x8C22657B: // Button '7' on my remote
strValue[index++] = '7';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0x2FF38C7:
case 0x488F3CBB: // Button '8' on my remote
strValue[index++] = '8';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF5AA5:
case 0x449E79F: // Button '9' on my remote
strValue[index++] = '9';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
case 0xFF4AB5:
case 0x1BC0157B: // Button '0' on my remote
strValue[index++] = '0';
Serial.print(index);
Serial.print(" ,");
Serial.println(strValue[index]);
//delay(200);
break;
/*case 0xFFFFFFFF : // Key depressed long
prevKey = 0; // clear
break;*/
}
//} while (index < 3);
/*if (irrecv.decode(&results)){
irrecv.resume();
delay(500);}*/
//delay(1000);
}
if (index >= 5){
state = 3;}
}
if (state == 3){
if (irrecv.decode(&results)){
irrecv.resume();
delay(150);
/*if (results.value == 0xFF02FD){ // OK button*/
//strValue[index] = 0; // terminate the string with a 0
if (results.value == 0xFF52AD || results.value == 0x3EC3FC1B){ //button # on my remote
index = 1; // reset index to receive other data
i = 0;
accumulVal = 0;
memset(strValue, 0, 3);
strValue[index] = 0;
state = 1;
}
else {
accumulVal = atoi(strValue); // use atoi to convert string to an int
Serial.print("Accumulated value: ");
//Serial.print(sign);
Serial.println(accumulVal, DEC);
Serial.print("Serial print value: ");
//Serial.print(sign);
for (i = 0; i < 5; i++){
Serial.print(strValue[i]);
}
Serial.println();
Steps2Take = accumulVal; // Rotate CCW 1/2 turn
small_stepper.setSpeed(1000); // 2000 a good max speed??
small_stepper.step(Steps2Take);
delay(2000);
//delay (1000);
accumulVal = 0;
}
}
}
} // loop end