Problem with a Arduino exercise and state - arduino

In this part of the code, I need to turn on two leds if the button is pressed for a continuous period of time of over 2 seconds. I need this code for a complexer exercise but I can't understand why it won't pass to etat_choix. (code right below)
const int ledmode1 = 10;
const int ledmode2 = 11;
const int buttonin = 4;
const int eteint = 0;
const int etat_choix = 1;
bool etat = 0;
bool debut = 0;
bool old_buttonin = 0;
unsigned long temps = 0;
unsigned long time1 = 0;
void setup()
{
pinMode(ledmode1, OUTPUT);
pinMode(ledmode2, OUTPUT);
pinMode(buttonin,INPUT);
}
void loop() {
temps = millis();
if (etat == eteint){
old_buttonin = buttonin;
if (buttonin == HIGH and debut == 0) {
time1 = millis();
}
if (buttonin == HIGH) {
debut = 1;
}
else if (old_buttonin == HIGH and buttonin == LOW ){
debut = 0;
}
if ( temps > time1 + 2000 and debut == 1) {
etat = etat_choix;
time1 = 0;
debut = 0;
}
}
else if (etat == etat_choix) {
digitalWrite(ledmode1,HIGH);
digitalWrite(ledmode2,HIGH);
}

Related

Question on Two servo project activated by timer and water level sensor

I am using a arduino uno in an attempt to power two servos. Servo A should open for a couple seconds every 24 hours OR if button A is pressed. Servo B should open for a couple seconds if the water level sensor reads below 300 OR if button B is pressed. The code below works fine when I only include one servo, but adding the code for servo B ruins everything.
#include <Servo.h>
Servo myservoA;
Servo myservoB;
const int BUTTONA_PIN = 8;
const int BUTTONB_PIN = 6;
const int SERVOA_PIN = 9;
const int SERVOB_PIN = 7;
unsigned long dayTimer_ms = 0;
unsigned long autoOpenDelay_ms = 86400000;
int angle = 0;
int waterSensor = A0;
int waterLevel = 0;
void setup(){
myservoA.attach(SERVOA_PIN);
myservoB.attach(SERVOB_PIN);
pinMode(BUTTONA_PIN, INPUT_PULLUP);
pinMode(BUTTONB_PIN, INPUT_PULLUP);
myservoA.write(0);
myservoB.write(0);
}
void loop() {
if(millis() - dayTimer_ms > autoOpenDelay_ms)
{
dayTimer_ms = millis();
myservoA.write(180); //(open?)
delay(8000);
myservoA.write(0);
}
if(millis()<dayTimer_ms)//overflow handling (in case this runs for more than 50 days straight)
{
dayTimer_ms = millis();
}
if (!digitalRead(BUTTONA_PIN) && angle != 180)
{
angle = 180;
myservoA.write(angle);
}
if (digitalRead(BUTTONA_PIN) && angle != 0)
{
angle = 0;
myservoA.write(angle);
}
if (!digitalRead(BUTTONB_PIN) && angle != 180)
{
angle = 180;
myservoB.write(angle);
}
if (digitalRead(BUTTONB_PIN) && angle != 0)
{
angle = 0;
myservoB.write(angle);
}
int waterLevel = analogRead(waterSensor);
if (waterLevel <= 300){
myservoB.write(180);
delay(8000);
myservoB.write(0);
}
}
You are actually super close!
You just need to make a second variable to track angleA separately from angleB. So you should initialize another variable at the top "angleB" to zero and then replace "angle" with this new variable everywhere below line 52
#include <Servo.h>
Servo myservoA;
Servo myservoB;
const int BUTTONA_PIN = 8;
const int BUTTONB_PIN = 6;
const int SERVOA_PIN = 9;
const int SERVOB_PIN = 7;
unsigned long dayTimer_ms = 0;
unsigned long autoOpenDelay_ms = 86400000;
int angleA = 0;
int angleB = 0;
int waterSensor = A0;
int waterLevel = 0;
void setup(){
myservoA.attach(SERVOA_PIN);
myservoB.attach(SERVOB_PIN);
pinMode(BUTTONA_PIN, INPUT_PULLUP);
pinMode(BUTTONB_PIN, INPUT_PULLUP);
myservoA.write(0);
myservoB.write(0);
}
void loop() {
if(millis() - dayTimer_ms > autoOpenDelay_ms)
{
dayTimer_ms = millis();
myservoA.write(180); //(open?)
delay(8000);
myservoA.write(0);
angleA = 0;
}
if(millis()<dayTimer_ms)//overflow handling (in case this runs for more than 50 days straight)
{
dayTimer_ms = millis();
}
if (!digitalRead(BUTTONA_PIN) && angleA != 180)
{
angleA = 180;
myservoA.write(angleA);
}
if (digitalRead(BUTTONA_PIN) && angleA != 0)
{
angleA = 0;
myservoA.write(angleA);
}
if (!digitalRead(BUTTONB_PIN) && angleB != 180)
{
angleB = 180;
myservoB.write(angleB);
}
if (digitalRead(BUTTONB_PIN) && angleB != 0)
{
angleB = 0;
myservoB.write(angleB);
}
int waterLevel = analogRead(waterSensor);
if (waterLevel > 300 && angleB != 0)
{
myservoB.write(0);
angleB = 0;
}
else if (waterLevel < 200 && angleB != 180){
myservoB.write(180);
angleB = 180;
}
}
the bottom two levels may need to be adjusted (200 and 300). Basically this creates a slight de-bounce. By separating the levels at which the water turns on and turns off, it keeps the system from jittering right at the limit (constantly turning on and off). That being said, depending on the accuracy of your sensor and how important precise level control is in your application, you may want to tighten or move these values around a bit.

Arduino hardware interrupt reliability issue

This may seem like a foolish problem and maybe its description is not the best I could have devised.
I am making a velocity sensor that uses two IR beams to calculate velocity based on the time it takes to break both beams.
I have two testing methods.
My hand (5-10 m/s)
A high speed cannon (30-60 m/s).
I have ruled out that it's a problem with the signal from the IR beams with an oscilloscope, when the code fails/works the data is identical on the scope.
My problem is that my code works when I use my hand, but still irregularly fails, while it fails more often at high speed. All the conditions are the same in both scenarios. What could be the issue?
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>
const int rs = 9, en = 8, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
File root;
int fileNo = 0;
String currentFileName;
const int CS = 10;
const byte interruptPinStart = 2;
const byte interruptPinFinish = 3;
volatile unsigned long int startTimeMillis = 0;
volatile unsigned long int stopTimeMillis = 0;
volatile unsigned long int startTimeMicros = 0;
volatile unsigned long int stopTimeMicros = 0;
volatile unsigned long int microsDifference = 0;
volatile unsigned long int millisDifference = 0;
int launchNo = 0;
float currentVelocity = 0;
volatile boolean started = false;
String inputString = "";
boolean stringComplete = false;
const int txLed1 = 14;
const int statusLed1 = 15;
const int statusLed2 = 16;
volatile boolean triggerDone = false;
float velocity = 0;
String temp;
unsigned long int lockout = 0;
boolean lockedOut = false;
boolean fileFail = false;
int testNo = 0;
void setup() {
inputString.reserve(200);
pinMode(statusLed1, OUTPUT);
pinMode(statusLed2, OUTPUT);
pinMode(txLed1, OUTPUT);
Serial.begin(9600);
while (!Serial) {
;
}
lcd.begin(16, 2);
pinMode(interruptPinStart, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPinStart), startTrigger, RISING);
pinMode(interruptPinFinish, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPinFinish), stopTrigger, RISING);
Serial.print("Initializing SD card...");
if (!SD.begin(CS)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
root = SD.open("/");
newDirectory(root);
Serial.println("done!");
lcd.clear();
lcd.print(currentFileName);
tone(txLed1, 38000);
}
void loop() {
int millsDiff = millis() - stopTimeMillis;
if (triggerDone) {
lockedOut = true;
Serial.print("Micros Diffrence: ");
Serial.println(microsDifference);
Serial.print("Millis Difference: ");
Serial.println(millisDifference);
float millDiff = (float) millisDifference;
float microDiff = (float) microsDifference;
if (microDiff > 0) {
velocity = (float) 0.09 / (microDiff/1000000);
testNo++;
temp = String(launchNo) + "%" + String(microsDifference) + "%" + String(velocity);
if (velocity > 10.0) {
root = SD.open(currentFileName, FILE_WRITE);
if (root) {
root.println(temp);
root.close();
Serial.println(temp);
launchNo++;
} else {
Serial.println("error opening file, " + currentFileName);
fileFail = true;
}
}
if (fileFail) {
lcd.clear();
lcd.print("File Error");
lcd.setCursor(0, 1);
lcd.print("Vel " + String(launchNo) + ": " + String(velocity) + " m/s");
fileFail = false;
} else {
lcd.clear();
lcd.print("Test Number: " + String(testNo));
lcd.setCursor(0, 1);
lcd.print("Vel " + String(launchNo) + ": " + String(velocity) + " m/s");
}
}
triggerDone = false;
Serial.println("Test Number: " + String(testNo));
}
if (digitalRead(interruptPinStart) == LOW) {
digitalWrite(statusLed1, HIGH);
} else {
digitalWrite(statusLed1, LOW);
}
if (digitalRead(interruptPinFinish) == LOW) {
digitalWrite(statusLed2, HIGH);
} else {
digitalWrite(statusLed2, LOW);
}
}
void startTrigger() {
startTimeMicros = micros();
startTimeMillis = millis();
volatile int diff1 = startTimeMicros - startTimeMillis;
volatile int diff2 = startTimeMillis - stopTimeMillis;
if (diff2 > 200) {
if (started == false || diff1 > 1000) {
started = true;
triggerDone = false;
}
}
}
void stopTrigger() {
stopTimeMicros = micros();
stopTimeMillis = millis();
microsDifference = stopTimeMicros - startTimeMicros;
millisDifference = stopTimeMillis - startTimeMillis;
if ((millisDifference > 0 && millisDifference < 800) && started) {
microsDifference = stopTimeMicros - startTimeMicros;
millisDifference = stopTimeMillis - startTimeMillis;
started = false;
triggerDone = true;
}
}

I can't print number inside an array in Arduino

I want to print value in an array (array name Array_index) which I write of variable name bit_1. But when I tried to enter inside this array, the value always show zero. Please advise me how to do a correct way in Arduino.
This is my code:
int test_number = 0;
unsigned int Array_index[] = {};
int bit_1 = 0;
int Andbit = 0;
int arrSize = 0;
void setup()
{
Serial.begin( 9600 );
}
void loop()
{
int count = 0;
test_number = random(10);
Serial.println(test_number);
for (bit_1 = 0; bit_1 <= 15; bit_1++)
{
Andbit = test_number & 1;
if (Andbit == 1)
{
Array_index[count] = bit_1;
//Serial.println(Array_index[count]);
count=count++;
}
else
{
}
test_number = test_number >> 1;
int arrSize = sizeof(Array_index) / sizeof( int );
Serial.println(arrSize);
for (int y = 0; y < arrSize; y++)
{
Serial.println(Array_index[y]);
}
}
while(1)
{
}
}
unsigned int Array_index[] = {}; is an array with 0 elements.
You should define it as unsigned int Array_index[16];.

Storing the value read previously until new pulse

I'm currently doing a project on an Arduino Uno. The project is based on receiving an IR Signal from an IR Remote and then based on the signal received, perform other operations.
The problem is that the signal gets reset every time. I want to store the value received from the IR Remote and then resets it if detects another pulse.
Here is my code :
int brojac = 0;
int pinData = 10;
unsigned long lengthHeader;
unsigned long bit;
int byteValue;
int vrime = 1000 ;
int storeValue = 0;
void setup()
{
Serial.begin(9600);
pinMode(pinData, INPUT);
}
void loop() {
lengthHeader = pulseIn(pinData, LOW);
if (lengthHeader > 1500)
{
for (int i = 1; i <= 32; i++) {
bit = pulseIn(pinData, HIGH);
if (i > 16 && i <= 24)
if (bit > 1000)
byteValue = byteValue + (1 << (i - 17));
}
}
Serial.print("byteValue = ");
Serial.println(byteValue);
if(byteValue == 66){
digitalWrite(11,HIGH);
}
else{
digitalWrite(11,LOW);
}
delay(vrime);
byteValue = 0;
delay(250);
}
I got the answer by storing the value in a variable until a new variable is detected.
int pinData = 10;
int led = 11;
unsigned long lengthHeader;
unsigned long bit;
int byteValue;
int storeValue = 0;
int previousValue = 0;
void setup()
{
Serial.begin(9600);
pinMode(pinData, INPUT);
pinMode(led, LOW);
}
void loop() {
lengthHeader = pulseIn(pinData, LOW);
if (lengthHeader > 1500)
{
for (int i = 1; i <= 32; i++) {
bit = pulseIn(pinData, HIGH);
if (i > 16 && i <= 24)
if (bit > 1000)
byteValue = byteValue + (1 << (i - 17));
}
}
Serial.print("byteValue = ");
Serial.println(byteValue);
**storeValue = byteValue;
if (storeValue != 0){
previousValue = storeValue;
}
Serial.print("Previous value = ");
Serial.println(previousValue);**
byteValue = 0;
delay(500);
}

arduino interrupt variable not working

I am a beginner with arduino and I'm trying to make a sinus wave generator. Since I've recently found I can't put everything into main void loop, I'm trying to use interrupts. I have problem with changing variable inside of the interrupt (Delay), I don't know where's the mistake.
Here is my code:
int sine256[] = { //256 sin values from 0 to 2pi
};
int i = 0;
int sensorPin = 7;
int outputPin = 6;
volatile float Delay = 10000;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(sensorPin), freq, RISING);
}
void loop()
{
analogWrite(6,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
Serial.println(Delay);
delayMicroseconds(Delay);
}
void freq() {
Delay = Delay/2;
}
EDIT
Try this:
int sine256[] = { //256 sin values from 0 to 2pi
};
int i = 0;
int sensorPin = 7;
int outputPin = 6;
volatile float Delay = 10000;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT);
//attachInterrupt(digitalPinToInterrupt(sensorPin), freq, RISING);
}
void loop()
{
analogWrite(6,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
Serial.println(Delay);
freq();
delay(Delay);
}
void freq() {
Delay = Delay / 2;
}
https://www.arduino.cc/en/Reference/AttachInterrupt
Try taking a look at that.
What model are you using?
The only thing that causes me troubles now is the button; when i press it, it often respond as if i had pressed the button multiple times (2,3 or 4x).
This is my final code for now. Since the execution time for a void loop is 12 microseconds, i've calculated delay required to run a generator on 20,40 & 60Hz.
int sine256[] = { //256 sin values from 0 to 2pi (from 0 to 255)
int i = 0;
int sensorPin = 2;
volatile int outputPin = 7;
volatile float Delay = 1000;
int time1;
int time2;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), freq, FALLING);
}
void loop()
{
//time1 = micros();
analogWrite(outputPin,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
//time2 = micros();
//Serial.println(time2 - time1);
delay(Delay);
}
void freq() {
outputPin = 6;
if(Delay == 0.02){
analogWrite(6,LOW);
outputPin = 7;
Delay = 1000;
}
if(Delay == 0.04){
Delay = 0.02;
}
if(Delay == 0.09){
Delay = 0.04;
}
if((Delay == 1000)&&(outputPin == 6)){
Delay = 0.09;
}
Serial.println(Delay);
}

Resources