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);
}
}
I had to change thing a little bit, I do not have any cancel commands for the beeper (I was making it cancel when I let go of the button) so I just want it to countdown when I press the button so no cancel function.
My problem still is that as soon as the Arduino has power it goes to the countdown section then to the LastChance section again and again as if the button is always held on.
Here is 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;
int SendLoRaData = 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() {
if (SendLoRaData = 1) {
while (ss.available() > 0){
if ((gps.encode(ss.read())) and (gps.location.isValid())){
SendLatandLong();
}
}
}
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
seconds = 0;
Countdown();
}
if (seconds > 2){
LastChance();
}
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
NewData();
}
if (Serial.available())
{
BT_input = Serial.read();
// if the refresh button is pressed on the phone app
if (( BT_input == 48) and (ago1 == 12345)) //ascii code for 0 is dec 48
{
Serial.print ("No Messages");
delay (20);
}
if (( BT_input == 48) and (ago1 != 12345)){
BData();
}
}
// 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;
Countdown();
}
delay (10);
}
void SendLatandLong(){
//Send the latitude coordinate via LoRa
LoRa.beginPacket();
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);
// Beep to show that a packet has been sent
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (2000);
//Send the longitude coordinate via LoRa
LoRa.beginPacket();
LoRa.print ("lng");
delay(20);
LoRa.print (gps.location.lng(), 6);
delay (20);
LoRa.print ("\n");
delay(20);
LoRa.endPacket();
delay (20);
delay (20);
tone (buzzer,1000,20);
delay(1000);
noTone (buzzer);
delay (200);
SendLoRaData = 0;
}
void Countdown(){
tone (buzzer,1000,20);
delay(1000);
seconds++;
if (seconds < 3) Countdown();
}
void LastChance(){
if (seconds > 2) seconds = 0;
tone (buzzer,1000,20);
delay (500);
tone (buzzer,1000,20);
delay(500);
seconds++;
if (seconds < 2) LastChance();
SendLoRaData = 1;
}
void NewData(){
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;
}
void BData(){
ago1 = (millis() - rxtime1) /1000 / 60;
delay (20);
Serial.print (lat1);
delay (1000);
Serial.print (lng1);
delay(1000);
Serial.print (ago1);
delay(20);
ago1 = 12345;
}
Please let me know if there are any errors or if there is something I could do better as I am new to this way of writing code!