Real Time Stepper Motors Control using ESP8266 and Blynk app - c++

I wanted to control 2 Stepper Motors for running a robot using the joystick of Blynk App and NodeMCU/ESP8266. But when I searched for the codes of real time controlling of Stepper Motors online I didn't get much code and most of them were not real time.
This is code I am currently working on:-
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define RightMotorSpeed D7
#define RightMotorDir D8
const int enPin = D2;
const int enPin2 = D3;
#define LeftMotorSpeed D6
#define LeftMotorDir D5
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
// Use your own WiFi settings
char auth[] = "LRTCZUnCI06P-pqh5rlPXRbuOUgQ_uGH";
char ssid[] = "Airtel_7599998800";
char pass[] = "air71454";
// neutral zone settings for x and y
// joystick must move outside these boundary numbers to activate the motors
// makes it a little easier to control the wifi car
int minRange = 312;
int maxRange = 712;
// analog speeds from 0 (lowest) - 1023 (highest)
// 3 speeds used -- 0 (noSpeed), 350 (minSpeed), 850 (maxSpeed).
// use whatever speeds you want...too fast made it a pain in the ass to control
int minSpeed = 450;
int maxSpeed = 1023;
int noSpeed = 0;
void moveControl(int x, int y)
{
// movement logic
// move forward
// y je vetsi jak maxrange a současně x je vetsi jak minRange a současne mensi jak max range
while(y >= maxRange && x >= minRange && x <= maxRange) //zataci R
{
digitalWrite(RightMotorDir,HIGH);
digitalWrite(LeftMotorDir,HIGH);
analogWrite(RightMotorSpeed,maxSpeed);
analogWrite(LeftMotorSpeed,maxSpeed);
delayMicroseconds(500);
digitalWrite(RightMotorSpeed,0);
digitalWrite(LeftMotorSpeed,0);
delayMicroseconds(500);
}
// move forward right
while(x >= maxRange && y >= maxRange) //zataci R
{
digitalWrite(RightMotorDir,HIGH);
digitalWrite(LeftMotorDir,HIGH);
analogWrite(RightMotorSpeed,minSpeed);
analogWrite(LeftMotorSpeed,maxSpeed);
}
// move forward left
while(x <= minRange && y >= maxRange)
{
digitalWrite(RightMotorDir,HIGH);
digitalWrite(LeftMotorDir,HIGH);
analogWrite(RightMotorSpeed,maxSpeed);
analogWrite(LeftMotorSpeed,minSpeed);
}
// neutral zone
while(y < maxRange && y > minRange && x < maxRange && x > minRange)
{
analogWrite(RightMotorSpeed,noSpeed);
analogWrite(LeftMotorSpeed,noSpeed);
}
// move back
while(y <= minRange && x >= minRange && x <= maxRange)
{
digitalWrite(RightMotorDir,LOW);
digitalWrite(LeftMotorDir,LOW);
analogWrite(RightMotorSpeed,maxSpeed);
analogWrite(LeftMotorSpeed,maxSpeed);
}
// move back and right
while(y <= minRange && x <= minRange)
{
digitalWrite(RightMotorDir,LOW);
digitalWrite(LeftMotorDir,LOW);
analogWrite(RightMotorSpeed,minSpeed);
analogWrite(LeftMotorSpeed,maxSpeed);
}
// move back and left
while(y <= minRange && x >= maxRange)
{
digitalWrite(RightMotorDir,LOW);
digitalWrite(LeftMotorDir,LOW);
analogWrite(RightMotorSpeed,maxSpeed);
analogWrite(LeftMotorSpeed,minSpeed);
}
}
void setup()
{
// initial settings for motors off and direction forward
pinMode(RightMotorSpeed, OUTPUT);
pinMode(LeftMotorSpeed, OUTPUT);
pinMode(RightMotorDir, OUTPUT);
pinMode(LeftMotorDir, OUTPUT);
digitalWrite(RightMotorSpeed, LOW);
digitalWrite(LeftMotorSpeed, LOW);
digitalWrite(RightMotorDir, HIGH);
digitalWrite(LeftMotorDir,HIGH);
Serial.begin(9600);
pinMode(enPin,OUTPUT);
digitalWrite(enPin,LOW);
pinMode(enPin2,OUTPUT);
digitalWrite(enPin2,LOW);
Blynk.begin(auth, ssid, pass);
}
void loop()
{
Blynk.run();
}
BLYNK_WRITE(V1)
{
int x = param[0].asInt();
int y = param[1].asInt();
moveControl(x,y);
}
Here I have defined by 2 Stepper motors as Right and Left and since I am using TB6600 Motor Driver therefore their Pulse and Direction Pins are also Defined. That is the main reason that I am unable to use the Stepper motor Library for the code.
Running the code I see that Both the motors runs fine once for 3 to 5 seconds and the the Blynk Server Disconnects and Reconnects again causing the motors to stop and not creating a real time communication. Some one Please help me create a code for these 2 stepper motors to run at realtime.
I think that Blink.run() causes the server to reconnect and stop the motor.
I also searched for this cause and found that instead of Stepper motor Library I should use AccelStepper Library but that is also not achieved . Please help me with this. Any correct reference is also appreciable. Thanks in advance.

Blynk requires constants pings to keep the connection alive. A while loop prevents any form of communication between your device and the Blynk server.
The preferred option is to use Timers to interactively call your functions and advance through the code. Another method is to force a server ping.
For example, you could add the following and call softDelay(1) within each of your while loops.
void softDelay(uint32_t t) {
unsigned long currentTime = millis();`
unsigned long newTime = currentTime + t;
while (currentTime <= newTime)
{
Blynk.run();
timer.run();
currentTime = millis();
}
}

Related

How to move forward and backward with the Arduino Stepper motor?

I want to create an Arduino program for a system that has three buttons and one stepper motor. If button 1 is pressed, the stepper should go for example 50 steps forward. If button 2 is pressed, the stepper should go 50 steps backward. If button 3 is pressed, the stepper should go 50 steps forward after that 50 steps backward.
I used Arduino's stepper library and wrote the following code. The functions Forward(), Backward() and Continuous() implement the actions to be performed for each button. Each function moves the motor step by step and logs the action on a serial output.
But I could not achieve my desired results: The stepper does not go backward but only goes forward. More precisely:
Forward() works as expected
Backward() produces the expected logging output (counting the steps up to 50), but the motor only moves forward instead of backward.
Continuous() function is not working either: after 50 step forward (moving and logging the step count), it continues moving forward logging just 1 for the counter.
I need your help. How can I make the motor going backwards in Backward()? And how to correct Continuous() to achieve move forward and backward, and producing the right backward step count?
Here my code:
#include <Stepper.h>
int forward_button = 2;
int backward_button = 3;
int cont_button = 4;
int button_cond1;
int button_cond2;
int button_cond3;
int del = 50;
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int stepCount = 0; // number of steps the motor has taken
int steps;
void Forward() { // should go forward by 50 steps
int stepCount = 0;
while (stepCount < 50) {
steps = 1;
myStepper.step(steps);
stepCount++;
delay(del);
Serial.print("Forward steps :");
Serial.println(stepCount);
}
}
void Backward() { // should go backward by 50 steps
int stepCount = 0;
while (stepCount < 50) {
steps = 1;
myStepper.step(steps);
stepCount++;
delay(del);
Serial.print("Backward steps :");
Serial.println(stepCount);
}
}
void Continuous() { // should go forward by 50 steps, then backwards
int stepCount = 0;
while (stepCount < 50) {
steps = 1;
myStepper.step(steps);
stepCount++;
delay(del);
Serial.print("Continuous steps :");
Serial.println(stepCount);
}
while (50 < stepCount <= 200) {
int stepCount = 0;
steps = 1;
myStepper.step(steps);
stepCount++;
delay(del);
Serial.print("Continuous steps :");
Serial.println(stepCount);
}
}
void setup() {
// initialize the serial port:
Serial.begin(9600);
pinMode(forward_button, INPUT_PULLUP);
pinMode(backward_button, INPUT_PULLUP);
pinMode(cont_button, INPUT_PULLUP);
//myStepper.setSpeed(60);
}
void loop() {
// step one step:
button_cond1 = digitalRead(forward_button);
button_cond2 = digitalRead(backward_button);
button_cond3 = digitalRead(cont_button);
if ((button_cond1 == LOW) && (button_cond2 == HIGH) && (button_cond3 == HIGH)) {
Forward();
}
else if ((button_cond1 == HIGH) && (button_cond2 == LOW) && (button_cond3 == HIGH)) {
Backward();
}
else if ((button_cond1 == HIGH) && (button_cond2 == HIGH) && (button_cond3 == LOW)) {
Continuous();
}
}
Issue with the direction of the stepper:
According to the documentation, myStepper.step() turns the motor:
Turns the motor a specific number of steps, at a speed determined by the most recent call to setSpeed().
And more importantly, to move in both directions, it uses a signed argument:
the number of steps to turn the motor - positive to turn one direction, negative to turn the other (int)
In your code, there is no difference between Backward() and Forward(): you provide positive values in both cases. So I suggest to change Backwards() to use a negative number:
myStepper.step(-steps);
Issues with the logic of Continuous()
The direction needs also to be corrected in the second loop of your Continuous() function, where you want to go backwards.
But first, you need to correct this loop's condition:
while (50 < stepCount <= 200) { //OUCH compares a boolean and an integer
C++ does not chain the comparison operators as you think. Therefore break it up in two distinct comparisons grouped with a logical and:
while (50 < stepCount && stepCount <= 200) {
Unfortunately, at the end of the first loop stepCount is exactly 50. And 50 is not strictly smaller (<) than 50. You could use a smaller or equal (<=) instead, but since the loop does not decrement the counter, you could simplify the condition to:
while (stepCount <= 200) { // we know that it will stay 50 or above
You also need to delete the redefinition of stepCount in this loop's block, since it creates a new local variable that hides the initial definition (i.e. one name, two variables, that's very confusing).
If it still does not work
Following the long exchange of comments, here some advice (in bold the one that solved the issue):
Make sure the latest version of the code runs on the arduino and there's no compilation error or warning.
Make sure that the different buttons execute the expected function.
If the motor movements are not as expected, make sure that you Stepper object is configured with a number of steps per rotation that is compatible with the motor.
If the movements are erratic, or if there is no difference between positive and negative steps (which should according to the documentation move in opposite directions), then cross check that the Stepper's constructor gets the pin numbers in the right order: this is important, because Stepper will send a sequence of signals to the different pins in a given order to achieve the right motion.
If it still does not work there is either a hardware issue, or an incompatibility with the library (see for example here, where the authors solved the problem by providing another signal sequences, which is not the easiest way).

Why is my Arduino code for running a Bluetooth controlled robot with obstacle sensor not working as it should be?

I have created a Bluetooth based smartphone controlled robot (a 4 wheel car) earlier using Arduino and an obstacle avoidance robot.
Now, I wanted to combine both of them. So, I combined their functions and codes in such a manner that felt right to me. But, it kinda seems wrong to my robot.
My Bluetooth Controlled robot was running smoothly. My obstacle avoiding robot was running flawless. But, when I tried to join them, both of them started crying.
I tried to change orders of the functions, adding some functions twice or thrice removing them from some places that didn't feel right then. Nothing was worthy.
I need to upload whole code because I'm not sure where am I doing it wrong
#include <SoftwareSerial.h>
#include <RemoteXY.h>
// RemoteXY connection settings
#define REMOTEXY_SERIAL_RX A2
#define REMOTEXY_SERIAL_TX A3
#define REMOTEXY_SERIAL_SPEED 9600
// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255,8,0,54,0,176,0,8,228,4,
5,48,44,26,30,30,0,31,8,1,
6,0,-84,-142,20,20,0,2,26,129,
0,6,37,23,8,0,64,78,97,118,
101,100,0,131,3,51,1,20,5,1,
2,31,82,111,98,111,116,32,67,97,
114,0,131,0,62,5,19,5,2,2,
31,67,111,110,116,114,111,108,108,101,
114,0,129,0,10,45,13,7,0,16,
84,72,69,0,129,0,5,52,25,8,
0,136,83,104,101,105,107,104,0,1,
0,-34,-111,12,12,1,2,31,88,0,
1,4,79,44,12,12,0,37,151,240,
159,147,162,0,65,4,87,9,7,7,
0,65,1,87,17,7,7,0,65,2,
87,25,7,7,0,67,5,3,3,25,
14,0,94,24,51,2,0,86,1,11,
5,0,135,26,31,31,79,78,0,79,
70,70,0 };
// this structure defines all the variables of your control interface
struct {
// input variable
int8_t joystick_1_x; // =-100..100 x-coordinate joystick position
int8_t joystick_1_y; // =-100..100 y-coordinate joystick position
uint8_t rgb_1_r; // =0..255 Red color value
uint8_t rgb_1_g; // =0..255 Green color value
uint8_t rgb_1_b; // =0..255 Blue color value
uint8_t button_1; // =1 if button pressed, else =0
uint8_t button_2; // =1 if button pressed, else =0
uint8_t switch_1; // =1 if switch ON and =0 if OFF
// output variable
uint8_t red_led_r; // =0..255 LED Red brightness
uint8_t blue_led_b; // =0..255 LED Blue brightness
uint8_t green_led_g; // =0..255 LED Green brightness
char text_indicator[51]; // string UTF8 end zero
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop)
/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
#define PIN_BUTTON_2 A4
#define PIN_SWITCH_1 A5
#include<AFMotor.h>
#include <NewPing.h>
#include <Servo.h>
#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 250
//#define MAX_SPEED 150 // sets speed of DC motors
//#define MAX_SPEED_OFFSET 20
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
AF_DCMotor left_motor_A(1, MOTOR12_64KHZ);
AF_DCMotor left_motor_B(2, MOTOR12_64KHZ);
AF_DCMotor right_motor_A(3, MOTOR34_64KHZ);
AF_DCMotor right_motor_B(4, MOTOR34_64KHZ);
Servo myservo;
int distance = 100;
int right_motor_speed = 0;
int left_motor_speed = 0;
//define two arrays with a list of pins for each motor
AF_DCMotor RightMotor[2] = {right_motor_A, right_motor_B};
AF_DCMotor LeftMotor[2] = {left_motor_A, left_motor_B};
//speed control of motors
void Wheel (AF_DCMotor * motor, int v) // v = motor speed, motor = pointer to an array of pins
{
if (v > 100) v=100;
if (v < -100) v=-100;
if (v > 0){
motor[0].run(FORWARD);
motor[1].run(FORWARD);
motor[0].setSpeed(v * 1.75);
motor[1].setSpeed(v * 1.75);
}
else if ( v<0 ){
motor[0].run(BACKWARD);
motor[1].run(BACKWARD);
motor[0].setSpeed(v * 1.75);
motor[1].setSpeed(v * 1.75);
/* //digitalWrite (motor [1], FORWARD);
analogWrite (motor [2], (v) * 0.75);
//analogWrite (motor [2], (-v) * 0.75); */
}
else{
motor[0].run(RELEASE);
motor[1].run(RELEASE);
motor[0].setSpeed(0);
motor[1].setSpeed(0);
}
}
int lookRight()
{
RemoteXY.blue_led_b = 255;
RemoteXY.red_led_r = 0;
RemoteXY.green_led_g = 0;
sprintf(RemoteXY.text_indicator, "CHECKING THE RIGHT SIDE.");
myservo.write(50);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
}
int lookLeft()
{
RemoteXY.blue_led_b = 255;
RemoteXY.red_led_r = 0;
RemoteXY.green_led_g = 0;
sprintf(RemoteXY.text_indicator, "CHECKING THE LEFT SIDE.");
myservo.write(170);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
delay(100);
}
int readPing()
{
delay(100);
int cm = sonar.ping_cm();
if(cm==0)
{
cm = MAX_DISTANCE ;
}
return cm;
}
void moveStop()
{
left_motor_A.run(RELEASE);
left_motor_B.run(RELEASE);
right_motor_A.run(RELEASE);
right_motor_B.run(RELEASE);
}
void setup()
{
RemoteXY_Init ();
pinMode (PIN_BUTTON_2, OUTPUT);
pinMode (PIN_SWITCH_1, OUTPUT);
myservo.attach(10);
myservo.write(115);
delay(2000);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
}
void loop()
{
RemoteXY_Handler ();
digitalWrite(PIN_BUTTON_2, (RemoteXY.button_2==0)?LOW:HIGH);
digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
int distanceR = 0;
int distanceL = 0;
delay(40);
if(distance<=27)
{
moveStop();
RemoteXY.blue_led_b = 0;
RemoteXY.red_led_r = 255;
RemoteXY.green_led_g = 0;
sprintf(RemoteXY.text_indicator, "AN OBSTACLE HAS COME IN FRONT OF YOUR ROBOT!!!");
digitalWrite(PIN_BUTTON_2, HIGH);
delay(1500);
distanceR = lookRight();
delay(250);
distanceL = lookLeft();
delay(250);
if(distanceR>=distanceL)
{
RemoteXY.blue_led_b = 255;
RemoteXY.red_led_r = 0;
RemoteXY.green_led_g = 0;
sprintf(RemoteXY.text_indicator, "IT IS GOOD TO GO ON THE RIGHT SIDE.");
}
else
{
sprintf(RemoteXY.text_indicator, "IT IS GOOD TO GO ON THE LEFT SIDE.");
}
}
else
{
RemoteXY.blue_led_b = 0;
RemoteXY.red_led_r = 0;
RemoteXY.green_led_g = 255;
//manage the right motor
Wheel (LeftMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
Wheel (RightMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x);
}
distance = readPing();
//manage the right motor
//Wheel (LeftMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
//Wheel (RightMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x);
}
I want my Robot to work on my directions and when he senses something on its front end then he should stop there and tell me through a RemoteXY.text_string and then check for obstacles at the left and right side and tell me on which side it is available to go. After that, it should again take my orders via my mobile phone.
Firstly, it became impossible to connect the robot to the Smartphone using Bluetooth because the robot was very busy in doing some other stuffs (only he knows what was he doing). Then, I applied a "RemoteXY Button" on my code (that is not in the code that I'm posting here) with an "if" block; such that if this switch is pressed via the Smartphone, only then the robot will start moving. So, doing this thing helped me to connect my robot to my smartphone via Bluetooth but, when I was connection then the Servo Motor was regularly spinning (again, I don't know why) after secure connection, when I turned that switch on, then my robot took only my first order (which is usually moving forward) and it performed on my first order for almost first 3 to 5 seconds and then the Robot got his system hanged and my smartphone was automatically disconnected from the robot.
I am unable to figure out where is the filth in my code or my code is itself fully filthy. This is the matter, where I need you guys' help
Other information that you might need for better Support/help, I am using:
1). RemoteXY app for Android to Robot Communication
2). Arduino UNO as Microcontroller
3). Arduino IDE for Programming Arduino
4). One SG 90 Servo Motor.
5). Four Geared DC- Motors.
6). L293D Motor Driver Shield for driving Dc motors and the Servo
7). HC SR-04 ultrasonic sensor for obstacle sensing
8). A 12V battery
9). HC-05 Module for Bluetooth Communication
10). A buzzer for external indicator/horn. At pin A4
11). A filthy code for Arduino Programming 😜.
Any help with the code will be appreciated.
Thank You So Much in advance. ❤️
For an arduino robot that needs to perform a lot of function simultaneously you may want to look into this https://forum.arduino.cc/index.php?topic=223286.0

Arduino Micro: SP02 Custom Sensor, IR & Red LEDS. Serial Output Inconsistant

thank you in advance for the community's help.
As of right now, we are looking to get consistent data to output to the serial monitor.
We are seeing output to the monitor several seconds after turning on the device, and sometimes the output takes more than 15 seconds. Furthermore, we are getting a oxogyn concentration of a value well above 100%.
There are times when we get a HR value, and a O2 value which seem reasonable, however, this is not always the case and rather inconsistent.
Is there something wrong with the timing of the interrupts or even the frequency in which we write to the serial monitor?
The code is as follows:
#include <LiquidCrystal.h> //Including this so we can test the code as is
//We can always remove the LCD code later
#include "floatToString.h" //SEE COMMENTS BELOW
/*
* You need to include the float to string header file. I am unsure if this goes in the
* main direcotry withe the code or just the library. For completness I have incouded it on my
* computer in both locations. Please do the same untill we can test further.
*/
#include "Arduino.h" //Formally floatToString.h This changed years ago, using Arduino.h
#include <SoftwareSerial.h> //bluetooth
#include <TimerOne.h> //interrupts SEE COMMENT BELOW
//**********************************************************
//Read Below..........................................
/*
* Need a library for the above timeerOne file
* without the library, you will get an error.
* See Github at https://github.com/PaulStoffregen/TimerOne
* Download the timerOne-master.zip file and place the entire
* TimerOne-master folder in my Documents > Arduino > libraries
*/
//**********************************************************
#define analogPin A0
#define Theta 0.6
#define RxD 1 //bluetooth read
#define TxD 0 //bluetooth transmit
#define DEBUG_ENABLED //bluetooth
#define redLED 5 //High is Red led on, Low is Infrared on.
//#define iredLED 6
volatile int maxTemp,minTemp; //shared variables between interrupts and loop
volatile int lastcount,count;
int Rmax, Rmin, IRmax, IRmin;
float R, Spo2,HeartR_frq;
int Sp02_int;
int HeartRate, HeartR;
float LastHeartRate = 70; //default
int average = 140; //average is average crossing
//int average2 = 220;
int interrupts_counter =0; //count the times of interrupts
float value=0.5;
float Spo2_float;
char buffer[25];
SoftwareSerial blueToothSerial(RxD,TxD); //define bluetooth
void setup() {
pinMode(redLED, OUTPUT); //define LED
pinMode(RxD, INPUT); //bluetooth input
pinMode(TxD, OUTPUT); //bluetooth output
pinMode(analogPin, INPUT); //analog signal input
//initially switch on Red LED, after each interrupt will turn on the other
digitalWrite(redLED, HIGH);
Serial.begin(115200);
//bluetooth
setupBlueToothConnection();
//We might not need this, this might be for the LCD display. Leaving it in for now
init_interrupts();
Timer1.initialize(40000); //terrupt every 0.04 seconds
Timer1.attachInterrupt(max_min_num); //interrupt call max_min_num function
Rmax = 0;
IRmax = 0;
Rmin = 0;
IRmin = 0;
LastHeartRate = 70;
}
void loop() {
//initialize LCD
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize LCD, the pins are all depends
lcd.begin(8, 2); //set up the LCD's number of columns and rows:
while(1){ //the whole while is used to avoid LCD reinitialize
digitalWrite(redLED,HIGH);
delay(2000); //let red led signal to be stable
//interrupts();
while(!((lastcount>average )&& (count<average)) ){ }
digitalWrite(redLED,HIGH);
init_interrupts();
while(!((lastcount>average )&& (count<average)) ){ }
noInterrupts(); // temporarily disabel interrupts, to be sure it will not change while we are reading
Rmax = maxTemp;
Rmin = minTemp;
delay(100);
HeartR_frq = 1/(0.04*interrupts_counter); //d is the times of ISR in 1 second,
interrupts(); //enable interrupts
HeartRate = HeartR_frq * 60;
if(HeartRate> 60 && HeartRate< 120){
HeartR = Theta*HeartRate + (1 - Theta)*LastHeartRate; //Use theta to smooth
LastHeartRate = HeartR;
}
digitalWrite(redLED, LOW);
//initialize lcd
lcd.setCursor(0,0);
lcd.print("HR:");
lcd.setCursor(5,0);
lcd.print(HeartR);
R = (Rmax - Rmin);
Spo2 = (R-180)*0.01 +97.838;
int Spo2_int = (int)Spo2; //float Spo2 to int Spo2_int
String Spo2_float = floatToString(buffer,Spo2,2);
lcd.setCursor(0,1);
lcd.print("SPO2:");
lcd.setCursor(5,1);
lcd.print(Spo2_int);
//transmit data to phone app through bluetooth
String H = String("H: ")+HeartR +String("S: ") +Spo2_float;
Serial.println(H);
delay(1000);
init_interrupts();
}
}
void setupBlueToothConnection() //initialize bluetooth
{
blueToothSerial.begin(115200); //Set BluetoothBee BaudRate to default baud rate 38400
blueToothSerial.print("\r\n+STWMOD=0\r\n"); //t the bluetooth work in slave mode
blueToothSerial.print("\r\n+STNA=HC-06\r\n"); //t the bluetooth name as "HC-05"
blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
//blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
blueToothSerial.print("bluetooth connected!\n");
delay(2000); // This delay is required.
blueToothSerial.flush();
}
void init_interrupts()
{
maxTemp = 0;
minTemp = 1023;
count = 0;
lastcount =0;
interrupts_counter = 0;
}
void max_min_num()
{
lastcount = count;
count = analogRead(analogPin); //read signa
if(count> maxTemp){
maxTemp = count;
}
else if(count<minTemp){
minTemp = count;
}
interrupts_counter++; //interrupt counter
}
Thank you in advance for your time!

Stopping a program under certain conditions

I am greeting you today with a program question for my project that uses light as an input for a servo on a wall. Light will enter the room and the shade will go down, and in the absence of light, the shade will recede. I would like to make two conditions in a void loop in the arduino code only applicable one time unless the condition changes. By saying this I mean that, I want this void loop to run continually,in which i have two conditions. And if the same condition is met twice in a row,(ie. sensor reading between 800 and 10000, like 5000 and and then at 6032), nothing will run. If one condition is met and then the other is met afterwards, that's ok. Here's my code and any help as to what reference commands I should use or my next course of action would be greatly appreciated.
// Reports the frequency from the TSL230, higher number means brighter
// Part: http://www.sparkfun.com/products/8940
// Article: http://bildr.org/2011/08/tsl230r-arduino/
#include <Servo.h>
Servo myservo1;
int TSL230_Pin = 4; //TSL230 output
int TSL230_s0 = 3; //TSL230 sensitivity setting 1
int TSL230_s1 = 2; //TSL230 sensitivity setting 2
int TSL230_samples = 30; //higher = slower but more stable and accurate
void setup(){
Serial.begin(9600);
setupTSL230();
pinMode(5,OUTPUT);
}
void loop(){
float lightLevel = readTSL230(TSL230_samples);
Serial.println(lightLevel);
if(lightLevel>800 && lightLevel<1000)
{
myservo1.attach(5);
myservo1.writeMicroseconds(1300);delay(1000);
myservo1.writeMicroseconds(1500);delay(5000000);
}
else if(lightLevel<800)
{
myservo1.attach(5);
myservo1.writeMicroseconds(1700);delay(5000);
myservo1.writeMicroseconds(1500);delay(5000000);
}
}
void setupTSL230(){
pinMode(TSL230_s0, OUTPUT);
pinMode(TSL230_s1, OUTPUT);
//configure sensitivity - Can set to
//S1 LOW | S0 HIGH: low
//S1 HIGH | S0 LOW: med
//S1 HIGH | S0 HIGH: high
digitalWrite(TSL230_s1, LOW);
digitalWrite(TSL230_s0, HIGH);
}
float readTSL230(int samples){
//sample light, return reading in frequency
//higher number means brighter
float start = micros();
int readings = 0;
while(readings < samples){
pulseIn(TSL230_Pin, HIGH);
readings ++;
}
float length = micros() - start;
float freq = (1000000 / (length / samples)) * 10;
return freq;
}
First add this to your setup ...
void setup(){
Serial.begin(9600);
setupTSL230();
pinMode(5,OUTPUT);
myservo1.attach(5);
}
Then make a new variable and add it to your if statements
Boolean once; // declare this with your other int variables
if(lightLevel > 800 && lightLevel < 1000 && once==True)
{
myservo1.writeMicroseconds(1300);delay(1000);
myservo1.writeMicroseconds(1500);delay(1000);
once = False;
}
else if(lightLevel<800 && once == False)
{
myservo1.writeMicroseconds(1700);delay(5000);
myservo1.writeMicroseconds(1500);delay(1000);
once = True;
}

Arduinosumo bot with rotatory motor

I am making a sumo bot for a project by using an Arduino. I have no experience with Arduino code, but I do have java experience. That said this bot has an edge detector to prevent it from falling off, a L298 driver, and so forth.
With my lack of experience, I don't know exactly how Arduino's code works with methods and etc. That said, my main question is how is it executing my methods with the delays? Is it getting stuck in the methods with no return? Not entering? Executing be ending later? Currently it seems to just run the motors forward without the switch on or off. I have also checked the wiring. ( I apologize for poor questioning- stackedoverflow virgin).
int motor_forward = 10;
int motor_reverse = 9;
int motor2_forward = 13;
int motor2_reverse = 12;
int edgeDec1 = 7;
//int edgeDec2 = 6;
//the setup routine runs once when you press reset;
void setup(){
//initialize the digital pin as an output.
pinMode(motor_forward, OUTPUT);
pinMode(motor_reverse,OUTPUT);
pinMode(motor2_forward,OUTPUT);
pinMode(motor2_reverse,OUTPUT);
pinMode(edgeDec1,INPUT);
}
//the loop routine runs over and over again forever
void loop(){
int indicator = random(2);
delay(5000);//5 second delay
//loop to prevent another 5 second delay
while(true){
if (indicator = 0){
for(int x = 0; x < random(200); x++){
Forward();
EdgeDec();
delay(10);
}
}
else if ( indicator = 1){
for(int x = 0; x < random(200); x++){
TurnLeft();
EdgeDec();
delay(10);
}
}
else if ( indicator = 2){
for(int x = 0; x < random(200); x++){
TurnRight();
EdgeDec();
delay(10);
}
}
}
}
void Forward(){
//right motor
digitalWrite(motor_forward,1);//terminal d1 will be high
digitalWrite(motor_reverse,0);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,1);//terminal d1 will be high
digitalWrite(motor2_reverse,0);//terminal d2 will be low
}
//going in reverse
void Reverse(){
//right motor
digitalWrite(motor_forward,0);//terminal d1 will be low
digitalWrite(motor_reverse,1);//terminal d2 will be high
//left motor
digitalWrite(motor2_forward,0);//terminal d1 will be low
digitalWrite(motor2_reverse,1);//terminal d2 will be high
}
//rotating left
void TurnLeft(){
//right motor
digitalWrite(motor_forward,0);//terminal d1 will be high
digitalWrite(motor_reverse,1);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,1);//terminal d1 will be high
digitalWrite(motor2_reverse,0);//terminal d2 will be low
}
void TurnRight(){
//right motor
digitalWrite(motor_forward,1);//terminal d1 will be high
digitalWrite(motor_reverse,0);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,0);//terminal d1 will be high
digitalWrite(motor2_reverse,1);//terminal d2 will be low
}
void EdgeDec(){
if(edgeDec1 == 1){
Reverse();
delay(700);
TurnLeft();
delay(1000);
Forward();
}
}
You have a couple of errors/misunderstandings in your code, so I've added a bit of simple debugging that works by opening Tools>Serial Monitor after you've downloaded your code. In your EdgeDec() function (function = Java method) you had if(EdgeDec = 1), but EdgeDec is just an int with the value of 7. What you wanted was to read the value of a pin numbered 7 - if(digitalRead(edgeDec1) == LOW).
also, I reversed your logic from HIGH (1) to LOW (0) because you hadn't tied down the digitalRead pins either LOW (using external resistors) or HIGH (using the Arduino's internal resistors) - read my comments in the code. Not sure what you were doing with the while(true) loop - maybe some further debugging? Anyway, hope it helps...
int motor_forward = 10;
int motor_reverse = 9;
int motor2_forward = 13;
int motor2_reverse = 12;
int edgeDec1 = 7;
//int edgeDec2 = 6;
int indicator; // pulled this out of your loop - askchipbug
String repeatstring; //debugging variable, stops a debug string from repeating in Serial monitor when watching a loop - askchipbug
//the setup routine runs once when you press reset;
void setup(){
Serial.begin(9600); // set up Serial library at 9600 bps, using SerialMonitor to debug - askchipbug
//initialize the digital pin as an output.
pinMode(motor_forward, OUTPUT);
pinMode(motor_reverse,OUTPUT);
pinMode(motor2_forward,OUTPUT);
pinMode(motor2_reverse,OUTPUT);
pinMode(edgeDec1,INPUT_PULLUP); // set this high so it doesn't float about - askchipbug
// you can use the internal 20k pullups with INPUT_PULLUP which means 1 = off, 0 = on
// or you have to use external pulldown resistors to have 1 = on, 0 = off
pr("setup completed"); // askchipbug
}
//the loop routine runs over and over again forever
void loop(){
randomSeed(analogRead(0)); // seeds the random() function with a different number each time the loop runs - askchipbug
indicator = random(2);
pr("indicator: " + String(indicator)); // askchipbug
pr("5 second delay");
delay(5000);//5 second delay
//loop to prevent another 5 second delay
while(true){
if (indicator == 0){ //you had this set as indicator = 0 - askchipbug
pr("indicator: " + String(indicator)); // askchipbug
for(int x = 0; x < random(200); x++){
Forward();
EdgeDec();
delay(10);
}
}
else if ( indicator = 1){
pr("indicator: " + String(indicator)); //askchipbug
for(int x = 0; x < random(200); x++){
TurnLeft();
EdgeDec();
delay(10);
}
}
else if ( indicator = 2){
pr("indicator: " + String(indicator));// askchipbug
for(int x = 0; x < random(200); x++){
TurnRight();
EdgeDec();
delay(10);
}
}
}
}
void Forward(){
//right motor
pr("forward"); //askchipbug
digitalWrite(motor_forward,1);//terminal d1 will be high
digitalWrite(motor_reverse,0);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,1);//terminal d1 will be high
digitalWrite(motor2_reverse,0);//terminal d2 will be low
}
//going in reverse
void Reverse(){
pr("reverse"); //askchipbug
//right motor
digitalWrite(motor_forward,0);//terminal d1 will be low
digitalWrite(motor_reverse,1);//terminal d2 will be high
//left motor
digitalWrite(motor2_forward,0);//terminal d1 will be low
digitalWrite(motor2_reverse,1);//terminal d2 will be high
}
//rotating left
void TurnLeft(){
pr("turn left"); //askchipbug
//right motor
digitalWrite(motor_forward,0);//terminal d1 will be high
digitalWrite(motor_reverse,1);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,1);//terminal d1 will be high
digitalWrite(motor2_reverse,0);//terminal d2 will be low
}
void TurnRight(){
pr("turn right"); //askchipbug
//right motor
digitalWrite(motor_forward,1);//terminal d1 will be high
digitalWrite(motor_reverse,0);//terminal d2 will be low
//left motor
digitalWrite(motor2_forward,0);//terminal d1 will be high
digitalWrite(motor2_reverse,1);//terminal d2 will be low
}
void EdgeDec(){
pr("edge detector: " + String(digitalRead(edgeDec1))); // read pin 7 - askchipbug
if(digitalRead(edgeDec1) == LOW){ // remember we're using the internal pullups so LOW = on - askchipbug
pr("edge detected!"); // askchipbug
Reverse();
delay(700);
TurnLeft();
delay(1000);
Forward();
}
}
//simple debug technique - use pr("something"); in your code - askchipbug
void pr(String txt){
if(repeatstring != txt){
//if the debug text is different, print it
Serial.println(txt); //prints the text and adds a newline
Serial.flush(); //waits for all the data to be printed
delay(1000); //just pauses the scrolling text for 1 second, make bigger if you want a longer pause
repeatstring = txt;
}
}
The delay method in Arduino generally speaking is implemented as just executing a number of nops on the CPU for enough cycles to make up the required delay time. It's essentially a blocking call in that it just completely uses up the CPU for enough time as specified by the argument passed to delay.
For example lets say that your processor is running at 100hz then essentially to delay for 1 second would involve generating 100 nop instructions that the processor would execute. The presumes of course that such an instruction takes exactly 1 clock cycle. Given that the Arduino Uno runs off an ATMEGA328p microprocessor you would want to look at that datasheet to find out more.