I am building a robot with multiple sensors, abilities etc. Since I had a bug with a HC-SR04 rotated by a servo, I experimented in a different sketch. If the distance is less than 30cm, the servo turns left and right. Since I need continuous readings of other sensors, I cannot use delays so I used millis in order to keep time. The sensor worked correctly in a different sketch, but something in the full one conflicts with it.
#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <Servo.h>
#include <IRremote.h>
RTC_DS1307 rtc;
/*const int blue2 = 12;
const int blue1 = 11;
const int red1 = 10;
const int red2 = 9;
*/
Servo servo;
byte leds[4] = {8, 7, 6, 9};
const int STBY1=45;
const int ain11=47;
const int ain12=43;
const int aPWM1=2;
const int bin11=41;
const int bin12=40;
const int bPWM1=4;
const int STBY2 = 39;
const int ain21=33;
const int ain22=31;
const int aPWM2=5;
const int bin21=35;
const int bin22=37;
const int bPWM2=3;
const int piezo = 32;
const int flamePin = A7;
int flameState;
const int photoResistor = A1;
int photoState;
const int temp = A2;
float temperature;
int ledAnalog;
const int irGnd = 52;
const int irVcc = 50;
const int irSignal = 48;
decode_results results;
IRrecv irrecv(irSignal);
boolean manualLeds = false;
boolean ledsOn = false;
unsigned long counter;
unsigned long prevMillis = 0;
int piezoInterval = 200;
int drivingMode = 0;
boolean playPiezo=false;
#define trig 22
#define echo 24
long duration;
boolean turned150 = false;
int cm30, cm, cm150;
bool checkLeft = false;
boolean checkRight = false;
boolean mainPing = true;
unsigned long servoTimer = millis();
void setup(){
Wire.begin();
rtc.begin();
pinMode(piezo, OUTPUT);
pinMode(STBY1, OUTPUT);
pinMode(aPWM1, OUTPUT);
pinMode(ain11, OUTPUT);
pinMode(ain12, OUTPUT);
pinMode(bPWM1, OUTPUT);
pinMode(bin11, OUTPUT);
pinMode(bin12, OUTPUT);
pinMode(STBY2, OUTPUT);
pinMode(aPWM2, OUTPUT);
pinMode(ain21, OUTPUT);
pinMode(ain22, OUTPUT);
pinMode(bPWM2, OUTPUT);
pinMode(bin21, OUTPUT);
pinMode(bin22, OUTPUT);
servo.attach(12);
for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
pinMode(leds[i], OUTPUT);
}
pinMode(flamePin, INPUT);
pinMode(photoResistor, INPUT);
pinMode(temp, INPUT);
pinMode(irGnd, OUTPUT);
digitalWrite(irGnd, LOW);
pinMode(irVcc, OUTPUT);
digitalWrite(irVcc, HIGH);
pinMode(irSignal, INPUT);
Serial.begin(9600);
irrecv.enableIRIn();
digitalWrite(STBY1, LOW);
digitalWrite(STBY2, LOW);
servo.write(90);
delay(200);
}
void loop(){
counter=millis();
//Serial.print("Millis1: ");
//Serial.println(millis());
if(irrecv.decode(&results)){
translateIR();
irrecv.resume();
}
// Serial.print("Millis2: ");
//Serial.println(millis());
if(drivingMode == 1){
if(((counter-servoTimer) >= 150) && mainPing){
ping();
cm=duration/29.1/2;
Serial.println(cm);
counter=millis();
servoTimer=counter;
}
if((cm<30) && mainPing){
mainPing=false;
checkRight = true;
counter=millis();
servoTimer=millis();
servo.write(150);
cm=30;
}
if(checkRight && !checkLeft && ((counter-servoTimer) >= 170)){
ping();
checkLeft=true;
cm150 = duration/29.1/2;
counter=millis();
servoTimer=millis();
servo.write(50);
}
if(checkRight && checkLeft && ((counter-servoTimer) >= 340)){
checkRight=false;
checkLeft=false;
mainPing=true;
ping();
cm30 = duration/29.1/2;
counter=millis();
servoTimer=millis();
servo.write(90);
}
}
//getTime();
//existsFire();
/*if(!manualLeds){
readPhoto();
}*/
}
void readPhoto(){
photoState = analogRead(photoResistor);
if(photoState>600){
ledAnalog=0;
}
else if(photoState<300){
ledAnalog=255;
}
else{
ledAnalog = 150 - photoState/4;
}
for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
analogWrite(leds[x], ledAnalog);
}
}
void existsFire(){
flameState = analogRead(flamePin);
Serial.println(flameState);
if(flameState <= 50){
static boolean playingBuzzer = true;
if(counter - prevMillis > piezoInterval){
prevMillis = counter;
playingBuzzer=!playingBuzzer;
}
if(playingBuzzer){
digitalWrite(piezo, HIGH);
}
else{
digitalWrite(piezo, LOW);
}
}
else if(!playPiezo){
digitalWrite(piezo, LOW);
}
else if(playPiezo){
digitalWrite(piezo, HIGH);
}
}
void checkTemp(){
temperature = ((analogRead(temp) / 1024.0 * 5.0) - .5) * 100;
Serial.println(temperature);
}
void ping(){
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH);
}
void getTime(){
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void forward(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, HIGH);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 255);
digitalWrite(bin11, LOW);
digitalWrite(bin12, HIGH);
analogWrite(bPWM1, 234);
digitalWrite(STBY2, HIGH);
digitalWrite(ain21, LOW);
digitalWrite(ain22, HIGH);
analogWrite(aPWM2, 255);
digitalWrite(bin21, LOW);
digitalWrite(bin22, HIGH);
analogWrite(bPWM2, 234);
}
void backward(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, LOW);
digitalWrite(ain12, HIGH);
analogWrite(aPWM1, 255);
digitalWrite(bin11, HIGH);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 235);
digitalWrite(STBY2, HIGH);
digitalWrite(ain21, HIGH);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 255);
digitalWrite(bin21, HIGH);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 235);
}
void left(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, HIGH);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 255);
digitalWrite(bin11, HIGH);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 255);
digitalWrite(STBY2, HIGH);
digitalWrite(ain21, LOW);
digitalWrite(ain22, HIGH);
analogWrite(aPWM2, 255);
digitalWrite(bin21, HIGH);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 255);
}
void right(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, LOW);
digitalWrite(ain12, HIGH);
analogWrite(aPWM1, 255);
digitalWrite(bin11, LOW);
digitalWrite(bin12, HIGH);
analogWrite(bPWM1, 255);
digitalWrite(STBY2, HIGH);
digitalWrite(ain21, HIGH);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 255);
digitalWrite(bin21, LOW);
digitalWrite(bin22, HIGH);
analogWrite(bPWM2, 255);
}
void brake(){
digitalWrite(STBY1, LOW);
digitalWrite(ain11, LOW);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 0);
digitalWrite(bin11, LOW);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 0);
digitalWrite(STBY2, LOW);
digitalWrite(ain21, LOW);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 0);
digitalWrite(bin21, LOW);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 0);
}
void translateIR(){
//Serial.println(results.value, HEX);
switch(results.value){
case 0xFF02FD:
case 0x20DF22DD:
//stop(ok)
if(drivingMode==0){
brake();
//Serial.println("brake");
}
break;
case 0xFF629D:
case 0x20DF02FD:
//forward
if(drivingMode==0){
forward();
//Serial.println("forward");
}
break;
case 0x20DF827D:
case 0xFFA857:
//back
if(drivingMode==0){
backward();
//Serial.println("back");
}
break;
case 0xFF22DD:
case 0x20DFE01F:
//left
if(drivingMode==0){
left();
//Serial.println("left");
}
break;
case 0x20DF609F:
case 0xFFC23D:
//right
if(drivingMode==0){
right();
//Serial.println("right");
}
break;
case 0xFF6897:
case 0x20DF8877:
if(drivingMode==0){
brake();
drivingMode=1;
}
else{
brake();
servo.write(90);
drivingMode=0;
}
//1(switch driving mode)
break;
case 0xFF9867:
case 0x20DF48B7:
//2(switch led mode)
if(!manualLeds){
manualLeds=true;
for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
digitalWrite(leds[x], LOW);
}
}
else{
manualLeds=false;
}
break;
case 0xFFB04F:
case 0x20DFC837:
if(manualLeds){
if(!ledsOn){
for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
digitalWrite(leds[x], HIGH);
}
ledsOn=true;
}
else{
for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
digitalWrite(leds[x], LOW);
}
ledsOn=false;
}
}
//3(toggle leds if mode is on)
break;
case 0xFF30CF:
case 0x20DF28D7:
//4(play sound)
playPiezo = !playPiezo;
}
}
EDIT 2:
I decided to see what will happen if I start removing code. I removed most of the code that I did not need for this experiment. After the removal, the issue persisted. The sensor is still giving me 0s. This is all the code that was left after I removed stuff:
#include <Servo.h>
//RTC_DS1307 rtc;
/*const int blue2 = 12;
const int blue1 = 11;
const int red1 = 10;
const int red2 = 9;
*/
Servo servo;
unsigned long counter;
unsigned long prevMillis = 0;
int piezoInterval = 200;
int drivingMode = 0;
boolean playPiezo=false;
#define trig 22
#define echo 24
long duration;
boolean turned150 = false;
int cm30, cm, cm150;
bool checkLeft = false;
boolean checkRight = false;
boolean mainPing = true;
unsigned long servoTimer = millis();
void setup(){
servo.attach(12);
/* for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
pinMode(leds[i], OUTPUT);
}
*/
Serial.begin(9600);
servo.write(90);
delay(200);
}
void loop(){
counter=millis();
//Serial.print("Millis1: ");
//Serial.println(millis());
/* if(irrecv.decode(&results)){
translateIR();
irrecv.resume();
}*/
// Serial.print("Millis2: ");
if(drivingMode == 0){
if(((counter-servoTimer) >= 150) && mainPing){
ping();
cm=duration/29.1/2;
Serial.println(cm);
counter=millis();
servoTimer=counter;
}
if((cm<30) && mainPing){
mainPing=false;
checkRight = true;
counter=millis();
servoTimer=millis();
servo.write(150);
cm=30;
}
if(checkRight && !checkLeft && ((counter-servoTimer) >= 170)){
ping();
checkLeft=true;
cm150 = duration/29.1/2;
counter=millis();
servoTimer=millis();
servo.write(50);
}
if(checkRight && checkLeft && ((counter-servoTimer) >= 340)){
checkRight=false;
checkLeft=false;
mainPing=true;
ping();
cm30 = duration/29.1/2;
counter=millis();
servoTimer=millis();
servo.write(90);
}
}
//getTime();
//existsFire();
/*if(!manualLeds){
readPhoto();
}*/
delay(2);
}
//}
void ping(){
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH, 24000L);
}
Maybe this means that the issue is within this remaining code. Of course I will need all of the code that I removed for the final project, but I was just trying to debug.
I made my code a lot more concise since the posted code draft, but the ultrasonic sensor still gives me 0s. I do not understand what can affect its performance as it works fine in my other sketch.
I tried connecting the sensor to an external 5 volt power source and the same thing happened. The reason for the issue is not because if my power source.
I used to have a small delay at the end of my code and I removed that in order to make it run faster. Since pulseIn is blocking for 24ms, the delays do not affect it and it should work normally. But it does not.
Also, the sensor is giving 0s not because the target is too far away. Even if I put my hand close, it still gives 0s. If I make the cm equal 400 if the duration equals 0, the cm are always 400 regardless of the distance from the sensor.
delay()
is not the only blocking function:pulseIn()
is also blocking, andSerial.print()
becomes blocking is the output buffer fills up.pulseIn()
- it is needed for the sensor. Even if I removeSerial.print()
, it makes no difference to the servo and sensor.I cannot really avoid using pulseIn()
- Yes you can, easily.pulseIn
is just a blocking way of measuring the time between two events. You could use interrupts and not block.