Beginner Arduino loop function and variable - arduino

This is the revised code, the initial value is reading ridiculously high without the conversion!! How do I get the conversion to apply to the initialTemp as well temperatureC?
The code you have helped with as far as I can tell is exactly what I was trying to achieve, but obviously.
Thanks again!!
int pin_tempRead = 0; // temperature sensor pin
int coolLED = 2; // cooling LED digital pin
int heatLED = 3; // heating LED digital pin
float initialTemp;
float cutOffTemp = 30; //cut off temperature = 30°C
void setup()
{
Serial.begin(9600); //Start the serial connection with the computer
pinMode(heatLED, OUTPUT); //initialise as OUTPUT
pinMode(coolLED, OUTPUT); //initialise as OUTPUT
initialTemp = analogRead(pin_tempRead); // read the initial temp
Serial.print("Initial temperature: "); Serial.print(initialTemp); Serial.println("C"); //prints out starting temperature
}
void loop() // run over and over again
{
//getting the voltage reading from the temperature sensor
float current_temp = analogRead(pin_tempRead);
// converting that reading to voltage
float voltage = current_temp * 5.0; voltage /= 1024.0;
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree with 500 mV offset
//to degrees ((voltage - 500mV) times 100)
if(temperatureC > cutOffTemp) {
// temp too high -> turn on the cooling system
digitalWrite(heatLED, LOW);
digitalWrite(coolLED, HIGH);
}else if (temperatureC < initialTemp) {
// temp too low -> turn on the heating system
digitalWrite(heatLED, HIGH);
digitalWrite(coolLED, LOW);
}
Serial.print("Current pump temperature: ");
Serial.print(temperatureC); Serial.println("C");
delay(1000);
}

the loop() function executes over and over, so it's not a good place to store initial values.
What you need to do is define a global variable, initialize it inside the setup() function and then you can read it in the loop() function
Minimalist example:
int pin_tempRead = 0; // temperature sensor pin
float initial_temp; // define a global variable
void setup() {
initial_temp = analogRead(pin_tempRead); // read the initial temp
}
void loop() {
float current_temp = analogRead(pin_tempRead);
// get the temperature difference respect to the initial one
float difference = initial_temp - current_temp;
delay(1000);
}
PD: Also is a good practice to distinguish the variables defining a hardware connection (pins) from the software ones. I usually append pin_ to the variables that define connections. Otherwise is not clear if tempRead is the value of the temperature or the pin where the sensor is attached.
Also, for the turning on and off of the heater/cooling system: You are already in a loop (the loop() function is a loop) so you don't need a while loop.
And you have some problem with our logic.
As I understood, you want to heat until the higher threshold (cutOff) is reached, then cool down until the lower threshold is reached (initialTemperature).
This is called Hysteresis, but your logic was wrong, here's the corrected one:
Just do:
void loop() {
if(temperatureC > cutOffTemp) {
// temp too high -> turn on the cooling system
digitalWrite(heatLED, LOW);
digitalWrite(coolLED, HIGH);
}else if (temperatureC < initialTemp) {
// temp too low -> turn on the heating system
digitalWrite(heatLED, HIGH);
digitalWrite(coolLED, LOW);
}
Serial.print("Current pump temperature: ");
Serial.print(temperatureC); Serial.println("C");
delay(1000);
}
By the way, you are using the initialTemperature as the low threshold for turning on the heating.
Is that what you really want?
What if the initial temperature is higher that the cutOffTemp? You will have problems in that case since the lower threshold is higher than the higher threshold.

Related

Pulsein() function blocks other tasks from running silmultaneously

I am using a zumo bot with a reflectance sensor used to follow a black line. I want to use an arduino to make the zumo bot stop once it gets a certain distance from an obstacle.
I have an ultrasonic sensor (HC-SR04) which ive connected to the bot.
Both of these tasks work independently but once i merge the code together(so it follows the line aswell as stoping when it detects an object using the ultrasonic sensor), it doesn't work properly.. (the zumo bot no longer follows the line)
I THINK it is to do with the pulsein() function blocking any other tasks but not sure.
My code is below. Can anyone help please?
#include <ZumoShield.h>
ZumoBuzzer buzzer;
ZumoReflectanceSensorArray reflectanceSensors;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON);
int lastError = 0;
// This is the maximum speed the motors will be allowed to turn.
// (400 lets the motors go at top speed; decrease to impose a speed limit)
const int MAX_SPEED = 400;
#define echoPin A4
#define trigPin A5
// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
void setup()
{
reflectanceSensors.init();
pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
// Initialize the reflectance sensors module
// Wait for the user button to be pressed and released
button.waitForButton();
// Turn on LED to indicate we are in calibration mode
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
// Wait 1 second and then begin automatic sensor calibration
// by rotating in place to sweep the sensors over the line
delay(1000);
int i;
for(i = 0; i < 80; i++)
{
if ((i > 10 && i <= 30) || (i > 50 && i <= 70))
motors.setSpeeds(-200, 200);
else
motors.setSpeeds(200, -200);
reflectanceSensors.calibrate();
// Since our counter runs to 80, the total delay will be
// 80*20 = 1600 ms.
delay(20);
}
motors.setSpeeds(0,0);
// Turn off LED to indicate we are through with calibration
digitalWrite(13, LOW);
// Wait for the user button to be pressed and released
button.waitForButton();
Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
Serial.println("with Arduino UNO R3");
}
void loop()
{
unsigned int sensors[6];
// Get the position of the line. Note that we *must* provide the "sensors"
// argument to readLine() here, even though we are not interested in the
// individual sensor readings
int position = reflectanceSensors.readLine(sensors);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Our "error" is how far we are away from the center of the line, which
// corresponds to position 2500.
int error = position - 2500;
// Get motor speed difference using proportional and derivative PID terms
// (the integral term is generally not very useful for line following).
// Here we are using a proportional constant of 1/4 and a derivative
// constant of 6, which should work decently for many Zumo motor choices.
int speedDifference = error / 4 + 6 * (error - lastError);
lastError = error;
// Get individual motor speeds. The sign of speedDifference
// determines if the robot turns left or right.
int m1Speed = MAX_SPEED + speedDifference;
int m2Speed = MAX_SPEED - speedDifference;
if (m1Speed < 0)
m1Speed = 0;
if (m2Speed < 0)
m2Speed = 0;
if (m1Speed > MAX_SPEED)
m1Speed = MAX_SPEED;
if (m2Speed > MAX_SPEED)
m2Speed = MAX_SPEED;
motors.setSpeeds(m1Speed, m2Speed);
//if (distance <20){
// motors.setSpeeds(0,0);
// }
////////////////////////////////////////////
// Calculating the distance
distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
// Displays the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
} ```
Of course pulseIn is blocking function. Arduino project is open source, you can easily check source code
Here is C equivalent countPulseASM function which does measurement.
unsigned long pulseInSimpl(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops)
{
unsigned long width = 0;
// wait for any previous pulse to end
while ((*port & bit) == stateMask)
if (--maxloops == 0)
return 0;
// wait for the pulse to start
while ((*port & bit) != stateMask)
if (--maxloops == 0)
return 0;
// wait for the pulse to stop
while ((*port & bit) == stateMask) {
if (++width == maxloops)
return 0;
}
return width;
}
If you need measure pulse length in non blocking way, use hw counters.

Problem in Computing the Energy in Energy Meter using ESP32

So me and my groupmates are been working on with our thesis project about energy meter. In our project, the esp32 is the main board we are using. We also have voltage sensor (ZMPT101B) and current sensor (SCT013 100V:50mA) connected to our main board.
here is the link for the ZMPT101B... https://www.autobotic.com.my/ac-voltage-sensor-module-zmpt101b-single-phase
and here is the link for the SCT013... https://innovatorsguru.com/sct-013-000/
I am also using the Emon library from https://www.arduino.cc/reference/en/libraries/emonlib/ to read the value thrown by the current and voltage sensor.
To get the power, i will multiply the current and voltage values.
Then to get the value of the energy i will be needing the time because Energy = Power x time. I saw formula online, it uses millis () function to get the time... but to be honest i dont know how millis works.
last_time = current_time;
current_time = millis();
Wh = Wh + power *(( current_time -last_time) /3600000.0) ;
The value of the energy will be send to the database, in our case our database is the firebase realtime database. Using this code...
Firebase.setDouble(firebaseData, path , KWh);
If the electricity cuts off , ESP32 will also be dead and will stop working. So we decided to add this line of codes...
Firebase.getInt(firebaseData, path);
totalEnergyDB = (firebaseData.intData());
preKWh = totalEnergyDB;
.... once the esp32 is turned on again, this code is used to get the data from the firebase... wherein the data got from the firebase will be used as a pre-kwh.
I used this lines of code to add the current readings from the pre-kwh.
KWh = (Wh/1000) + preKWh;
I set the calibration for the voltage and current sensor high so the changes will be easy to be seen.
My problem is that i was able to get the value from the database but it seems the energy formula is not working properly.
this is the result from the serial monitor... (171 KWH is the initial value from the database)
enter image description here
i wasn't able to show you the result of the power but it say in the lcd that it is around 3000W! But still Energy reading is not changing even its been turned on for over an hour:(
Here is the complete code for our project...
#include "EmonLib.h"
#define VOLT_CAL 52.5000
#define CURRENT_CAL 10.07
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
EnergyMonitor emon1;
int i;
// Wifi
#include <WiFi.h>
#include "FirebaseESP32.h"
#define FIREBASE_HOST "#!##!#$!#a.firebaseio.com"
#define FIREBASE_AUTH "RRw3u$!#%!##%##%$#%^#$^oI8LpQyVo0AWBC"
#define WIFI_SSID "WIFI"
#define WIFI_PASSWORD "PASSWORD"
// Define Firebase Data object
FirebaseData firebaseData;
// Root Path
String path = "/USER INFO/jdc/totalEnergy";
unsigned long last_time =0;
unsigned long current_time =0;
int Wh = 0;
int preKWh;
int KWh;
int totalEnergyDB;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
initWifi();
lcd.init();
lcd.backlight();
lcd.begin(4, 20);
lcd.clear();
lcd.setCursor(1,4);
lcd.print("LOADING...");
Serial.print("LOADING...");
emon1.voltage(32, VOLT_CAL, 1.7); // Voltage: input pin, calibration, phase_shift
emon1.current(33, CURRENT_CAL);
for ( i = 0; i < 5; i++ ) {
emon1.calcVI(20,2000);
float currentDraw = emon1.Irms;
float supplyVoltage = emon1.Vrms;
}
delay(1);
Firebase.getInt(firebaseData, path);
totalEnergyDB = (firebaseData.intData());
preKWh = totalEnergyDB;
}
void loop() {
emon1.calcVI(20,2000);
float currentDraw = emon1.Irms; //extract Irms into Variable
float supplyVoltage = emon1.Vrms;
float power = currentDraw * supplyVoltage;
last_time = current_time;
current_time = millis();
Wh = Wh + power *(( current_time -last_time) /3600000.0) ;
KWh = (Wh/1000) + preKWh;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("VOLTAGE: ");
lcd.print(supplyVoltage);
lcd.print(" V");
lcd.setCursor(0,1);
lcd.print("CURRENT: ");
lcd.print(currentDraw);
lcd.print(" A");
lcd.setCursor(0,2);
lcd.print("POWER: ");
lcd.print(power);
lcd.print(" W");
lcd.setCursor(0,3);
lcd.print("ENERGY: ");
lcd.print(KWh);
lcd.print(" KWh");
delay(100);
if (isnan(Wh)) { // if Wh is Not A Number
Serial.println(F("Error reading Energy!"));
}
else {
Serial.print(F("preKWh: "));
Serial.print(preKWh);
Serial.println(F("KWH"));
Serial.print(F("Energy: "));
Serial.print(KWh);
Serial.println(F("KWH"));
Firebase.setDouble(firebaseData, path , KWh);
delay(100);
}
}
void initWifi(){
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
//Set database read timeout to 1 minute (max 15 minutes)
Firebase.setReadTimeout(firebaseData, 1000 * 60);
//tiny, small, medium, large and unlimited.
//Size and its write timeout e.g. tiny (1s), small (10s), medium (30s) and large (60s).
Firebase.setwriteSizeLimit(firebaseData, "tiny");
}
Can anyone help me with the code. What changes should be done?
Looking at your data types, you are storing Wh and KWh as an integer, and you are adding likely very small floats to them (imagine (current_time - last_time) being 1000 (1 second), then Wh would become Wh + power * 2.78e-5, which will result in rounding errors unless your power consumption is enormous. To solve this, you should not round to integers, and keep Wh and KWh as floats.

Stop getting values from arduino after some time

I have a strange problem, I have Arduino UNO/MEGA and I need to get Gyro sensors's data and I want to see the data in the serial monitor. Seems like a simple task, I wrote a simple C program which collects data from Arduino through serial monitor I can see the data. Everything is working for few minutes and after that, it stops.
This code is supposed to calculate a distance travelled in a line using encoder (PID algorithm implemented using Gyroscope data for straight motion) after reaching desired position, machine takes a U-Turn.
It stop for a second after taking the U-Turn and then starts straight motion again. The problem I'm facing is that the gyroscope readings stop randomly while machine taking the turn. Due to this, the machine keeps rotating about that point without stopping.
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
float timeStep = 0.01, yaw=0;
const int motor11=6;//LEFT MOTOR FW
const int motor12=7;//LEFT MOTOR BK
const int motor1pwm=3;
const int motor21=8;//RIGHT MOTOR FW
const int motor22=9;//RIGHT MOTOR BK
const int motor2pwm=5;
int flag1 = 0;
int thres1=120;//PWM Values
int thres2=120;
void setup()
{
Serial.begin(115200);
// Initialize MPU6050
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}
mpu.calibrateGyro();
mpu.setThreshold(1);
pinMode(motor11, OUTPUT);
pinMode(motor12, OUTPUT);
pinMode(motor1pwm, OUTPUT);
pinMode(motor21, OUTPUT);
pinMode(motor22, OUTPUT);
pinMode(motor2pwm, OUTPUT);
}
void loop()
{
Vector norm=mpu.readNormalizeGyro();
yaw=yaw+norm.ZAxis*timeStep;
if(flag1 == 0){
straight();
}
if(flag1 == 2){
taketurn();
}
}
void straight()
{
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, thres1);
digitalWrite(motor21, HIGH);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, thres2);
delay(8000);
flag1 = 2;
}
void taketurn()
{
float setPoint = yaw - 500;
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, 120);
digitalWrite(motor21, LOW);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, 120);
while(true)
{
Vector norm = mpu.readNormalizeGyro();
yaw = yaw + norm.ZAxis * timeStep;
Serial.print("Turning Yaw= ");
Serial.println(yaw);
if(setPoint >= yaw) {
digitalWrite(motor11, LOW);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, thres2);
digitalWrite(motor21, LOW);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, thres1);
delay(2000);
break;
}
}
flag1 = 0;
}
The serial monitor just stops displaying the reading. This does not happen every time, and it is very random. I want to get proper and continuous data. Is it a logical problem or a board problem?
Normally a random crash would indicate possibly unhandled interrupts or memory overwrite, but looking at your code and it being an Arduino program, it's unlikely to be either. I don't see any divide ops either, so you are not dividing by zero. The two possible things I see is that a) you have a "while (true)" without exit, so surely that could get you into trouble, and b) perhaps your delay functions are called with a very large value unexpectedly, and the MCU is actually just delaying a long time.

Arduino Interfacing with Magnetic Pickup

Currently I have a diesel engine with magnetic pickup attached to it. I want to use Arduino (Uno/Nano) to measure engine RPM.
Magnetic Pickup Description: A magnetic pickup is installed over a gear, (most commonly the flywheel inside a vehicle’s bell housing) and as the gear turns the pickup will create an electric pulse for each tooth on the gear. These pulses are then read by the instrument which interprets it to indicate the correct RPMs or speed.The signal from the magnetic speed Sensor, teeth per second(HZ), is directly proportional to engine speed.
Magnetic Pickup Image:
MP - Self Powered
I've tried to rectify the signal using diode then limit the current using a resistor with .1Uf capacitor to filter the noise, then connected it to Optocopler 4N35 and the output from Opto to Arduino interrupt pin, by just observing Arduino interrupt ping is highly affected by surroundings.
Also I have tried to directly connect the magnetic pickup to "A0" pin and use analogue read and connect a led to pin 13 just to monitor the pulses from MP.
int sensorPin = A0;
int ledPin = 13;
int sensorValue = 0;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
digitalWrite(ledPin, HIGH);
delay(sensorValue);
digitalWrite(ledPin, LOW);
Serial.println(sensorValue);
Serial.println(" ");
}
Using analogueRead works with the LED as indicator for pulses generated by pickup. (Tested using small motor and small gear to protect Arduino).
Also I tried to use LM139 Comparator but the readings make no sense
(ex: 60 RPM, 1500 RPM,2150 RPM, 7150 RPM).
LM139 Circuit
Code used with LM139:
// read RPM
volatile int rpmcount = 0;
//see http://arduino.cc/en/Reference/Volatile
int rpm = 0;
unsigned long lastmillis = 0;
void setup() {
Serial.begin(9600);
attachInterrupt(0, rpm_fan, RISING);
//interrupt cero (0) is on pin two(2).
}
void loop() {
if (millis() - lastmillis == 500) {
/*Update every one second, this will be equal to reading frequency (Hz).*/
detachInterrupt(0); //Disable interrupt when calculating
rpm = rpmcount * 60;
/* Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrupts per full rotation use rpmcount * 30.*/
Serial.print(rpm); // print the rpm value.
Serial.println(" ");
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Update lastmillis
attachInterrupt(0, rpm_fan, RISING); //enable interrupt
}
}
void rpm_fan() {
/* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}
// Elimelec Lopez - April 25th 2013
What is the best way or approach to interface a magnetic pickup with Arduino to display RPM?
Your use of analogRead is wrong. Besides, analogRead will not get you anywhere close to what you want to achieve.
What you want from your pickup is a clear 0-5v digital signal. You can obtain that by playing with the input resistor on your opto-coupler. I'd do some measurements, and place a trimpot + resistors on the board do the actual value can be tweaked after the system is installed.
Once you get the electrical signal as clean as you can get, you can the use an interrupt pin on the Arduino to keep count of the number of pulses.
#define SENSOR_PIN (2) // using define instead of variable for constants save memory.
#define LED_PIN (13)
#define READ_DELAY (100) // in milliseconds.
// we'll get a reading every 100ms, so 8 bits are enough to keep
// track of time. You'd have to widen to unsigned int if you want
// READ_DELAY to exceed 255 ms.
//
typedef delay_type unsigned char;
typedef unsigned int counter_type; // You may want to use
// unsigned long, if you
// experience overflows.
volatile counter_type pulseCount = 0; // volatile is important here
counter_type lastCount = 0;
delay_type lastTime = 0;
// pulse interrupt callback, keep short.
void onSensorPulse()
{
++pulseCount;
// the following may already be too long. Use for debugging only
// digitalWrite() and digitalRead() are notoriously slow.
//
//
// digitalWrite(LED_PIN, !digitalRead(LED_PIN));
//
// using fastest direct port access instead. (for ATMega)
//
if (pulseCount & 1)
PORTB |= (1 << PB5);
else
PORTB &= ~(1 << PB5);
}
void setup()
{
pinMode(SENSOR_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), onSensorPulse, RISING);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
// control frequency of readings
//
delay_type now = (delay_type)millis();
if (now - lastTime < READ_DELAY)
{
return;
}
lastTime = now;
// get a reading. must disable interrupts while doing so.
// because pulseCount is multi-bytes.
//
noInterrupts();
counter_type curCount = pulseCount;
interrupts();
// get the number of pulses since last reading.
//
counter_type delta = curCount - lastCount;
lastCount = curCount;
// to convert to RPMs, you will need to use this formula:
// note the use of long (UL) to avoid overflows in the
// computation. 60000 = miliseconds per minute.
//
// RPM = delta * 60000UL / (READ_DELAY * TEETH_COUNT);
// send delta to client for now.
//
Serial.println(delta);
}

Arduino Uno Avoidance Robot: One of two motors not working

I'm trying to code an Arduino avoidance robot as a learning project. When I run the following code only one motor (the left one) works. If I comment out the if statement that uses the checkDistance() function and just loop the forward() function both motors work fine. I'm using an Adafruit Motorshield v1.2, and I believe this is the motor: Link. I've tried powering directly through USB, and also through external power supply (4 x AAs), and have the same issue. Any pointers would be appreciated. Thank you!
#include <AFMotor.h>
#define trigPin 3
#define echoPin 2
AF_DCMotor left_motor(2, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
AF_DCMotor right_motor(1, MOTOR12_64KHZ); // motor #2\
int maxDistance = 30;
//int minDistance = 0;
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
left_motor.setSpeed(255);
right_motor.setSpeed(255);
}
void forward(int delayTime) {
left_motor.run(FORWARD);
right_motor.run(FORWARD);
delay(delayTime);
}
void backward(int delayTime) {
left_motor.run(BACKWARD);
right_motor.run(BACKWARD);
delay(delayTime);
}
void stop(int delayTime) {
left_motor.run(RELEASE);
right_motor.run(RELEASE);
delay(delayTime);
}
void right(int delayTime) {
left_motor.run(FORWARD);
right_motor.run(BACKWARD);
delay(delayTime);
}
void left(int delayTime) {
left_motor.run(BACKWARD);
right_motor.run(FORWARD);
delay(delayTime);
}
int checkDistance(){
long duration, distance;
/* The following trigPin/echoPin cycle is used to determine the
distance of the nearest object by bouncing soundwaves off of it. */
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the speed of sound.
distance = duration/59.1;
return distance;
}
void loop() {
int currentDistance = checkDistance();
Serial.print(currentDistance);
if (currentDistance >= maxDistance){
Serial.println(" cm. No immediate obstacles detected. Moving forward.");
forward(2000);
stop(1000);
}
else {
Serial.println(" cm. Obstacle detected. Changing direction.");
right(1500);
stop(1000);
}
}
If I were trying to debug this, I would first test each of the motor functions without any logic check from the sensor. (e.g. do both wheels turn and in the correct direction when left, right, backward, etc are called just from loop()). That will give confidence that it is not a wiring or other hardware problem. If they don't work then sorting that out give you a place to start.
If they do work, then it must be the values with the sensor, right? How did you determine the maxDistancevalue? If it is too high then this line:
if (currentDistance >= maxDistance){
may never evaluate to true. You have some log statements in there so you have some sense of the value of currentDistance. Does it seem to be reflecting accurate values when you place objects at varying distances from the sensor?
Anyway... some thoughts.

Resources