robo_body.ino.
sketch robo_body.ino.
#include <EEPROM.h> ... const int IR_TOTAL_COMMANDS = 17; // Total Number of commands, that can be send by IR control unsigned long IrCommands[IR_TOTAL_COMMANDS]; // All command from remote control // Read all IR commands from EEPROM for(int i=0; i<sizeof(IrCommands); i++) { *((byte*)&IrCommands + i) = EEPROM.read(i); }
irrecv.decode(&results);
returns the button code in results.value
if the button was just clicked. If the button was pressed and held, the button code is sent, and then IR_COMMAND_SEPARATOR = 0xFFFFFFFF
sent at a certain frequency until the button is released. Thus, we define the duration of pressing - fast IrRemoteButtonState = 1
, short IrRemoteButtonState = 2
- one IR_COMMAND_SEPARATOR
came after the command, and a long IrRemoteButtonState = 3
- two or more IR_COMMAND_SEPARATOR
.CheckIrCommands()
function is called from the main loop()
. // Check if any IR remote buttons pressed void CheckIrCommands() { // If we're in programm mode, just check if buttons vere pressed there if(IsInIrProgrammMode) { IrProgrammatorProcess(); return; } if (irrecv.decode(&results)) { // Button was pressed for LONG or SHORT time, but not VERY SHORT ) if(results.value==IR_COMMAND_SEPARATOR) { if(IrRemoteButtonState<3) { // Set the IR remote button state IrRemoteButtonState++; } // Update last pressed button state IrLastCommandsState[0] = IrRemoteButtonState; }else { IrRemoteLastCommand = results.value; IrRemoteButtonState = 1; // Saving last pressed buttons and their state - we will use it to determine when to start IR programmator. for(int i=IR_LAST_COMMANDS_BUFFER_SIZE-1; i>0; i--) { IrLastCommandsState[i] = IrLastCommandsState[i-1]; IrLastCommandsValue[i] = IrLastCommandsValue[i-1]; } IrLastCommandsValue[0] = IrRemoteLastCommand; IrLastCommandsState[0] = 2; // For programmator mode short and very short press of the button is equal. checkIrHit(); // Check if robot was hit by another robot } ProcessIrCommands(); irrecv.resume(); } }
ProcessIrCommands()
function determines which of the known keys has been pressed and executes the corresponding command. void ProcessIrCommands() { if(IrRemoteLastCommand==0) return; // The signal was not good enough to get the signal data // Check for known commands and executing them for(int i=0; i<IR_TOTAL_COMMANDS; i++) { if(IrCommands[i]==IrRemoteLastCommand) { executeIrCommand(i); return; } } // We recieved unknown command. Let's check if we need to enter in programmator mode. (Same button should be pressed in the following order: LONG->SHORT->LONG->SHORT if((IrLastCommandsValue[0]==IrLastCommandsValue[1])&&(IrLastCommandsValue[0]==IrLastCommandsValue[2])&&(IrLastCommandsValue[0]==IrLastCommandsValue[3]) &&(IrLastCommandsState[0]==2)&&(IrLastCommandsState[1]==3)&&(IrLastCommandsState[2]==2)&&(IrLastCommandsState[1]==3)) { // Starting Programmator mode. IrServoStep = IR_SERVO_STEP_PROGRAM_MODE; // Maximun step for Programm mode, so that user will notice servo movement IsInIrProgrammMode = true; IrProgrammatorStep = 0; executeIrCommand(0); // Executing command and waiting for user to press the button to save it. } }
void executeIrCommand(int cmd) { switch(cmd) { case 0: // move forward moveMotor( "G", IR_MOVE_SPEED ); break; case 1: // move backwards moveMotor( "G", -IR_MOVE_SPEED ); break; case 2: // turn left moveMotor( "L", -IR_MOVE_SPEED ); moveMotor( "R", IR_MOVE_SPEED ); break; case 3: // turn right moveMotor( "L", IR_MOVE_SPEED ); moveMotor( "R", -IR_MOVE_SPEED ); break; case 4: //stop moveMotor( "G", 0 ); break; case 5: // Move Horizontal Head Left moveHead( "H", servoHeadHorizontal.read()-IrServoStep ); break; case 6: // Move Horizontal Head Right moveHead( "H", servoHeadHorizontal.read()+IrServoStep ); break; case 7: // Move Vertical Head Up moveHead( "V", servoHeadVertical.read()-IrServoStep ); break; case 8: // Move Vertical Head Down moveHead( "V", servoHeadVertical.read()+IrServoStep ); break; case 9: //no noSwinger.startSwing(90, 1, 400, 2.5, 60, 0.75, true); break; case 10: //yes yesSwinger.startSwing(60, 1, 400, 2.5, 30, 0.8, true); break; case 11: //tail tailSwinger.startSwing(90, 1, 250, 6, 70, 0.9, true); break; case 12: // Mood executeAction("M", 0x0102, true ); break; case 13: // Mood executeAction("M", 0x0103, true ); break; case 14: // Mood executeAction("M", 0x0104, true ); break; case 15: // Mood executeAction("M", 0x0105, true ); break; case 16: // Mood executeAction("M", 0x0106, true ); break; } }
void IrProgrammatorProcess() { if (irrecv.decode(&results)) { if((results.value!=IR_COMMAND_SEPARATOR)&&(results.value!=0)&&(results.value!=IrLastCommandsValue[0])) { IrCommands[IrProgrammatorStep]=results.value; if(IrProgrammatorStep==IR_TOTAL_COMMANDS-1) // Was it the last command? { // Save all IR commands to EEPROM for(int i=0; i<sizeof(IrCommands); i++) { EEPROM.write(i, *((byte*)&IrCommands + i) ); } IsInIrProgrammMode = false; IrServoStep = IR_SERVO_STEP_DEFAULT; executeIrCommand(2); // Tell the user that we finished programm mode }else { executeIrCommand(++IrProgrammatorStep); } } irrecv.resume(); } }
Source: https://habr.com/ru/post/168197/
All Articles