Below is the code which can run in both UNO and Mega. You can find it is success in UNO but failed in Mega when 'C' is received every 100 ms. I would like to know why I get this result although I can solve the problem using serial port connection directly.
#include <Wire.h>
#include <NewPing.h>
#define SONAR_NUM 3 // Number of Sonar
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping
/*NewPing sonar[SONAR_NUM] = { // Ultrasonic Sensor Object array
NewPing(13, 12, MAX_DISTANCE),
NewPing(11, 10, MAX_DISTANCE),
NewPing(9, 8, MAX_DISTANCE)
};*/
uint8_t i;
char inbyte; // command byte received from Rpi (Serial 1)
String sid; // String of Ultrasonic sensor id
String dist; // String of distance value
String outpackage; // String sent to rpi via Serial 1
String irsensor; // String of ir sensor id
String irstate; // ir sensor state
// unsigned int iteration;
unsigned int duration;
unsigned int distance;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
// Serial1.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
inbyte = ' ';
if (Serial.available() > 0){
inbyte = Serial.read();
}
if (inbyte == 'C'){
for (i = 0; i < SONAR_NUM; i++){
// delay(10);
/* sid = String(i + 1);
duration = sonar[i].ping();
distance = (duration/2)*0.0343;
distance = sonar[i].ping_cm();
dist = String(distance);
outpackage = "u"+sid+" "+dist+"\n";
Serial.print(outpackage);
Serial1.print(outpackage);*/
sid = String(i);
Serial.print(sid);
}
Serial.print("E\n");
} else if (inbyte == ' '){
// do nothing
} else {
Serial.write(inbyte);
// Serial1.write(inbyte);
}
}
I changed the test sketch a little, to show you a different way of producing the same output.
The sketch times the for loop, and changes the way to operate when a 'x' is received.
#include <Wire.h>
#include <NewPing.h>
#define SONAR_NUM 3 // Number of Sonar
uint8_t i;
char inbyte; // command byte received from Rpi (Serial 1)
String sid; // String of Ultrasonic sensor id
String dist; // String of distance value
String outpackage; // String sent to rpi via Serial 1
String irsensor; // String of ir sensor id
String irstate; // ir sensor state
unsigned int distance;
void setup() {
Serial.begin(115200);
}
bool noString = true;
void loop() {
if (Serial.available() > 0) {
inbyte = Serial.read();
if (inbyte == 'C') {
uint32_t start = micros();
for (i = 0; i < SONAR_NUM; i++) {
distance = random(0, 400);
if (noString) {
Serial.write('u');
Serial.print(i + 1);
Serial.write(' ');
Serial.println(distance);
} else {
sid = String(i + 1);
dist = String(distance);
outpackage = "u" + sid + " " + dist + "\n";
Serial.print(outpackage);
}
}
uint32_t dur = micros() - start;
Serial.print("E ");
Serial.print(dur);
Serial.println(" us");
} else if (inbyte == 'x') {
noString = !noString;
} else if (inbyte != ' ') {
Serial.write(inbyte);
}
}
}
I changed the processing sketch to send 'Cx' so each 'scan' switches the method.
u1 244
u2 158
u3 96
E 1004 us
u1 371
u2 264
u3 360
E 1476 us
u1 198
u2 351
u3 340
E 1060 us
u1 103
u2 351
u3 1
E 1436 us
u1 5
u2 280
u3 18
E 916 us
u1 74
u2 49
u3 13
E 1376 us
u1 120
u2 225
u3 12
E 1004 us
Using Strings cost you about 400 us per scan, which makes it 40% slower.
I think the non String code is a lot cleaner and does not need any additional variables.