Arduino hardware interrupt reliability issue - arduino

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;
}
}

Related

How can I get out of the loop?

I'd like to get out of the loop in my Arduino project. Currently I am programming a digital watch, everything works just fine but I wanted to add options menu by clicking a button, but after clicking it nothing pops up even if I have something inside the code. Take a look at it. I don't know how to write it better. If you have some ideas, please you could rewrite some parts of the code and explain why you did so. Thanks forwardly.
Please do not mind s = s + 1, I wanted it like that.
#include "LiquidCrystal.h"
#include <EEPROM.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int h = 0;
int m = 0;
int s = 0;
int right = 8;
int left = 9;
int buttonStateLeft = 0;
String when;
uint8_t EEPROMaddress_sec = 1;
uint8_t EEPROMaddress_min = 2;
uint8_t EEPROMaddress_hour = 3;
bool clockShown = true;
bool menuShown = false;
void setup()
{
lcd.begin(16,2);
pinMode(right, INPUT);
pinMode(left, INPUT);
}
void loop()
{
if(menuShown)
{
lcd.setCursor(0,0);
lcd.print("jozo je kkt");
delay(200);
}
if(clockShown) {
lcd.setCursor(0,0);
buttonStateLeft = digitalRead(left);
if(buttonStateLeft == HIGH)
{
clockShown = false;
menuShown = true;
lcd.clear();
}
s = EEPROM.read(EEPROMaddress_sec);
m = EEPROM.read(EEPROMaddress_min);
h = EEPROM.read(EEPROMaddress_hour);
s = s + 1;
if(h > 12)
when = "PM";
if(h < 12)
when = "AM";
if(h == 12)
when = "PM";
lcd.print("Cas: ");
if(h<10)lcd.print("0");
lcd.print(h);
lcd.print(":");
if(m<10)lcd.print("0");
lcd.print(m);
lcd.print(":");
if(s<10)lcd.print("0");
lcd.print(s);
lcd.print(" ");
lcd.print(when);
if(s == 60)
{
s = 0;
m = m+1;
}
if(m == 60)
{
s = 0;
m = 0;
h = h+1;
}
if(h == 24)
{
m = 0;
s = 0;
h = 0;
}
EEPROM.write(EEPROMaddress_sec, s);
EEPROM.write(EEPROMaddress_min, m);
EEPROM.write(EEPROMaddress_hour, h);
delay(1000);
}
}
In order to do that you will have to use Interrupts, note that you must connect your button to an interrupt pin (not every pin is an interrupt pin) you can google "what are the interrupt pins of 'your_card_name' ", the code would have to change, you can follow these :
In the setup function replace :
pinMode(left, INPUT);
by :
attachInterrupt(digitalPinToInterrupt(left), switchMode, RISING);
add this function before setup(){...}
int lastPressTime=millis();
void switchMode(){ // function called when the button is pressed
if((millis()-lastPressTime)>60){ // for debouncing
clockShown = false;
menuShown = true;
lcd.clear();
lastPressTime=millis();
}
}
and remove this part from your code : (the one in the loop() function)
buttonStateLeft = digitalRead(left);
if(buttonStateLeft == HIGH)
{
clockShown = false;
menuShown = true;
lcd.clear();
}

Arduino LED Controller hanging at startup

I'm trying to code an LED controller that controls the intensity via PWM. However, my issue is that I can't even get to the loop portion, it seems to hang at when I declare my class. I've tried checking to see if any of my functions in my class are causing the issues, but since I can't even get to loop, there must be something wrong within the class. I've written the class and placed it into a library called LED.
The code is somewhat long, but here it is:
#ifndef LED_H
#define LED_H
#include <LiquidCrystal.h>
#include <Button.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <PWM.h>
class LED
{
public:
LED();
int read_encoder(); //Reads rotary encoder
void clearLCD();
void setAllLed();
void printLCD();
void setOneLed(int);
int setLed(int, // current time in minutes
int, // pin for this channel of LEDs
int, // start time for this channel of LEDs
int, // photoperiod for this channel of LEDs
int, // fade duration for this channel of LEDs
int, // max value for this channel
bool // true if the channel is inverted
);
void menuWizard();
int subMenuWizard(int, int, bool, bool);
void displayMainMenu();
void printMins(int, bool);
void printHMS(byte,byte,byte);
long EEPROMReadlong(long);
void EEPROMWritelong(int, long);
bool pressSelect();
bool pressBack();
void rotateCheck(int&, int, int);
//variables for the LED channels
int minCounter = 0; // counter that resets at midnight.
int oldMinCounter = 0; // counter that resets at midnight.
int ledPins[5]={2,3,5,6,7};
int ledVal[5]={0,0,0,0,0};
// Variables making use of EEPROM memory:
int variablesList[20];
bool invertedLEDs[5]={false,false,false,false,false};
//Backlight Variables
unsigned long backlightIdleMs = 0;
private:
};
#endif // LED_H
And here is the .cpp file:
#define LCD_RS 35 // RS pin
#define LCD_ENABLE 34 // enable pin
#define LCD_DATA4 33 // d4 pin
#define LCD_DATA5 32 // d5 pin
#define LCD_DATA6 31 // d6 pin
#define LCD_DATA7 30 // d7 pin
#define LCD_BACKLIGHT 9 // backlight pin
// Backlight config
#define BACKLIGHT_DIM 10 // PWM value for backlight at idle
#define BACKLIGHT_ON 70 // PWM value for backlight when on
#define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
#include <LiquidCrystal.h>
#include <Button.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <PWM.h>
#include "LED.h"
LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_DATA4, LCD_DATA5, LCD_DATA6, LCD_DATA7);
Button goBack=Button(12, PULLDOWN);
Button select=Button(13, PULLDOWN);
LED::LED()
{
InitTimersSafe();
pinMode(LCD_BACKLIGHT, OUTPUT);
lcd.begin(16, 2);
digitalWrite(LCD_BACKLIGHT, HIGH);
lcd.print("sEx LED, V1");
clearLCD();
delay(5000);
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
if (variablesList[0] > 1440 || variablesList[0] < 0) {
variablesList[0] = 720; // minute to start this channel.
variablesList[1] = 400; // photoperiod in minutes for this channel.
variablesList[2] = 100; // max intensity for this channel, as a percentage
variablesList[3] = 100; // duration of the fade on and off for sunrise and sunset for
// this channel.
variablesList[4] = 720;
variablesList[5] = 400;
variablesList[6] = 100;
variablesList[7] = 100;
variablesList[8] = 720;
variablesList[9] = 400;
variablesList[10] = 100;
variablesList[11] = 100;
variablesList[12] = 720;
variablesList[13] = 400;
variablesList[14] = 100;
variablesList[15] = 100;
variablesList[16] = 720;
variablesList[17] = 400;
variablesList[18] = 100;
variablesList[19] = 100;
}
else {
variablesList[0] = EEPROMReadlong(0); // minute to start this channel.
variablesList[1] = EEPROMReadlong(4); // photoperiod in minutes for this channel.
variablesList[2] = EEPROMReadlong(8); // max intensity for this channel, as a percentage
variablesList[3] = EEPROMReadlong(12); // duration of the fade on and off for sunrise and sunset for
// this channel.
variablesList[4] = EEPROMReadlong(16);
variablesList[5] = EEPROMReadlong(20);
variablesList[6] = EEPROMReadlong(24);
variablesList[7] = EEPROMReadlong(28);
variablesList[8] = EEPROMReadlong(32);
variablesList[9] = EEPROMReadlong(36);
variablesList[10] = EEPROMReadlong(40);
variablesList[11] = EEPROMReadlong(44);
variablesList[12] = EEPROMReadlong(48);
variablesList[13] = EEPROMReadlong(52);
variablesList[14] = EEPROMReadlong(56);
variablesList[15] = EEPROMReadlong(60);
variablesList[16] = EEPROMReadlong(64);
variablesList[17] = EEPROMReadlong(68);
variablesList[18] = EEPROMReadlong(72);
variablesList[19] = EEPROMReadlong(76);
}
}
void LED::printLCD(){lcd.print("test");clearLCD();delay(2000);lcd.print("testing");clearLCD();}
bool LED::pressSelect(){
if (select.uniquePress()){return 1;}
else {return 0;}
}
bool LED::pressBack(){
if (goBack.uniquePress()){return 1;}
else {return 0;}
}
void LED::clearLCD(){
lcd.clear();
}
void LED::displayMainMenu(){
oldMinCounter = minCounter;
minCounter = hour() * 60 + minute();
for (int i=0;i<17;i=i+4){
if (variablesList[i+3] > variablesList[i+1] / 2 && variablesList[i+1] > 0) {
variablesList[i+3] = variablesList[i+1] / 2;
}
if (variablesList[i+3] < 1) {
variablesList[i+3] = 1;
}
}
//check & set any time functions
if (minCounter > oldMinCounter) {
lcd.clear();
}
lcd.setCursor(0, 0);
printHMS(hour(), minute(), second());
lcd.setCursor(0, 1);
lcd.print(ledVal[0]);
lcd.setCursor(4, 1);
lcd.print(ledVal[1]);
lcd.setCursor(8, 1);
lcd.print(ledVal[2]);
}
int LED::read_encoder()
{
static int enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static int old_AB = 0;
/**/
old_AB <<= 2; //remember previous state
old_AB |= ( ENC_PORT & 0x03 ); //add current state
return ( enc_states[( old_AB & 0x0f )]);
}
int LED::setLed(int mins, // current time in minutes
int ledPin, // pin for this channel of LEDs
int start, // start time for this channel of LEDs
int period, // photoperiod for this channel of LEDs
int fade, // fade duration for this channel of LEDs
int ledMax, // max value for this channel
bool inverted // true if the channel is inverted
) {
int val = 0;
//fade up
if (mins > start || mins <= start + fade) {
val = map(mins - start, 0, fade, 0, ledMax);
}
//fade down
if (mins > start + period - fade && mins <= start + period) {
val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
}
//off or post-midnight run.
if (mins <= start || mins > start + period) {
if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
{
val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
}
else
val = 0;
}
if (val > ledMax) {
val = ledMax;
}
if (val < 0) {
val = 0;
}
if (inverted) {
pwmWrite(ledPin, map(val, 0, 100, 255, 0));
}
else {
pwmWrite(ledPin, map(val, 0, 100, 0, 255));
}
return val;
}
void LED::printMins(int mins, //time in minutes to print
bool ampm //print am/pm?
) {
int hr = (mins % 1440) / 60;
int mn = mins % 60;
if (hr < 10) {
lcd.print(" ");
}
lcd.print(hr);
lcd.print(":");
if (mn < 10) {
lcd.print("0");
}
lcd.print(mn);
}
void LED::printHMS (byte hr,
byte mn,
byte sec //time to print
)
{
if (hr < 10) {
lcd.print(" ");
}
lcd.print(hr, DEC);
lcd.print(":");
if (mn < 10) {
lcd.print("0");
}
lcd.print(mn, DEC);
lcd.print(":");
if (sec < 10) {
lcd.print("0");
}
lcd.print(sec, DEC);
}
//EEPROM write functions
long LED::EEPROMReadlong(long address)
{
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
void LED::EEPROMWritelong(int address, long value)
{
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
void LED::setAllLed(){
int j=0;
for (int i=0;i<17;i=i+4){
int a=i;int b=i+1;int c=i+2;int d=i+3;
ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);
j++;
}
}
void LED::setOneLed(int channel){
int j=channel;
int i=0;
if(channel==1){i+=4;}
if(channel==2){i+=8;}
if(channel==3){i+=12;}
if(channel==4){i+=16;}
int a=i;int b=i+1;int c=i+2;int d=i+3;
ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);
}
void LED::rotateCheck(int& menuCount, int minMenu, int maxMenu){
while (menuCount!=0){
int rotateCount;
rotateCount=read_encoder();
if (rotateCount) {
menuCount+=rotateCount;
if (menuCount<minMenu){menuCount==maxMenu;}
if (menuCount>maxMenu){menuCount==minMenu;}
clearLCD();
}
}
}
void LED::menuWizard(){
int menuCount=1;
String menuList[6]={"Time","LED Max","LED Start","LED End","Fade Length","Ch Override"};
String channelList[5]={"1","2","3","4","5"};
while (menuCount!=0){
rotateCheck(menuCount,1,6);
lcd.setCursor(0, 0);
lcd.print(menuList[menuCount-1]);
clearLCD();
if (goBack.isPressed()){
menuCount=0;
}
if (pressSelect() && menuCount!=0){
int timeMode=1;
int channelCount=0;
bool goBack=0;
while (goBack!=1){
if (menuCount==1){
if (pressSelect()){
timeMode++;
if (timeMode>2){timeMode=1;}
}
int timeAdjDetect=read_encoder();
if (timeMode==1){
if (timeAdjDetect){
if (timeAdjDetect>0){adjustTime(SECS_PER_HOUR);}
if (timeAdjDetect<0) {adjustTime(-SECS_PER_HOUR);}
}
lcd.setCursor(0, 0);
lcd.print("Set Time: Hrs");
lcd.setCursor(0, 1);
printHMS(hour(), minute(), second());
}
else{
if (timeAdjDetect){
if (timeAdjDetect>0){adjustTime(SECS_PER_MIN);}
if (timeAdjDetect<0) {adjustTime(-SECS_PER_MIN);}
}
lcd.setCursor(0, 0);
lcd.print("Set Time: Mins");
lcd.setCursor(0, 1);
printHMS(hour(), minute(), second());
}
clearLCD();
}
else{
rotateCheck(channelCount,0,4);
lcd.setCursor(0,0);
lcd.print("Select Channel");
lcd.setCursor(0,1);
lcd.print(channelList[channelCount]);
clearLCD();
if (pressSelect()){
if (menuCount==2){
subMenuWizard(2,channelCount,0,0);
}
if (menuCount==3){
subMenuWizard(0,channelCount,1,0);
}
if (menuCount==4){
subMenuWizard(1,channelCount,1,1);
}
if (menuCount==5){
subMenuWizard(3,channelCount,1,0);
}
}
}
if (pressBack()){goBack=1;}
}
}
}
for (int i=0;i<20;i++){
int j=0;
EEPROMWritelong(j, variablesList[i]);
j+=4;
}
}
int LED::subMenuWizard(int i, int channel, bool time, bool truetime){
if (channel==1){i=i+4;}
if (channel==2){i=i+8;}
if (channel==3){i=i+12;}
if (channel==4){i=i+16;}
while (!pressBack()){
if (time==0){
rotateCheck(variablesList[i],0,100);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
lcd.print(variablesList[i]);
setOneLed(channel);
clearLCD();
}
else{
if (truetime){
rotateCheck(variablesList[i],0,1439);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
printMins(variablesList[i] + variablesList[i-1], true);
clearLCD();
}
else {
rotateCheck(variablesList[i],0,1439);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
printMins(variablesList[i], true);
clearLCD();
}
setOneLed(channel);
}
}
}
and finally, the .ino file:
#define LCD_BACKLIGHT 9 // backlight pin
#define BACKLIGHT_DIM 10 // PWM value for backlight at idle
#define BACKLIGHT_ON 70 // PWM value for backlight when on
#define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay
#include <LED.h>
//Initialize buttons
int buttonCount = 1;
LED main;
void setup() {
};
void loop() {
/* main.setAllLed();
//turn the backlight off and reset the menu if the idle time has elapsed
if (main.backlightIdleMs + BACKLIGHT_IDLE_MS < millis() && main.backlightIdleMs > 0 ) {
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
main.clearLCD();
main.backlightIdleMs = 0;
}
if (buttonCount == 1) {
main.displayMainMenu();
}
if (buttonCount == 2) {
main.menuWizard();
buttonCount = 1;
}
*/
main.printLCD();
};
Also, in the loop portion, I've commented the part of code that is intended to run, and I'm running a function that tests to see if I've successfully entered the loop by printing "test" on screen.
I'm using a Mega for this.
LED::LED()
{
InitTimersSafe();
pinMode(LCD_BACKLIGHT, OUTPUT);
lcd.begin(16, 2);
digitalWrite(LCD_BACKLIGHT, HIGH);
lcd.print("sEx LED, V1");
clearLCD();
delay(5000);
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
You have to understand that this constructor is running when the object is created and that is probably before init() is run from main. So the hardware isn't ready at that point and pinMode and digitalWrite and stuff isn't going to work. The lcd code can't really work there and I bet that is the part that is hanging things.
A constructor should only do things like initialize variables. Any code that relies on the hardware should go into a begin() or init() or whatever method that you can call from setup once it is safe to do those things. The Serial object is a great example of another class that has to do this.

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);
}

arduino nothing printing to serial

I've built an arduino sketch that attempts to do a couple of different lengths of windowing and some simple calculations (mean/variance) on the analog values from a couple of sensors. Previously I had the same code for 1 sensor working as intended but the code below has been expanded with a bunch of little for loops so that everything should run for both sensors now.
I simply can't get anything at all to print to serial - even the two serial prints i put in setup and start of loop just to debug - yet the code compiles and uploads without any errors or warnings.
I apologise for including the whole sketch, I couldn't think how to break it apart to show.
long int currentTime = 0;
long int stopTime[2] = {0,0};
long int shortWindowTime = 0;
int shortVal[2][40];
int reflexWindowStart = 0;
int reflexWindowTime = 0;
int reflexVal[2][500];
int mean[2] = {0,0};
unsigned int variance[2] = {0,0};
int lowVal[2] = {0,0};
int peakVal[2] = {0,0};
int lowIndex[2] = {0,0};
int peakIndex[2] = {0,0};
int stopIndex[2] = {0,0};
boolean stopped[2] = {false,false};
void setup(){
Serial.begin(9600);
Serial.println("wtf?");
for(int i=0;i<2;i++){
for(int j=0;j<40;j++){
shortVal[i][j] = 0;
}
for(int j=0;j<500;j++){
reflexVal[i][j] = 1023;
}
}
}
void loop() {
Serial.println("wtf?");
currentTime = micros();
if(currentTime - shortWindowTime > 500){
shortWindowTime = currentTime;
writeShortWindow();
meanVariance();
if(reflexWindowStart == 0){
reflexWindow();
}
reflexWindowStart++;
if(reflexWindowStart > 9){
reflexWindowStart = 0;
}
}
}
void writeShortWindow(){
for(int i=0;i<2;i++){
for(int j=39; j>0; j--){
shortVal[i][j] = shortVal[i][j-1];
}
int ground = analogRead(A5);
shortVal[0][0] = analogRead(A1);
analogRead(A5);
shortVal[i][0] = analogRead(A2);
}
}
void meanVariance(){
for(int i=0;i<2;i++){
for(int j=0; j<39; j++){
mean[i] = mean[i] + shortVal[i][j];
}
mean[i] = mean[i] / 40;
for(int j=0; j<39; j++){
variance[i] = variance[i] + sq(mean[i] - shortVal[i][j]) ;
}
variance[i] = variance[i] / 40;
}
}
void reflexWindow(){
for(int i=0;i<2;i++){
if(stopped[i] == true){
if((millis() - stopTime[i] > 20) && (peakVal[i] - shortVal[i][0] > 20) && (variance[i] <= 1)){
stopped[i] = false;
stopIndex[i] = 0;
Serial.println("................................NOTstopped");
}
}
}
for(int i=0;i<2;i++){
if(stopped[i] == false){
lowVal[i] = 1023;
peakVal[i] = 0;
for(int j=stopIndex[i]; j>0; j--){
reflexVal[i][j] = reflexVal[i][j-1];
if(reflexVal[i][j] < lowVal[i]){
lowVal[i] = reflexVal[i][j];
lowIndex[i] = j;
}
}
reflexVal[i][0] = shortVal[i][0];
for(int j=lowIndex[i]; j>=0; j--){
if(reflexVal[i][j] > peakVal[i]){
peakVal[i] = reflexVal[i][j];
}
}
}
}
for(int i=0;i<2;i++){
if(stopped[i] == false){
if(peakVal[i] - lowVal[i] >= 50){
Serial.print(i);
Serial.println("...................................stopped");
stopTime[i] = millis();
stopped[i] = true;
}
}
}
for(int i=0;i<2;i++){
if(stopIndex[i] < 499){
stopIndex[i]++;
}
}
Serial.print(shortVal[0][0]);
Serial.print(" ... ");
Serial.print(lowVal[0]);
Serial.print(" ... ");
Serial.print(peakVal[0]);
Serial.print(" ........ ");
Serial.print(shortVal[1][0]);
Serial.print(" ... ");
Serial.print(lowVal[1]);
Serial.print(" ... ");
Serial.println(peakVal[1]);
}
If you have a Leonardo board you will most likely not see the Serial.print in the setup function.
Try changing your setup to this (notice the extra while loop waiting for the Serial)
void setup(){
Serial.begin(9600);
while (!Serial);
Serial.println("wtf?");
for(int i=0;i<2;i++){
for(int j=0;j<40;j++){
shortVal[i][j] = 0;
}
for(int j=0;j<500;j++){
reflexVal[i][j] = 1023;
}
}
}
The reason behind this you can read in the Arduino docs for Leonardo http://arduino.cc/en/Guide/ArduinoLeonardo#toc3 but in short is that Leonardo doesnt resets the serial port when opening the serial stream.
Have you checked your BAUD rate in serial monitor, because if it is different, it will not show anything.
be sure the one in serial monitor and in Serial.begin(<BAUD rate here>) is the same

Resources