Error on PWM output while using ATMega328p-au and Atmel Studio - c++

Hallo everyone,
I am new into AVR programming and I was asked to develop a board which could read out the values of an analog sensor and set a PWM output. The design included a potentiometer, to act as a percentage dimmer between two PWM signals.
As my programming experience is only in the Arduino IDE, when migrating to Atmel Studio 7 I used the import Arduino Code option and proceed with ISP programming using Atmel ICE.
The model itself is composed of two analog signals (sensor and potentiometer) and 4 pwm outputs (two pairs of signals). Moreover, the code is based on a basic State Machine:
1) Read Sensor and Potentiometer, which determines the PWM output value.
2) Case 1: increase the PWM output value
3) Case 2: decrese the PWM output value
4) Case 3: mantain the PWM output value
However, whenever I put the sensor under my Lamp (controlled by the PWM) it starts to flicker and I can not reach a "stable state". My posible solution would be read out the sensor's value and have an average between the highest and lower value, which will be later used to set the PWM output level and a second one would be using interrumptions but I do not know how to implement them.
Note: the frequency is set to 10 MHz because I am using 3,3 V, so the cristal was selected according to the input value
/*Begining of Auto generated code by Atmel studio */
#define F_CPU 10000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <Arduino.h>
/*End of auto generated code by Atmel studio */
//Pinout
const int C1 = 9; // Select the pin for Channel 1 PWM Dimming (Sunrise)
const int C2 = 6; // Select the pin for Channel 2 PWM Dimming (Daylight)
const int C3 = 5; // Select the pin for Channel 3 PWM Dimming (Sunrise 2)
const int C4 = 3; // Select the pin for Channel 4 PWM Dimming (Daylight 2)
const int CM = A1; // Select the pin for the color mixer (Potentiometer)
const int ALS = A0; // Select the pin for the ALS signal
//Variables
int ch = 0; // Current PWM level
int count = 0;
float ch1 = 0; // Color mixer factor of the Channel 1 and 3 PWM (0% - 100%)
float ch2 = 0; // Color mixer factor of the Channel 2 and 4 PWM (0% - 100%)
int mixer = 0; // Potentiometer value
int pwm = 0; // PWM counter
int th = 200; // Threshold value (light sensitivity)
int als = 0; // Stores the value of the ALS
int mst = 0; // Maschine state
int sum = 0; // Average ALS value
int sum2 = 0; // Average trimmer value
int wait = 100; // Delay value
int f = 0; //1 Machine State counter
int i = 0; //2 Machine State counter
//Setup
void setup() {
// I/O Pins
pinMode(C1, OUTPUT);
pinMode(C2, OUTPUT);
pinMode(C3, OUTPUT);
pinMode(C4, OUTPUT);
pinMode(ALS, INPUT);
pinMode(CM, INPUT);
// Set PWM outputs to LOW
analogWrite(C1, ch1);
analogWrite(C2, ch2);
analogWrite(C3, ch1);
analogWrite(C4, ch2);
//Serial.begin(9600);
}
void loop() {
//State machine init
switch(mst){
case 0:
// Read the value from the Ambient Light Sensor and the Mixer Pin
for(int i =0; i<wait; i++){
delay(0.00001);
als = analogRead(ALS);
sum = als + sum;
}
// Obtain an average ALS value
sum = sum/wait;
mixer = analogRead(CM);
//Serial.println(sum2);
if(sum > th) {
sum = th;
}
if(mixer >= 1000) {
mixer = 1000;
} else {
}
// Re-map average value to PWM level (0-255 == 0-100%)
pwm = map(sum, 0, th, 255, 0);
//Declare the color mixer percentage
if((mixer>=0)&&(mixer<512)){
ch1 = 100;
ch2 = (100*mixer)/512;
} else if(mixer<1022) {
ch1 = map(mixer, 512, 1000, 100, 0);
ch2 = 100;
} else {
ch1 = 0;
ch2 = 100;
}
//Serial.print(mixer);
ch1 = ch1/100;
ch2 = ch2/100;
//Increase PWM
if(ch<pwm-5){
mst = 1;
}
//Change to the second stage
if(ch>pwm+5){
mst = 2;
}
//Change to third stage
if((ch > pwm-5) && (ch < pwm+5)){
mst = 3;
}
delay(0.000001);
break;
case 1: //Current PWM level less than the actual ALS value
//Compare PWM and ch1 to make a gradual change
count = ch+3;
if (count > 255)
{
count = 255;
}
ch = count;
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
delay(0.0000001);
//Return to initial state
mst = 0;
break;
case 2: //Current PWM level greater than the actual ALS value
//Compare PWM and ch1 to make a gradual change
count = ch-3;
if (count < 0)
{
count = 0;
}
ch = count;
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
delay(0.0000001);
//Return to initial state
mst = 0;
break;
case 3: //Current PWM level equal than the actual ALS value
//Keep tha output value
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
//Return to initial state (Read ALS & Trimmer)
mst = 0;
delay(0.0000001);
break;
default:
//Empty
break;
}
}

Related

How do I use an arduino as an LED controller?

I'm a total C++ newbie, but I recently got an arduino and I'm doing my first project with it. I may be jumping into the deep end here, but I've got some experience with electronics already. I also have some experience with python.
I want to make a fancy interior lighting setup using two of these led strips and this arduino starter kit.
I need to make a whole bunch of presets that can be quickly activated using the IR remote included with the kit.
I need to be able to split the strips into individual zones , which I can use to easily set the presets. Maybe I want preset1 to be the ceiling lights a dark blue at 50% brightness and the window lights an orange at 25% brightness.
I know that to achieve this I want every button on the remote to call a different function. I've written some Psuedocode and I'd like some advice on the best way to learn how to implement this on an arduino.
I really need help with the software side of this project, the hardware side is all good.
disclaimer: I haven't touched coding since high school, so my psuedocode is probably trash. I just hope it's vaguely understandable
//Psuedocode attempt to make an LED thingy
// Importing needed libraries
Import fastled
Import IRremote
define num_led 300
define data_pin 5
// defining various zones. Zone 1 = Under cabinet, Zone 2 = Around window etc.
Global zone1 = num_led [0:24]
Global zone2 = num_led [24:172]
Global zone3 = num_led [173:277]
Global zone4 = num_led [278:299]
Def preset1()
for led in zone1:
ledRGB = (160, 0, 210)
for led in zone2:
ledRGB = (120, 0, 24)
for led in zone3:
ledRGB = (0, 0, 0)
for led in zone4:
ledRGB = (100,100,100)
// Make a whole bunch more of these normal presets
Def preset6()
for led in zone1:
do cool fastled animation
for led in zone2:
do different fastled animation
for led in zone3:
ledRGB = (0, 0, 0)
for led in zone4:
ledRGB = (0, 0, 0)
// Make a whole bunch more of these fancy presets
Def BrightnessUp()
i = 0
for num_led in zone1 and zone2 and zone3 and zone4:
if i in ledRGB > 0: //This is to minimise colour shift. Any RGB channel set at 0 won’t increase.
i = i+10
else:
return
// Similar for brightness down
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
{
//The following is mostly copy pasted C++ code with modifications
//It works to understand the IR remote inputs and call functions based on input
const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
void setup(){
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop(){
if (irrecv.decode(&results)){
if (results.value == 0XFFFFFFFF)
results.value = key_value;
switch(results.value)
case 0xFF30CF:
Serial.println("1");
Call preset1()
break ;
case 0xFF18E7:
Serial.println("2");
Call preset2()
break ;
case 0xFF7A85:
Serial.println("3");
Call preset3()
break ;
//ETC for every number on remote
case 0xFFE01F:
Serial.println("-");
Call BrigtnessDown()
break ;
case 0xFFA857:
Serial.println("+");
Call BrightnessUp()
break ;
}
key_value = results.value;
irrecv.resume();
}
}
Steps to be followed are
Install the FastLED Library from GitHub: FastLED Lib
Install the IRremote Library from GitHub: IRremote Lib
Import it to your Arduino library folder via Arduino IDE: Importing a .zip Library
Here is a basic structure of the program which we will require.
#include "FastLED.h"
#include "IRremote.h"
#define DATA_PIN 5 // digital pin of your arduino
#define NUM_LEDS 300
CRGB leds[NUM_LEDS];
//Zones array
int zone1[2] = {0, 24}; //For zone1: Start,End
int zone2[2] = {25, 172}; //For zone2: Start,End
int zone3[2] = {173, 277}; //For zone3: Start,End
int zone4[2] = {278, 299}; //For zone4: Start,End
// For IR receiver
const int RECV_PIN = 3; // Hardware specs allows 3 or 9 pin to be used for ATmega328p
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
//Setup for FastLED
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
//Setup for IRremote
pinMode(LED_BUILTIN, OUTPUT); //LED_BUILTIN is the inbuild led on Arduino UNO at Pin13
irrecv.enableIRIn(); // Start the receiver
irrecv.blink13(true); // Enable blinking the LED when during reception
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
switch (results.value) {
case 0xFF30CF:
Serial.println("1");
preset1();
break;
case 0xFF18E7:
Serial.println("2");
//preset2(); //TODO: Complete this preset2
break;
case 0xFF7A85:
Serial.println("3");
//preset3(); //TODO: Complete this preset3
break;
//ETC for every number on remote
case 0xFFE01F:
Serial.println("-");
brightnessDown();
break;
case 0xFFA857:
Serial.println("+");
brightnessUp();
break;
default:
Serial.println("Not Understood.");
break;
}
irrecv.resume(); // Receive the next value
}
delay(100);
}
void preset1()
{
//Zone 1
for (int i = zone1[0]; i <= zone1[1]; i++) {
leds[i] = CRGB(160, 0, 210);
}
//Zone 2
for (int i = zone2[0]; i <= zone2[1]; i++) {
leds[i] = CRGB(120, 0, 24);
}
//Zone 3
for (int i = zone3[0]; i <= zone3[1]; i++) {
leds[i] = CRGB(0, 0, 0);
}
//Zone 4
for (int i = zone4[0]; i <= zone4[1]; i++) {
leds[i] = CRGB(100, 100, 100);
}
//To set the LEDs
FastLED.show();
}
void brightnessUp()
{
for (int i = 0; i < NUM_LEDS; i++) {
if (leds[i].r > 0)
leds[i].r = leds[i].r + 10;
if (leds[i].g > 0)
leds[i].g = leds[i].g + 10;
if (leds[i].b > 0)
leds[i].b = leds[i].b + 10;
}
//To set the LEDs
FastLED.show();
}
void brightnessDown()
{
for (int i = 0; i < NUM_LEDS; i++) {
if (leds[i].r > 10)
leds[i].r = leds[i].r - 10;
if (leds[i].g > 10)
leds[i].g = leds[i].g - 10;
if (leds[i].b > 10)
leds[i].b = leds[i].b - 10;
}
//To set the LEDs
FastLED.show();
}
Note: This code this created with the help of Pseudo-code provided and the logic implemented in it, you may have to change certain things in order for it to produce best results.

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.