softwareserial cant read

i am using softwareserial to read data from electronic compass, and i cant use the hardware serial which is connected to other device.

lets show u guys my program first:

#include <SoftwareSerial.h>

SoftwareSerial compass(8,9);

//other variable

void setup()
{
attachInterrupt(0, count_pulse_left, RISING);
attachInterrupt(1, count_pulse_right, RISING);
pinMode(8,INPUT);
pinMode(9,OUTPUT);
digitalWrite(9,HIGH);
compass.begin(9600);
val_x[3] = ‘\0’;
val_y[3] = ‘\0’;
angle[3] = ‘\0’;
}

void loop()
{
Serial.begin(115200);
//some codes here for the hardware serial communication

cal_path();
}

void motor1(int high_low2, int pwm2)
{
digitalWrite(EN2,high_low2);
analogWrite(IN2,pwm2);
}

void motor2(int high_low1, int pwm1)
{
digitalWrite(EN1,high_low1);
analogWrite(IN1,pwm1);
}

void count_pulse_left()
{
encoder0count++;

}

void count_pulse_right()
{
encoder1count++;
}

void cal_path()
{
//some calculations here

robot_turn(); //control how much the robot should turn

compass_check();

robot_forward(); //move the robot forward

//and both robot_turn() and robot_forward call motor1()/motor2() to control the robot
}

void compass_check()
{
compass.print((byte)0x2A); //
compass.print((byte)0x50); // acquire data from electronic compass

for(int i=0;i<11;i++) // to acquire an angle reading from the compass, 11 bytes of data is obtained from the compass
{
compass_data = compass.read();

if(i>2&&i<6)
{
angle[i-3] = compass_data; // the angle reading is at the 4th - 6th byte
}
delay(1);
}
angle_2 = atoi(angle);

Serial.print(angle_2);
}

the problem is after the robot turns, angle_2 doesnt shows on the serial monitor, and the robot doesnt move forward.
if i comment robot_turn(); and robot_forward(); ,the program works well and keeps showing angle_2 on the serial monitor.
it seems that if motor1()/motor2() runs before compass.read(), the program just stop, its my observation when i modify the program like this:

void compass_check()
{
compass.print((byte)0x2A); //
compass.print((byte)0x50); // acquire data from electronic compass

Serial.print(“test”);

for(int i=0;i<11;i++)
{

compass_data = compass.read();

if(i>2&&i<6)
{
angle[i-3] = compass_data;
}
delay(1);
}
angle_2 = atoi(angle);

Serial.print(angle_2);
}

“test” is shown on the serial monitor but angle_2 is not shown.

wt makes me more confused is that the following program works…

//All the variables, sub-functions are the same as the above program

void loop()
{ Serial.begin(115200);

motor1(LOW,180);
delay(1000);
motor1(LOW,0);

compass_check();

motor1(LOW,180);
motor2(LOW,180);
delay(1000);

delay(100);
}

everytime it finishs turning, it shows angle_2 on the serial monitor, and then move forward.

so why the softwareserial doesnt work(cant read) in the first program(which is a very long program, about 500 lines, but i guess it has nothing to do with the length of the program)?

The standard software serial is purely polling on receive, so if it isn't listening at the right time it misses stuff . You'd be a lot better using newsoftserial : NewSoftSerial | Arduiniana which does interrupt listening.

pluggy:
The standard software serial is purely polling on receive, so if it isn't listening at the right time it misses stuff . You'd be a lot better using newsoftserial : NewSoftSerial | Arduiniana which does interrupt listening.

i tried newsoftseria b4, the motors counldnt move.
i put serial.print at differnent position and tried to debug it
i found that the program cant even reach the first line of cal_path() when i used newsoftserial

Am I missing a compass.begin() statement somewhere?

What pins are the motors using? What kind of motors are they?

PaulS:
Am I missing a compass.begin() statement somewhere?

What pins are the motors using? What kind of motors are they?

i use 5,6,7,8 pins for the two servo motors
and i'm using this motor drive:
http://www.droboticsonline.com/index.php/arduino-motor-drive-shield.html

SoftwareSerial compass(8,9);

i use 5,6,7,8 pins for the two servo motors

I see a conflict here.

PaulS:

SoftwareSerial compass(8,9);

i use 5,6,7,8 pins for the two servo motors

I see a conflict here.

:)thx
I change the pins from 8,9 to 10,11 now, but the program still stop at compass.read() after the motors move :roll_eyes:.

I'd suggest using two non-PWM pins for the software serial port.

PaulS:
I’d suggest using two non-PWM pins for the software serial port.

i change it to 12&13, still cant get it works =(
simple code like this is work:

void loop()
{
robot_turn(false,90);

Serial.print((byte)0x2A);
Serial.print((byte)0x50);

for(int i=0;i<11;i++)
{
compass_data = Serial.read();
if(i>2&&i<6)
{
angle[i-3] = compass_data;
}
}
angle_2 = atoi(angle);
Serial.println(angle_2);
}

i just cant make it works when i call compass_check() in cal_path(). Nothing special in cal_path(), just have about 160 lines of codes to calculate the degree the robot need to turn, which are not related to any interrupt/PWM/hardware or software serial communication, it’s just math. then i check whether the degree is positive or negative, which decides which way should the robot turn. Then i call compass_check to check whether the robot turn too much, or not enough.Finally, i told it to move forward.