I am adding a feature to my program that when you press a button and hold it goes to the “Countdown” section in the program and then into the “LastChance” section where it beeps faster and if you let go at any time it goes back to section called “Check”.
The problem is that as soon as the unit gets switched on it starts beeping continually.
If I change “HIGH” to “LOW” it never starts beeping no matter if the button is pressed or not pressed.
All my code:
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
//Setting up pin 8 as 'ledPin'
int rxtime1 = 0; //previously ago
int ago1 = 12345; //previously agofinal
int seconds = 0;
const int buttonPin = 9; // the number of the pushbutton pin
int buzzer = 8;
int buttonState = 0; // variable for reading the pushbutton status
//intializing variables to store received data and lat and long
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
char lat1[numChars];
char lng1[numChars];
boolean newData = false;
// set pins for GPS serial rx and tx
static const int RXPin = 6, TXPin = 7;
// set GPS Baud rate constant
static const uint32_t GPSBaud = 9600;
// set initial Bluetooth input string
char BT_input=' ';
// The TinyGPS++ object
TinyGPSPlus gps;
// Define the serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//Assign a unique ID to the accelerometer
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
void setup() {
pinMode(buttonPin, INPUT);
//start arduino serial comms
Serial.begin(9600);
//start gps serial comms
ss.begin(GPSBaud);
while (!Serial); // should this be there at all? try commenting out and see if any difference
//start the LoRa serial comms
//Serial.println("Starting LoRa Sender and Receiver");
if (!LoRa.begin(915E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
{
#ifndef ESP8266 //LoRa, What exactly does it do?
while (!Serial); // for Leonardo/Micro/Zero
#endif
//Initialise the accelerometer sensor
if(!accel.begin()) {
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
while (1);
}
}
Serial.println ("Check if rx_byte init correctly "); //debug
Serial.println (receivedChars); //debug
}
void loop() {
Check:{
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
goto Countdown;
}
static byte ndx = 0;
char endMarker = '\n';
char rc;
//try to parse a LoRa packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packet
while (LoRa.available()) {
rc = LoRa.read(); //whatever is availble in the LoRa buffer goes into the variable rc
if (rc != endMarker) { //if variable rc does not equal "/n"
receivedChars[ndx] = rc; //stores the received data into received Chars
ndx++; //adds 1 to ndx
if (ndx >= numChars) { //if received characters above or equals 32
ndx = numChars - 1; //variable ndx = 32 - 1 which equals 31
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true; //variable for testing whether new data has been recieved == true which means there has been new data received
}
}
}
if (newData == true) { //if new data recieved
ago1 = 0;
Serial.print(receivedChars); //send received data over bluetooth to the phone
if (strstr(receivedChars, "lat")){ //if data recieved include the word "lat" (received the latitude)
strcpy (lat1,receivedChars); //make variable lat1 = the received data
}
if (strstr(receivedChars, "lng")){ //if data recieved include the word "lng" (received the lng)
strcpy (lng1,receivedChars); //make variable lng2 = the received data
rxtime1 = millis(); //time since arduino powered up (for setting how long ago the message was received)
}
newData = false;
}
//check for phone app refresh button press packet received via bluetooth
{
if (Serial.available())
{
BT_input = Serial.read();
// if the refresh button is pressed on the phone app
if ( BT_input== 48) //ascii code for 0 is dec 48
{
goto Resend;
}
}
}
/* Check the accelerometer for an accident event */
sensors_event_t event;
accel.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
if (event.acceleration.y + event.acceleration.x > 15 || event.acceleration.y + event.acceleration.x < -15) {
seconds = 0;
goto Countdown;
}
delay (10);
goto Check;
}
Countdown:{
//Serial.print (event.acceleration.y + event.acceleration.x || event.acceleration.y + event.acceleration.x );
tone (buzzer,1000,20);
delay(1000);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
seconds++;
if (seconds < 3) goto Countdown;
else goto LastChance;
}
LastChance:{
if (seconds > 0) seconds = 0;
tone (buzzer,1000,20);
delay (500);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
tone (buzzer,1000,20);
delay(500);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
seconds++;
if (seconds < 2) goto LastChance;
else goto HelpLat;
}
HelpLat:{
while (ss.available() > 0){
if (gps.encode(ss.read())){
goto Lat;
}
}
goto HelpLat;
}
HelpLng:{
while (ss.available() > 0){
if (gps.encode(ss.read())){
goto Lng;
}
}
goto HelpLng;
}
Lat:{
//Send the latitude coordinate via LoRa
LoRa.beginPacket();
if (gps.location.isValid())
{
LoRa.print ("lat");
delay (20);
LoRa.print (gps.location.lat(), 6); // add lat prefix to the data sent
delay (20);
LoRa.print ("\n");
delay (20);
LoRa.endPacket();
delay (20);
}
else
{
goto HelpLat;
}
// Beep to show that a packet has been sent
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (200);
goto HelpLng;
}
Lng:{
//Send the longitude coordinate via LoRa
LoRa.beginPacket();
if (gps.location.isValid())
{
LoRa.print ("lng");
delay(20);
LoRa.print (gps.location.lng(), 6);
delay (20);
LoRa.print ("\n");
delay(20);
LoRa.endPacket();
delay (20);
}
else
{
goto HelpLng;
}
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (200);
goto Check;
}
Resend:
{
if (ago1 == 12345) {
Serial.print ("No Messages");
delay (20);
goto Check;
}
ago1 = (millis() - rxtime1) /1000 / 60;
delay (20);
Serial.print (lat1);
delay (1000);
Serial.print (lng1);
delay(1000);
Serial.print (ago1);
delay(20);
ago1 = 12345;
goto Check;
}
}
There's is almost never any reason to use goto in C++ programs so I'm guessing that your program being scattered with them is what's causing the problem. But they're so confusing I'm not even going to try to trace the paths.
Perhaps it is time to learn how to write functions and incorporate them into your program.
The problem seems to be that it is detecting that the button is always pressed on.
This might indicate a wiring problem but it is not as I uploaded this program and it worked great.
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 9; // the number of the pushbutton pin
const int ledPin = 8; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
Updated code with new attempts to fix problem. Still it appears to be the problem of thinking that the button is always “HIGH”.
Do you think this is this the problem or is it something else?
Code:
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
//Setting up pin 8 as 'ledPin'
int rxtime1 = 0; //previously ago
int ago1 = 12345; //previously agofinal
int seconds = 0;
const int buttonPin = 9; // the number of the pushbutton pin
const int buzzer = 8; //the pin number for the buzzer
int buttonState = 0; // variable for reading the pushbutton status
//intializing variables to store received data and lat and long
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
char lat1[numChars];
char lng1[numChars];
boolean newData = false;
// set pins for GPS serial rx and tx
static const int RXPin = 6, TXPin = 7;
// set GPS Baud rate constant
static const uint32_t GPSBaud = 9600;
// set initial Bluetooth input string
char BT_input=' ';
// The TinyGPS++ object
TinyGPSPlus gps;
// Define the serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//Assign a unique ID to the accelerometer
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
void setup() {
pinMode(buttonPin, INPUT);
//start arduino serial comms
Serial.begin(9600);
//start gps serial comms
ss.begin(GPSBaud);
while (!Serial); // should this be there at all? try commenting out and see if any difference
//start the LoRa serial comms
//Serial.println("Starting LoRa Sender and Receiver");
if (!LoRa.begin(915E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
{
#ifndef ESP8266 //LoRa, What exactly does it do?
while (!Serial); // for Leonardo/Micro/Zero
#endif
//Initialise the accelerometer sensor
if(!accel.begin()) {
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
while (1);
}
}
Serial.println ("Check if rx_byte init correctly "); //debug
Serial.println (receivedChars); //debug
}
void loop() {
Check:{
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
goto Countdown;
}
static byte ndx = 0;
char endMarker = '\n';
char rc;
//try to parse a LoRa packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packet
while (LoRa.available()) {
rc = LoRa.read(); //whatever is availble in the LoRa buffer goes into the variable rc
if (rc != endMarker) { //if variable rc does not equal "/n"
receivedChars[ndx] = rc; //stores the received data into received Chars
ndx++; //adds 1 to ndx
if (ndx >= numChars) { //if received characters above or equals 32
ndx = numChars - 1; //variable ndx = 32 - 1 which equals 31
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true; //variable for testing whether new data has been recieved == true which means there has been new data received
}
}
}
if (newData == true) { //if new data recieved
ago1 = 0;
Serial.print(receivedChars); //send received data over bluetooth to the phone
if (strstr(receivedChars, "lat")){ //if data recieved include the word "lat" (received the latitude)
strcpy (lat1,receivedChars); //make variable lat1 = the received data
}
if (strstr(receivedChars, "lng")){ //if data recieved include the word "lng" (received the lng)
strcpy (lng1,receivedChars); //make variable lng2 = the received data
rxtime1 = millis(); //time since arduino powered up (for setting how long ago the message was received)
}
newData = false;
}
//check for phone app refresh button press packet received via bluetooth
{
if (Serial.available())
{
BT_input = Serial.read();
// if the refresh button is pressed on the phone app
if ( BT_input== 48) //ascii code for 0 is dec 48
{
goto Resend;
}
}
}
/* Check the accelerometer for an accident event */
sensors_event_t event;
accel.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
if (event.acceleration.y + event.acceleration.x > 15 || event.acceleration.y + event.acceleration.x < -15) {
seconds = 0;
goto Countdown;
}
delay (10);
goto Check;
}
Countdown:{
tone (buzzer,1000,20);
delay(1000);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
seconds++;
if (seconds < 3) goto Countdown;
else goto LastChance;
}
LastChance:{
if (seconds > 2) seconds = 0;
tone (buzzer,1000,20);
delay (500);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
tone (buzzer,1000,20);
delay(500);
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
goto Check;
}
seconds++;
if (seconds < 2) goto LastChance;
else goto HelpLat;
}
HelpLat:{
while (ss.available() > 0){
if (gps.encode(ss.read())){
goto Lat;
}
}
goto HelpLat;
}
HelpLng:{
while (ss.available() > 0){
if (gps.encode(ss.read())){
goto Lng;
}
}
goto HelpLng;
}
Lat:{
//Send the latitude coordinate via LoRa
LoRa.beginPacket();
if (gps.location.isValid())
{
LoRa.print ("lat");
delay (20);
LoRa.print (gps.location.lat(), 6); // add lat prefix to the data sent
delay (20);
LoRa.print ("\n");
delay (20);
LoRa.endPacket();
delay (20);
}
else
{
goto HelpLat;
}
// Beep to show that a packet has been sent
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (200);
goto HelpLng;
}
Lng:{
//Send the longitude coordinate via LoRa
LoRa.beginPacket();
if (gps.location.isValid())
{
LoRa.print ("lng");
delay(20);
LoRa.print (gps.location.lng(), 6);
delay (20);
LoRa.print ("\n");
delay(20);
LoRa.endPacket();
delay (20);
}
else
{
goto HelpLng;
}
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (200);
goto Check;
}
Resend:
{
if (ago1 == 12345) {
Serial.print ("No Messages");
delay (20);
goto Check;
}
ago1 = (millis() - rxtime1) /1000 / 60;
delay (20);
Serial.print (lat1);
delay (1000);
Serial.print (lng1);
delay(1000);
Serial.print (ago1);
delay(20);
ago1 = 12345;
goto Check;
}
}
Have you got a multimeter? If so check that the button pin isn't always high. It's easy to wire those buttons wrong so they're permanently on.
Since you don't have any functions except setup() and loop() but are still using the ancient spaghetti technique of gotos and labelled code blocks I'd say your use of functions hasn't improved.
You can't just drop the word "void" in at random places. It is used in a function declaration to say that the function is not returning any value. Used outside that context it is meaningless.
I have checked the wiring of the button and it appears to be right.
I also uploaded this code to test it and it worked fine:
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 9; // the number of the pushbutton pin
const int ledPin = 8; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
How do you have the button wired? Do you have an external pull-up or pull-down resistor? Which one? Or could the input be floating when not pressed? In which case it is perfectly reasonable for it to read HIGH in both states.
You also seem to have things backwards of normal where the buttons read HIGH when pressed.
The regular way to do a button is to wire between the pin and ground and use INPUT_PULLUP so the button will read HIGH when not pressed and LOW when pressed.
ZebH:
What's the difference between a pull-up and a pull-down resistor?
I am using a standard 10K resistor.
Thanks
Zeb
One pulls the line up to 5V and the other pulls the line down to ground.
Typically one wouldn't use either since the Arduino has pull-ups built in. You just enable them by INPUT_PULLUP instead of INPUT in pinMode and then you don't need any external parts.
So you're still wanting to know why the code with all the gotos doesn't work? I don't know, I don't debug code if it has a goto. I just tell the writer of the code that they did it wrong and they need to rewrite without the goto. goto makes code very hard to debug. If you insist on goto then you're on your own. There's NEVER any good reason to use it in C++.