Go Down

Topic: Code running on Uno doesn't run on Mega (Read 2228 times) previous topic - next topic

haritha2000

Hi, the code posted below runs perfectly on UNO, but the loop only runs for twice or thrice (figured this out by printing out "TEST" on the Serial Monitor) on the Arduino mega. Someone can tell me what's wrong with this? It's a 4wd robot which runs on RF Joystick. The circuit has a RF receiver connected to digital pin 2. Also, I noticed that when all the functions are removed from the loop, it runs perfectly.

Code: [Select]
#include <VirtualWire.h>
#include <AFMotor.h>
#include <NewPing.h>
int RF_RX_PIN = 2;
void(* resetFunc) (void) = 0; 
int servopin=9;
#define TRIGGER_PIN  11 
#define ECHO_PIN     12 
#define MAX_DISTANCE 200
AF_DCMotor rb(4);
AF_DCMotor lb(3);
AF_DCMotor rf(1);
AF_DCMotor lf(2);
unsigned long t=1000;
  int xh,xl,yh,yl;
  uint8_t z;
  uint8_t button;
long duration, cm, inches;
String data;
void setup()
{
  Serial.begin(9600);
  vw_set_rx_pin(RF_RX_PIN);  // Setup receive pin.
  vw_setup(2000); // Transmission speed in bits per second.
  vw_rx_start(); // Start the PLL receiver.
  pinMode(servopin,OUTPUT);
  pinMode(13,OUTPUT);
  rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  digitalWrite(13,HIGH);
}
uint8_t buffer[VW_MAX_MESSAGE_LEN]; // buffer array for data recieve over serial port
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int x=0;
int y=0;
int right_prox;
int front_prox;
int left_prox;
int state=2;
void loop()
{
  Serial.println("TEST");
  if(vw_get_message(buffer, &buflen)) // non-blocking I/O
  {
    decode();
  if ((x==0 && y==0) || z==1){rstop();}
  else {
  Serial.print(x);
  Serial.print(" ");
  Serial.println(y);
  godirection(x,y);
  }
  }else{
    state=2;
    rstop();
  }
}
void decode()
{
  if((buffer[0]!=0x7E)||(buffer[4]!=0xEF))
  {
  resetFunc();
  }
  uint8_t i = 0;
  x = buffer[1]<<2;
  y = buffer[2]<<2;
  z = buffer[3]>>3;
  button = buffer[3]&0x07;
   if (x>600){
    x=1;
  }else if (x<=600 && x>=400){x=0;}
  else {x=-1;}
  if (y>600){
    y=1;
  }else if (y<=600 && y>=400){y=0;}
  else {y=-1;}
}

void clearBufferArray()              // function to clear buffer array
{
  for (int i=0; i<VW_MAX_MESSAGE_LEN;i++)
    { buffer[i]=0;}                  // clear all index of array with command NULL
}
void delayh(long interval){
  unsigned long prev_time=millis();
  unsigned long current_time=millis();
  while ((current_time-prev_time)<interval){
    current_time=millis();
  }
}
void godirection(int x,int y) {
     if (x==0){
      if (y==1){forward();}
      else if (y==0){rstop();}
      else if (y==-1){backward();}
     }
     else if (x==1){
      if (y==1){srf();}
      else if (y==0){right();}
      else if (y==-1){srb();}
     }
     else if (x==-1){
      if(y==1){slf();}
      else if (y==0){left();}
      else if (y==-1){slb();}
     }
}
void rstop (){
  if (state==0){
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
  delay(75);
  rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
  state=2;
}
else if (state==1){
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
  delay(75);
  rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
  state=2;
}
else if (state==2){
    rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
}
}
void forward(){
  state=1;
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void backward(){
  state=0;
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void right(){
  state=2;
  rf.run(BACKWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void left(){
  state=2;
  lf.run(BACKWARD);rf.run(FORWARD);rb.run(FORWARD);lb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void srf(){
  state=1;
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
}
void srb(){
  state=0;
  Serial.println("SRB");
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
}
void slf(){
  state=1;
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
}
void slb(){
  state=0;
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
}

TheMemberFormerlyKnownAsAWOL

Your code needs more
1) line breaks
2) Serial prints
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

haritha2000

#2
Nov 16, 2019, 03:29 am Last Edit: Nov 16, 2019, 03:34 am by haritha2000
Here you go. Sorry for the bloated up code
Also, as my suspicion that the board is not functioning properly, I tried uploading other programs to the MEGA and they run flawlessly. Including the "ESP8266 as a shield controlled using the Blynk app version" of this code.
Code: [Select]
#include <VirtualWire.h>
#include <AFMotor.h>
int RF_RX_PIN = 2;// RF signal from joystick
void(* resetFunc) (void) = 0; 
AF_DCMotor rb(4);//means rightside,back wheel
AF_DCMotor lb(3);//leftside, back wheel
AF_DCMotor rf(1);
AF_DCMotor lf(2);
  int xh,xl,yh,yl;
  uint8_t z;
  uint8_t button;

void setup()
{
  Serial.begin(9600);
  vw_set_rx_pin(RF_RX_PIN);  // Setup receive pin.
  vw_setup(2000); // Transmission speed in bits per second.
  vw_rx_start(); // Start the PLL receiver.
  pinMode(servopin,OUTPUT);
  pinMode(13,OUTPUT);
  rf.run(RELEASE);
  lf.run(RELEASE);
  lb.run(RELEASE);
  rb.run(RELEASE);
  digitalWrite(13,HIGH);
}

uint8_t buffer[VW_MAX_MESSAGE_LEN]; // buffer array for data recieve over serial port
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int x=0;
int y=0;
int state=2;

void loop()
{
  Serial.println("TEST");

  if(vw_get_message(buffer, &buflen)) // non-blocking I/O
  {

    Serial.println("Decoding...");
    decode();


  if ((x==0 && y==0) || z==1){rstop();}

  else {

  Serial.println("Robot Moves");
  Serial.print(x);
  Serial.print(" ");
  Serial.println(y);
  godirection(x,y);

  }

  }
else{

    state=2;
    rstop();

  }
}

void decode()
{
  if((buffer[0]!=0x7E)||(buffer[4]!=0xEF))
  {
  resetFunc();
  }
  uint8_t i = 0;
  x = buffer[1]<<2;
  y = buffer[2]<<2;
  z = buffer[3]>>3;
  button = buffer[3]&0x07;
   if (x>600){
    x=1;
  }else if (x<=600 && x>=400){x=0;}
  else {x=-1;}
  if (y>600){
    y=1;
  }else if (y<=600 && y>=400){y=0;}
  else {y=-1;}
}

void clearBufferArray()              // function to clear buffer array
{
  for (int i=0; i<VW_MAX_MESSAGE_LEN;i++)
    { buffer[i]=0;}                  // clear all index of array with command NULL
}
void godirection(int x,int y)
{
     if (x==0){

      if (y==1){forward();}
      else if (y==0){rstop();}
      else if (y==-1){backward();}

     }

     else if (x==1){

      if (y==1){srf();}
      else if (y==0){right();}
      else if (y==-1){srb();}

     }

     else if (x==-1){

      if(y==1){slf();}
      else if (y==0){left();}
      else if (y==-1){slb();}

     }
}

void rstop (){

  Serial.println("STOP");
  if (state==0){
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
  delay(75);
  rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
  state=2;

}

else if (state==1){

  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
  delay(75);
  rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
  state=2;
}

else if (state==2){

    rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
  rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);

}

}

void forward(){

  state=1;
  Serial.println("FORWARD");
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);

}

void backward(){

  Serial.println("BACKWARD");
  state=0;
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);

}

void right(){

  Serial.println("RIGHT");
  state=2;
  rf.run(BACKWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);

}

void left(){

  Serial.println("LEFT");
  state=2;
  lf.run(BACKWARD);rf.run(FORWARD);rb.run(FORWARD);lb.run(BACKWARD);
  rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);

}

void srf(){//srf means slanted right forward

  Serial.println("SRF");
  state=1;
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);

}

void srb(){

  state=0;
  Serial.println("SRB");
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);

}

void slf(){

  Serial.println("SLB");
  state=1;
  rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
  lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);

}

void slb(){

  Serial.println("SLB");
  state=0;
  rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
  lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);

}

krupski

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

krupski

Hi, the code posted below runs perfectly on UNO, but the loop only runs for twice or thrice (figured this out by printing out "TEST" on the Serial Monitor) on the Arduino mega. Someone can tell me what's wrong with this? It's a 4wd robot which runs on RF Joystick. The circuit has a RF receiver connected to digital pin 2. Also, I noticed that when all the functions are removed from the loop, it runs perfectly.
Do any of the libraries you load use an interrupt? The interrupt capable pins and numbers differ between the 328p and the 2560.  You may need to tell a library which AVR you are using or modify the library code to use the proper pins.

Also I assume you are compiling and loading your code. If you just try to take a .hex file compiled for one board and try to load it into a different kind of board, chances are it won't work.
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

TheMemberFormerlyKnownAsAWOL

How does that help the OP?
1) it renders the code legible
2) it helps to show the flow of the code

(Seriously?)
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

haritha2000

#6
Nov 17, 2019, 02:38 am Last Edit: Nov 17, 2019, 04:51 am by haritha2000
Do any of the libraries you load use an interrupt? The interrupt capable pins and numbers differ between the 328p and the 2560.  You may need to tell a library which AVR you are using or modify the library code to use the proper pins.

Also I assume you are compiling and loading your code. If you just try to take a .hex file compiled for one board and try to load it into a different kind of board, chances are it won't work.
I recognized that when I remove the following command
Code: [Select]
vw_setup(2000);

which is to set up the bit rate and also initialize, the code runs perfectly but the virtual wire becomes useless because I removed the code that initializes the rf receiving. however, much less complex codes such as the example receiver code in the library runs smoothly on the mega. but when I add other lengthy functions which I need the robot car to function, the same thing happens again. I know that the functions are not to blame because they run on the UNO perfectly. I know my code is a bit lengthy but it would be a big help if you guys could help me. I even tried using a different version of the virtual wire library but I got the same results.
And I don't really understand to modify the library to use proper pins so, it would be a big help if you can further explain.
Further, I checked if there is a usage in interrupt pins but I couldn't find any. So please help.
Thank you very much.

haritha2000

I did a lot of research and noticed that the two libraries' are trying to use the same timer of something. Can someone tell me how to prevent the two libraries from clashing or to have a work around for that.
I'm using a L293D motor driver shield, so I cannot run the motors without the AFMotor library.

cattledog

Quote
I did a lot of research and noticed that the two libraries' are trying to use the same timer of something. Can someone tell me how to prevent the two libraries from clashing or to have a work around for that.
What exactly does the error message say.

You will need to understand which timer is in conflict. Many libraries let you change the timer they use so you will need to do a little poking around in the library documentation or source code to see if that is possible.

haritha2000

What exactly does the error message say.

You will need to understand which timer is in conflict. Many libraries let you change the timer they use so you will need to do a little poking around in the library documentation or source code to see if that is possible.
there is no error message... the serial monitor which is supposed to print "TEST" just stop running after second time. in the first time, it prints the whole "TEST" but in the second or third time, it stops after printing "TE" or something like that, it never stops with the complete code.

cattledog

I think the issue is with the use of Timer1 by both VirtualWire and the PWM1 output for the motor shield.

I have seen there are ways to force VW to use Timer2, but I'm not clear how to do it. It might be easier to switch to RadioHead ASK where there is a simple switch at the start of RH_ASK.cpp
Code: [Select]
// RH_ASK on Arduino uses Timer 1 to generate interrupts 8 times per bit interval
// Define RH_ASK_ARDUINO_USE_TIMER2 if you want to use Timer 2 instead of Timer 1 on Arduino
// You may need this to work around other librraies that insiston using timer 1
//#define RH_ASK_ARDUINO_USE_TIMER2


It may also be possible to change the PWM1 output to a different timer in AFMotor.cpp.
You could move the Timer1 pwm to Timer5, or possible use two outputs on Timer4 like the library does on Timer3.

You might also consider puchasing a V2 motor shield. I believe that is uses an onboard pwm driver.

Good luck.

haritha2000

Thank you very much for your help. I will try to use the Radiohead library. By the way, I still don't understand why it would work perfectly or UNO.. does it use a different method from the mega?

cattledog

Take a look at the AFMotor library. The Uno uses Timer 2 and Timer 0 for pwm to the motors.

krupski

#13
Nov 25, 2019, 10:18 pm Last Edit: Nov 25, 2019, 10:20 pm by krupski
Thank you very much for your help. I will try to use the Radiohead library. By the way, I still don't understand why it would work perfectly or UNO.. does it use a different method from the mega?
https://forum.arduino.cc/index.php?topic=648297.msg4373929#msg4373929

Read the first paragraph. Why do I even bother?
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Go Up