MKR WIFI 1010 MKR Motor Carrier and IRremote.h

Nothing special, just an attempt to move a very simple vehicle with 2 DC motors and to control it through an Infrared Remote Control.

The issue is about the infrared ability to get the right code: with an high and random frequence the exadecimal codes that are received are erratic and it takes few seconds to the system to start again receiving one among “the right code”.

All in all, there is an issue regarding the Infrared Transmission.

Went through several messages and blogs and moved motors to 3 and 4 in order to avoid conflicts on timers between IRremote.h library and MKRMotorCarrier.h library but the erratic behaviour keeps on.

//version 02 includes IRRemote control first attempt
//modfica sketch originale per iniziare a montare motori su supporto lego giugno luglio 2019
// added one duty variable for each motor
// moved to motor 3 and 4 to see if it resolves conflicts with IRRemote
// IRremote.h is using Timer 2
//let see if it is the same situation reported for AFMotor.h that uses timer0 for motor 3 and 4

//**** remote controller buttons documentation
// 1 Y output -->brown cable
// 2 R vcc 3.3 5 volt -->red cable
// 3 G gnd ground -->black cable
// on off --> FFA25D --> 16753245
// MENU --> FFE21D --> 16769565
// TEST --> FF22DD --> 16720605
// + --> FF02FD --> 16712445
// freccia back --> FFC23D --> 16761405
// FrecceSx --> FFE01F --> 16769055
// FrecciaPlay --> FFA857 --> 16754775
// FrecceDx --> FF906F --> 16748655
// 0 --> FF6897 --> 16738455
// - --> FF9867 --> 16750695
// C --> FFB04F --> 16756815
// 1 --> FF30CF --> 16724175
// 2 --> FF18E7 --> 16718055
// 3 --> FF7A85 --> 16743045
// 4 --> FF10EF --> 16716015
// 5 --> FF38C7 --> 16726215
// 6 --> FF5AA5 --> 16734885
// 7 --> FF42BD --> 16728765
// 8 --> FF4AB5 --> 16730805
// 9 --> FF52AD --> 16732845
//*** end of remote controller buttons documentation


//***MotorCarrier***    
#include <MKRMotorCarrier.h>
#define INTERRUPT_PIN 6
static int batteryVoltage;//Variable to store the battery voltage
static int dutyM3= 0;//Variable to change the motor speed and direction
static int dutyM4= 0;//Variable to change the motor speed and direction

//***IRRemote
#include <IRremote.h>
int RECV_PIN=7; //infrared receiving pin
IRrecv irrecv(RECV_PIN); //create a class object used to receive class
decode_results results; //create a decoding result class object
unsigned long int ReceivedValue=0;//set a variable to store received value. On this variable the controlling logic should be set


void setup() 
{
  //***MotorCarrier***    
  //Serial port initialization
  Serial.begin(9600);
  while (!Serial);

  //Establishing the communication with the motor shield
  if (controller.begin()) 
    {
      Serial.print("MKR Motor Shield connected, firmware version ");
      Serial.println(controller.getFWVersion());
    } 
  else 
    {
      Serial.println("Couldn't connect! Is the red led blinking? You may need to update the firmware with FWUpdater sketch");
      while (1);
    }
  // Reboot the motor controller; brings every value back to default
  Serial.println("reboot");
  controller.reboot();
  delay(500);
  //Take the battery status
  float batteryVoltage = (float)battery.getConverted();
  Serial.print("Battery voltage: ");
  Serial.print(batteryVoltage);
  Serial.print("V, Raw ");
  Serial.println(battery.getRaw());

//***IRRemote
Serial.println("Ready for getting IR commands"); // print the string ready
  irrecv.enableIRIn();// starts the receiver Begin the receiving process. This will enable the timer interrupt which consumes a small amount of CPU every 50 µs.
  
}


void loop() {
   //Take the battery status
  float batteryVoltage = (float)battery.getConverted();
  
  //Reset to the default values if the battery level is lower than 11V
  if (batteryVoltage < 5) 
  {
    Serial.println(" ");
    Serial.println("WARNING: LOW BATTERY");
    Serial.println("ALL SYSTEMS DOWN");
    //M1.setDuty(0);
    //M2.setDuty(0);
    M3.setDuty(0);
    M4.setDuty(0);
    while (batteryVoltage < 5) 
    {
      batteryVoltage = (float)battery.getConverted();
    }
  }
  else //put all the controlling logic at work unless there is the low battery condition tested before
  {

if (irrecv.decode(&results)){ //waiting for decoding or maybe receiving this is the most relevant codeline. 
  //Attempt to receive a IR code. Returns true if a code was received, or false if nothing received yet. When a code is received, information is stored into "results".
if (results.value == 0XFFFFFFFF)
          results.value = ReceivedValue;
      Serial.println(results.value, HEX); //print out the decoded results
 // ReceivedValue = (results.value);
 // Serial.print ("Valore salvato = ");
 // Serial.println (ReceivedValue);
//switch (ReceivedValue){ //set duty according with received IR value
  switch (results.value){ //set duty according with received IR value directly with the value got from IR
    
//  case 16753245: //OnOff pressed button
  case 0xFFA25D: //OnOff pressed button exadecimal
  dutyM3= 24; //start with low speed since M3 seems stronger than M4
  dutyM4= 30; //start with low speed
  break;

//  case 16769565: //MENU pressed button
  case 0xFFE21D: //MENU pressed button 
  dutyM3= 0; //turn off motors
  dutyM4= 0; //turn off motors
  break;
  
//case 16761405: //back arrow pressed button 
case 0xFFC23D : //back arrow pressed button
  dutyM3= - dutyM3; //reverts duty and therefore direction
  dutyM4= -dutyM4; //reverts duty and therefore direction
  break;
  
//case 16769055: //LEFT arrows pressed button 
  case 0xFFE01F: //LEFT arrows pressed button 
  dutyM3= (dutyM3-2); //slowerM3 fasterM4
  dutyM4= (dutyM4+2); //slowerM3 fasterM4
  break;
  
  // case 16748655: //RIGHT arrows pressed button 
  case 0xFF906F: //RIGHT arrows pressed button 
  dutyM3= (dutyM3+2); //slowerM3 fasterM4
  dutyM4= (dutyM4-2); //slowerM3 fasterM4
  break;
  
  //case 16712445: //+ pressed button 
  case 0xFF02FD: //+ pressed button 
  dutyM3= (dutyM3+2); //fasterM3 fasterM4
  dutyM4= (dutyM4+2); //fasterM3 fasterM4
  break;
  
  // case 16750695: //- pressed button 
  case 0xFF9867: //- pressed button 
  dutyM3= (dutyM3-2); //slowerM3 slowerM4
  dutyM4= (dutyM4-2); //slowerM3 slowerM4
  break;
}
  
Serial.print("Motor Duty M3: ");
Serial.println(dutyM3);
Serial.print("Motor Duty M4: ");
Serial.println(dutyM4);

M3.setDuty(dutyM3);//set Motor1 speed
M4.setDuty(dutyM4); //set Motor4 speed

delay(100); 
ReceivedValue = results.value;
irrecv.resume(); //receive the next value

controller.ping();//Keep active the communication between MKR1000 and  MKRMotorCarrier. Ping the samd11. Not sure about the real usefulness
}//end of wait for an IR information
}//end of else it means that it goes up and stops since the battery level is lower than the check
}//end of the loop