Canceling a delay in Arduino C/C++ - arduino

The Problem!
My problem is that I'm making a clock, and I want to make it able to change the time with a keypad, but I think this line of code to delay for 60 seconds, delay(60000); interferes.
My Code
This is my code with #tuyau2poil's implementation:
/*
* 7 Segment Clock
* Created by SniverDaBest
* Date: 2/9/23
*/
// Include the 7-segment display library:
#include <TM1637Display.h>
#include <Key.h>
#include <Keypad.h>
#define CLK 5
#define DIO 6
const byte ROWS = 4;
const byte COLS = 4;
int buzzer = 3;
bool clockStarted = false;
unsigned long timerSec;
int time = 1200;
int secTime = 0;
char result;
char buttons[ROWS][COLS] = {
{'1', '2', '3', 'A'}, // 1st row
{'4', '5', '6', 'B'}, // 2nd row
{'7', '8', '9', 'C'}, // 3rd row
{'*', '0', '#', 'D'} // 4th row
};
byte rowPins[ROWS] = {9, 8, 7, 4};
byte colPins[COLS] = {10, 11, 12, 13}; // reassigned two of the column pins
// This is useful for power https://www.amazon.com/Printer-Adapter-Convert-Connector-Compatible/dp/B092C5DNSF/ref=sr_1_10?adgrpid=1335908033757253&hvadid=83494457602384&hvbmt=be&hvdev=c&hvlocphy=43722&hvnetw=o&hvqmt=e&hvtargid=kwd-83495174141932%3Aloc-190&hydadcr=18004_10780277&keywords=usb-c+to+usb+b&qid=1675997137&sr=8-10
// Create display object of type TM1637Display:
TM1637Display disp = TM1637Display(CLK, DIO);
Keypad kp = Keypad(makeKeymap(buttons), rowPins, colPins, ROWS, COLS);
// Create array that turns all segments on:
const uint8_t all_on[] = {0xff, 0xff, 0xff, 0xff}; // 0xff is a hexidecimal number whose binary
// representation is all ones
// Create array that turns all segments off:
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00};
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
disp.clear();
delay(1000);
// Set the brightness:
disp.setBrightness(7);
// All segments on:
disp.setSegments(all_on);
delay(2000);
disp.clear();
delay(1000);
timerSec = millis();
}
void runEverySecond() {
timerSec = millis();
secTime++;
if (secTime > 60) {
runEveryMinute();
}
}
void runEveryMinute() {
secTime = 0;
if (result == '1') {
if (time <= 1259) {
time++;
}
if (time == 1260) {
time = 100;
}
if (time <= 159) {
time++;
}
if (time == 160) {
time = 200;
}
if (time <= 259) {
time++;
}
if (time == 260) {
time = 300;
}
if (time <= 359) {
time++;
}
if (time == 360) {
time = 400;
}
if (time <= 459) {
time++;
}
if (time == 460) {
time = 500;
}
if (time <= 559) {
time++;
}
if (time == 560) {
time = 600;
}
if (time <= 659) {
time++;
}
if (time == 660) {
time = 700;
}
if (time <= 759) {
time++;
}
if (time == 760) {
time = 800;
}
if (time <= 859) {
time++;
}
if (time == 860) {
time = 900;
}
if (time <= 959) {
time++;
}
if (time == 960) {
time = 1000;
}
if (time <= 1059) {
time++;
}
if (time == 1060) {
time = 1100;
}
if (time <= 1159) {
time++;
}
if (time == 1160) {
time = 1200;
}
}
else if (result == '2'){
if (time <= 1259) {
time = time - 1;
}
if (time == 1199) {
time = 1159;
}
if (time <= 159) {
time = time - 1;
}
if (time == 160) {
time = 1000;
}
if (time <= 259) {
time = time - 1;
}
if (time == 260) {
time = 300;
}
if (time <= 359) {
time = time - 1;
}
if (time == 360) {
time = 400;
}
if (time <= 459) {
time = time - 1;
}
if (time == 460) {
time = 500;
}
if (time <= 559) {
time = time - 1;
}
if (time == 560) {
time = 600;
}
if (time <= 659) {
time = time - 1;
}
if (time == 660) {
time = 700;
}
if (time <= 759) {
time = time - 1;
}
if (time == 760) {
time = 800;
}
if (time <= 859) {
time = time - 1;
}
if (time == 860) {
time = 900;
}
if (time <= 959) {
time = time - 1;
}
if (time == 960) {
time = 1000;
}
if (time <= 1059) {
time = time - 1;
}
if (time == 1060) {
time = 1100;
}
if (time <= 1159) {
time = time - 1;
}
if (time == 1160) {
time = 1200;
}
}
for (time <= 1259; time++;) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 100; time <= 159; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 200; time <= 259; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 300; time <= 359; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 400; time <= 459; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 500; time <= 559; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 600; time <= 659; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 700; time <= 759; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 800; time <= 859; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 900; time <= 959; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 1000; time <= 1059; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
for (time = 1100; time <= 1159; time++) {
disp.showNumberDecEx(time, 0b11100000, false, 4, 0);
delay(60000);
}
}
void loop() {
result = kp.getKey();
if (millis() - timerSec > 1000) {
runEverySecond();
}
}
What I did to try and fix my problem
I tried searching Arduino forms posts, but found nothing. I tried searching for some other posts here, but no luck. There also is no command like cancelDelay(); or resetDelay();. Help would be most appreciated!

use millis() : this function return mS from last powerOn and is incremented... every mS.
You can then create timers without blocking loop execution.
update : I dont understand why you complicate things as much: basically just create a few simple functions to increase or decrease hours and minutes (integer vars), then, to display time,
multiplie hour by 100, which shifts it from 2 digits to the left, and add it to minutes. (I chose cross keys on the keyboard but you can choose others).
Without keypad intervention, the display changes time automatically every minute.
I dont have necessary harware and time to test but I think it must work.
I added some comments for your understanding
keypad keys assignment
8 = increase hours
2 = decrease hours
4 = decrease minutes
6 = increase minutes
time go from 00:00 to 23:59
#include <TM1637Display.h>
//#include <Key.h>
#include <Keypad.h>
#define CLK 5
#define DIO 6
const byte ROWS = 4;
const byte COLS = 4;
int buzzer = 3;
bool clockStarted = false;
unsigned long timerSec;
int secTime = 0;
char result;
int H, M; //hours, minutes
char buttons[ROWS][COLS] = {
{'1', '2', '3', 'A'}, // 1st row
{'4', '5', '6', 'B'}, // 2nd row
{'7', '8', '9', 'C'}, // 3rd row
{'*', '0', '#', 'D'} // 4th row
};
byte rowPins[ROWS] = {9, 8, 7, 4};
byte colPins[COLS] = {10, 11, 12, 13}; // reassigned two of the column pins
// Create display object of type TM1637Display:
TM1637Display disp = TM1637Display(CLK, DIO);
Keypad kp = Keypad(makeKeymap(buttons), rowPins, colPins, ROWS, COLS);
// Create array that turns all segments on:
const uint8_t all_on[] = {0xff, 0xff, 0xff, 0xff}; // 0xff is a hexidecimal number whose binary
// representation is all ones
// Create array that turns all segments off:
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00};
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
disp.clear();
delay(1000);
// Set the brightness:
disp.setBrightness(7);
// All segments on:
disp.setSegments(all_on);
delay(2000);
disp.clear();
delay(1000);
timerSec = millis();
}
void loop() {
readKeypad();
if (millis() - timerSec > 999) { //tick when exceed 999mS = every seconds
runEverySecond();
}
}
void readKeypad() {
result = kp.getKey();
if (result) { //key pressed
if (result == '8') increaseHour();
if (result == '2') decreaseHour();
if (result == '6') increaseMinute();
if (result == '4') decreaseMinute();
delay(40); //small delay to avoid key repeating - change for your convenient
}
}
void increaseHour() {
if (H > 23) H = 0; //if hour > 23, hour restart from 0
H++; //else hour simply incremented
}
void decreaseHour() {
if (H < 0) H = 23;
H--;
}
void increaseMinute() {
if (M > 59) M = 0;
M++;
}
void decreaseMinute() {
if (M < 0) M = 59;
H--;
}
void incrementTime() { //call every minutes
increaseMinute();
if (M == 0) { //occur every hours : If minute exceeds 59 restart from 0
increaseHour(); //if hour exceeds 23 restart from 0
}
}
void runEverySecond() {
timerSec = millis();
secTime++;
if (secTime > 59) { //ticks every minute
runEveryMinute();
}
}
void runEveryMinute() {
secTime = 0;
incrementTime();
updateDisplay();
}
void updateDisplay() {
int fullTime = H * 100 + M; // ex for H=5 and M=15 fullTime = 515 so display = 05:15
disp.showNumberDecEx(fullTime, 0b11100000, false, 4, 0);
}

Related

I need the value to go up on 7 segment. help me pls

why is it like this How should I fix it?
It's my first time using PMS5003 with 7segment
I am able to display the value in the Serial Monitor but cannot get the pm2_5 value to be displayed in the 7 segment.
#include "SevSeg.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial(A0, A1);
SevSeg sevseg;
unsigned int pm1 = 0;
unsigned int pm2_5 = 0;
unsigned int pm10 = 0;
void setup() {
Serial.begin(9600);
while (!Serial) ;
mySerial.begin(9600);
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; //6, 7, 8, 9, 10, 11, 12, 13
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(30);
}
void loop() {
int index = 0;
char value;
char previousValue ;
static unsigned long timer = millis ();
static int deciSeconds = 0;
if (millis() - timer >= 100)
{
timer += 100;
sevseg.setNumber(pm2_5, 2);
}
sevseg.refreshDisplay();
while (mySerial.available()) {
value = mySerial.read();
if ((index == 0 && value != 0x42) || (index == 1 && value != 0x4d)) { //0x42,0x4d ค่าคงที่
Serial.println("Cannot find the data header.");
break;
}
if (index == 4 || index == 6 || index == 8 || index == 10 || index == 12 || index == 14) {
previousValue = value;
}
else if (index == 5) {
pm1 = 256 * previousValue + value;
Serial.print("{ ");
Serial.print("\"pm1\": ");
Serial.print(pm1);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 7) {
pm2_5 = 256 * previousValue + value;
Serial.print("\"pm2_5\": ");
Serial.print(pm2_5);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 9) {
pm10 = 256 * previousValue + value;
Serial.print("\"pm10\": ");
Serial.print(pm10);
Serial.print(" ug/m3");
} else if (index > 15) {
break;
}
index++;
}
while (mySerial.available()) mySerial.read();
Serial.println(" }");
delay(1000);
}
I want the 7segment to be able to display the value of the sensor PMS5003.

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.

Incremental index doesn't change at end of for loop

I want to interface Arduino with PLC to pull some information.
My problem is at Function 3: Set alarm flag / reset flag. This function is used to compare history value and present value. I tried to process some integer number (test_number) and process like binary 16 bits data for finding 1 at some bit. I found the for loop in Findbit function, which should repeat 16 times, runs infinitely. It does not change the incremental index (variable name bit_1) which is still stuck at 1.
This is my code :
int test_number_array[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int test_number = 0;
int bit_1 = 0;
int Andbit = 0;
const char* message;
int flagAlarm[2][16] = {};
int flagReset[2][16] = {};
void setup()
{
// put your setup code here, to run once:
Serial.begin( 9600 );
}
void loop()
{
// put your main code here, to run repeatedly:
for (int j = 1; j <= 2; j++)
{
for (int i = 1; i <= 2; i++) // Example with 2 modbus address
{
unsigned int address = 40000 + i;
Serial.print ("Modbus address = ");
Serial.println(address, DEC);
pull_data(i);
Serial.print("Test number is ");
Serial.println(test_number);
Findbit(i);
Serial.println("------------------------------------------------- ");
}
}
while (1)
{
}
}
// ---------------Function 1 : Function finding alarm bit-----------------//
void Findbit(int i)
{
for (bit_1 = 0; bit_1 <= 15; bit_1++)
{
Andbit = test_number & 1;
Serial.print("Test number (BINARY) is ");
Serial.println(test_number, BIN);
Serial.print("Check at bit number ");
Serial.println(bit_1);
Serial.print("And bit is ");
Serial.println(Andbit, BIN);
Serial.print("flagAlarm(Before1) = ");
Serial.println(flagAlarm[i][bit_1]);
Serial.print("flagreset(Before1) = ");
Serial.println(flagReset[i][bit_1]);
if (Andbit == 1) //found "1" pass into loop
{
flagAlarm[i][bit_1] = 1;
}
else
{
}
Serial.print("flagAlarm(Before2) = ");
Serial.println(flagAlarm[i][bit_1]);
Serial.print("flagreset(Before2) = ");
Serial.println(flagReset[i][bit_1]);
Set_reset_flag(i,bit_1);
test_number = test_number >> 1;
Serial.print("flagAlarm(After) = ");
Serial.println(flagAlarm[i][bit_1]);
Serial.print("flagreset(After) = ");
Serial.println(flagReset[i][bit_1]);
Serial.println(" ");
}
}
// -----------------------Function 2 : Pull data------------------------- //
int pull_data(int i)
{
i = i - 1;
test_number = test_number_array[i];
return test_number;
}
// -------------Function 3 : Set alarm flag / reset flag ---------------- //
void Set_reset_flag(int i, int bit_1)
{
Serial.print("i = ");
Serial.println(i);
Serial.print("bit_1 = ");
Serial.println(bit_1);
if (flagAlarm[i][bit_1] == 1 && flagReset[i][bit_1] == 0)
{
Serial.print("Alarm at bit ");
Serial.println(bit_1);
flagAlarm[i][bit_1] = 0;
flagReset[i][bit_1] = 1;
}
else if (flagAlarm[i][bit_1] == 0 && flagReset[i][bit_1] == 1)
{
Serial.print("Reset Alarm at bit ");
Serial.println(bit_1);
flagReset[i][bit_1] = 0;
}
else if (flagAlarm[i][bit_1] == 1 && flagReset[i][bit_1] == 1)
{
Serial.print("Alarm still active at bit ");
Serial.println(bit_1);
flagAlarm[i][bit_1] = 0;
flagReset[i][bit_1] = 1;
}
else
{
}
}
Could it be that your bit_1 variable is modified from some other code not mentioned here, or get optimized at all? Also, is it necessary to make a loop counter a global variable? Can you declare it inside the Findbit function?

Arduino 16-step sequencer - Notes not in sync

I am using the following code for my arduino mega to send midi clock out to my drum machine & synth.
The problem appears when I also try to send midi notes exactly on the 'beat'.
Only the first note is perfectly synced, the rest of them are out of sync and you can hear it.
Is there any apparent flaw in the code?
// METRONOME
#include <MIDI.h>
#define LED1PIN 13
#define LED4PIN 7
#define SWITCHAPIN 5
#define SWITCHBPIN 2
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
void setup() {
pinMode(LED1PIN, OUTPUT);
pinMode(LED4PIN, OUTPUT);
pinMode(SWITCHAPIN, INPUT);
pinMode(SWITCHBPIN, INPUT);
digitalWrite(SWITCHAPIN, HIGH);
digitalWrite(SWITCHBPIN, HIGH);
MIDI.begin(MIDI_CHANNEL_OMNI);
Serial.begin(9600);
Serial.println("Setting up");
}
unsigned long nextClockTime = 0;
int clockDelay = 20;
int tickCount = 0;
byte running = 0;
int pula = 0;
int currentStep = 1;
int lastPulse = 0;
int currPulse = 0;
int nextTickCount = 0;
typedef struct {
int noteNumber;
int velocity;
int noteLength;
bool enabled;
}
Step;
Step stepData[100];
void loop() {
stepData[0].enabled = true;
stepData[0].velocity = 127;
stepData[0].noteNumber = 40;
stepData[23].enabled = true;
stepData[23].velocity = 127;
stepData[23].noteNumber = 40;
stepData[47].enabled = true;
stepData[47].velocity = 127;
stepData[47].noteNumber = 40;
stepData[71].enabled = true;
stepData[71].velocity = 127;
stepData[71].noteNumber = 40;
stepData[95].enabled = true;
stepData[95].velocity = 127;
stepData[95].noteNumber = 40;
MIDI.read();
unsigned long milliseconds = millis();
if (milliseconds > nextClockTime) {
if (running)
MIDI.sendRealTime(MIDI_NAMESPACE::Clock);
nextClockTime = milliseconds + clockDelay;
nextTickCount = tickCount + 1;
if (tickCount == 0) {
if (stepData[tickCount].enabled) {
MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
Serial.print("STEP ENABLED: ");
Serial.println(tickCount);
}
}
if (tickCount == 23) {
if (stepData[tickCount].enabled) {
MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
Serial.print("STEP ENABLED: ");
Serial.println(tickCount);
currPulse = millis(); //1500
Serial.println(currPulse - lastPulse); //1500-500
lastPulse = currPulse;
}
}
if (tickCount == 47) {
if (stepData[tickCount].enabled) {
MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
Serial.print("STEP ENABLED: ");
Serial.println(tickCount);
currPulse = millis();
Serial.println(currPulse - lastPulse);
lastPulse = currPulse;
}
}
if (tickCount == 71) {
if (stepData[tickCount].enabled) {
MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
Serial.print("STEP ENABLED: ");
Serial.println(tickCount);
currPulse = millis();
Serial.println(currPulse - lastPulse);
lastPulse = currPulse;
}
}
if (tickCount == 95) {
if (stepData[tickCount].enabled) {
//MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
Serial.print("STEP ENABLED: ");
Serial.println(tickCount);
currPulse = millis();
Serial.println(currPulse - lastPulse);
lastPulse = currPulse;
}
nextTickCount = 0;
}
tickCount = nextTickCount;
} else if (digitalRead(SWITCHBPIN) == LOW) {
if (running) {
MIDI.sendRealTime(MIDI_NAMESPACE::Stop);
running = 0;
digitalWrite(LED4PIN, LOW);
}
} else {
clockDelay = analogRead(A0) / 10;
}
if (pula == 0) {
if (!running) {
MIDI.sendRealTime(MIDI_NAMESPACE::Start);
tickCount = 0;
running = 1;
digitalWrite(LED4PIN, HIGH);
pula = 1;
}
}
}
The beats are not evenly spaced. 24 - 1 is 23, 48 - 24 is 24 etc.
A simple fix would be to put your first beat on 0 not 1. Instead of incrementing tickCount, set a variable nextTickCount to tickCount +1, and assign it to tickCount at the end of the if (milliseconds > nextClockTime) { conditional bracket.
Also, set nextTickCount to 0 when tickCount reaches 95, but don't play any note (it will be played on the 0 beat )

Arduino - cannot get buzzer to buzz

I've hooked up a buzzer to pin 13 & ground on my Arduino.
The "Blink" example works fine and the buzzer sounds every second off and on as expected.
However, when I try to do the same buzz with my code, I can't get it to buzz upon a specific event. This is a homegrown security system - when the door is opened, I want the Arduino to check a PHP page which returns "armed" if the system has been armed.
Everything else seems to work except the buzzer part.
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xD3, 0x6C };
char serverName[] = "mysite.com";
String currentLine = "";
String armed = "No";
int nFrontWindow = 0;
int sFrontWindow = 1;
int kitchenWindow = 2;
int bedroomWindow = 3;
int frontDoor = 4;
int val0 = 0;
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
int threshold0 = 20;
int threshold1 = 20;
int threshold2 = 20;
int threshold3 = 20;
int threshold4 = 20;
int breach0 = 0;
int breach1 = 0;
int breach2 = 0;
int breach3 = 0;
int breach4 = 0;
int alarm0 = 0;
int alarm1 = 0;
int alarm2 = 0;
int alarm3 = 0;
int alarm4 = 0;
EthernetClient client;
void setup() {
pinMode(13, OUTPUT);
// initialize serial communications at 9600 bps:
Serial.begin(9600);
if(Ethernet.begin(mac) == 0) { // start ethernet using mac & IP address
Serial.println("Failed to configure Ethernet using DHCP");
while(true) // no point in carrying on, so stay in endless loop:
;
}
delay(1000); // give the Ethernet shield a second to initialize
}
void loop() {
// read the analog in values:
val0 = analogRead(nFrontWindow);
val1 = analogRead(sFrontWindow);
val2 = analogRead(kitchenWindow);
val3 = analogRead(bedroomWindow);
val4 = analogRead(frontDoor);
// print the analog in values:
if (val0 > threshold0)
{
Serial.print("nFrontWindow: ");
Serial.print(val0);
Serial.print("\n");
if (alarm0)
{
if (breach0 < 10)
breach0++;
}
else
{
if (breach0 > 9)
{
alarm0 = 1;
send_alert(0);
}
else
breach0++;
}
}
else
{
if (alarm0)
{
if (breach0 > 0)
breach0--;
else
{
alarm0 = 0;
send_alert(10);
}
}
else
{
if (breach0 > 0)
breach0--;
}
}
if (val1 > threshold1)
{
Serial.print("sFrontWindow: ");
Serial.print(val1);
Serial.print("\n");
if (alarm1)
{
if (breach1 < 10)
breach1++;
}
else
{
if (breach1 > 9)
{
alarm1 = 1;
send_alert(1);
}
else
breach1++;
}
}
else
{
if (alarm1)
{
if (breach1 > 0)
breach1--;
else
{
alarm1 = 0;
send_alert(11);
}
}
else
{
if (breach1 > 0)
breach1--;
}
}
if (val2 > threshold2)
{
Serial.print("kitchenWindow: ");
Serial.print(val2);
Serial.print("\n");
if (alarm2)
{
if (breach2 < 10)
breach2++;
}
else
{
if (breach2 > 9)
{
alarm2 = 1;
send_alert(2);
}
else
breach2++;
}
}
else
{
if (alarm2)
{
if (breach2 > 0)
breach2--;
else
{
alarm2 = 0;
send_alert(12);
}
}
else
{
if (breach2 > 0)
breach2--;
}
}
if (val3 > threshold3)
{
Serial.print("bedroomWindow: ");
Serial.print(val3);
Serial.print("\n");
if (alarm3)
{
if (breach3 < 10)
breach3++;
}
else
{
if (breach3 > 9)
{
alarm3 = 1;
send_alert(3);
}
else
breach3++;
}
}
else
{
if (alarm3)
{
if (breach3 > 0)
breach3--;
else
{
alarm3 = 0;
send_alert(13);
}
}
else
{
if (breach3 > 0)
breach3--;
}
}
if (val4 > threshold4)
{
Serial.print("frontDoor: ");
Serial.print(val4);
Serial.print("\n");
if (alarm4)
{
if (breach4 < 10)
breach4++;
}
else
{
if (breach4 > 9)
{
alarm4 = 1;
send_alert(4);
}
else
breach4++;
}
}
else
{
if (alarm4)
{
if (breach4 > 0)
breach4--;
else
{
alarm4 = 0;
send_alert(14);
}
}
else
{
if (breach4 > 0)
breach4--;
}
}
delay(100);
}
void send_alert(int pin)
{
if (client.connect(serverName, 80)>0) {
client.flush();
Serial.print("\nconnected... ");
String link = "GET [PHP FILE GOES HERE]";
link += pin;
link += " HTTP/1.1";
Serial.print("Sending alert code: ");
Serial.print(pin);
Serial.print("\n\n");
client.println(link);
client.println("Host: mysite.com");
client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
delay(3000);
} else {
Serial.println("connection failed");
//handle this
}
Serial.print("Server response:\n");
Serial.print("----------------\n");
while(client.available()){
char c = client.read();
Serial.print(c);
currentLine += c;
if (c == '\n') {
currentLine = "";
}
if (currentLine.endsWith("armed"))
{
if (pin == 4 || pin == 3 || pin == 2 || pin == 1 || pin == 0)
{
Serial.print("\nBZZZZZZZZZZ\n");
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
}
}
Serial.print("\n----------------\n");
//else
// Serial.println("result not found");
client.stop();
client.flush();
}
I think your problem is that pin 13 is used by the Ethernet Shield. So are pin 10, 11, and 12. So use a pin other then them.
I think you problem is that you aren't generating a square wave to make sound the buzzer.
Since you are using Arduino you can just use tone() and noTone() functions, well explained in Arduino site.

Resources