Go Down

Topic: Help with logic (Read 436 times) previous topic - next topic

daniloke

Yeah sorry, but you get the blinking LED. the check to see if a certain amount of time has passed and then executed a toggle of the led status, the siren is in a way something similar, but since there are no individual steps, well there are or could be, 300 step 1 way and 300 steps back, rather then waiting for elapsed time to take the next step, we measure the whole cycle, and calculate at which step we should be. But Ok doesn't matter so much.Yeah i figured as much, but it is as Morgan said, it is the 'int' that just shouldn't be there to begin with,
the sketch i posted earlier can be converted to a function which is called if the alarm is ringing. I took your code added it removed the other delay() thing (because you have started with a situation in which delay() does not work, if you want to press button and get a response, well during delay() that can only be done with interrupts and using millis() is definitely something you should start with before that)
I had to make it more readable for me, so i moved a few thing around a bit, put all the include's together, all the #defines etc.

Then the issues remaining , one i don't have the button class in my GFX, it should be there but it isn't so i can't verify if it compiles, there may be typos and other small errors, i had to modify some variable names into #defines, which i (and others) tend to write in Caps. so do the honors, compile.
and second, how do you want it to work ? i set it up now (leaving your aux variable as a state-machine counting down from 99) that when the alarm is on and the sensor is triggered it rings and the led flashes until it is turned off.  You could set it up so it stops when either it is turned off or the sensor is no longer triggered, you could also let the LED blink if it is turned on (armed) but only the siren rings when the sensor is triggered (though for that the Alarmringing() function should be split into to separate ones) etc. anyway have a look.
Deva, thanks for the reply! I've compiled here and get some errors, look:
Code: [Select]
Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Placa:"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users\jakk_\Documents\Arduino\Test\Test.ino: In function 'void loop()':

Test:66:9: error: assignment of read-only variable 'aux'

     aux = 98;

         ^

Test:73:9: error: assignment of read-only variable 'aux'

     aux = 99;

         ^

Test:76:45: error: assignment of read-only variable 'aux'

   if ((aux == 98) && (leitura == HIGH)) aux = 97;

                                             ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino: In function 'void AlarmRinging()':

Test:90:14: error: expected initializer before 'currentMillis'

   uint32_t g currentMillis = millis();       // ths section is from Blink without delay example

              ^

Test:91:7: error: 'currentMillis' was not declared in this scope

   if (currentMillis - previousMillis >= INTERVAL) {

       ^

Test:17:18: error: expected primary-expression before '=' token

 #define INTERVAL = 1000;

                  ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:91:41: note: in expansion of macro 'INTERVAL'

   if (currentMillis - previousMillis >= INTERVAL) {

                                         ^

Test:17:24: error: expected ')' before ';' token

 #define INTERVAL = 1000;

                        ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:91:41: note: in expansion of macro 'INTERVAL'

   if (currentMillis - previousMillis >= INTERVAL) {

                                         ^

Test:91:49: error: expected primary-expression before ')' token

   if (currentMillis - previousMillis >= INTERVAL) {

                                                 ^

Test:98:22: error: 'currentMillis' was not declared in this scope

   uint16_t inCycle = currentMillis % SIRENCYCLE;    // this is how i would use millis() & modulo

                      ^

Test:18:20: error: expected primary-expression before '=' token

 #define SIRENCYCLE = 2000;

                    ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:98:38: note: in expansion of macro 'SIRENCYCLE'

   uint16_t inCycle = currentMillis % SIRENCYCLE;    // this is how i would use millis() & modulo

                                      ^

Test:18:20: error: expected primary-expression before '=' token

 #define SIRENCYCLE = 2000;

                    ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:99:17: note: in expansion of macro 'SIRENCYCLE'

   if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back

                 ^

Test:18:26: error: expected ')' before ';' token

 #define SIRENCYCLE = 2000;

                          ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:99:17: note: in expansion of macro 'SIRENCYCLE'

   if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back

                 ^

Test:99:28: error: expected primary-expression before '/' token

   if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back

                            ^

Test:18:20: error: expected primary-expression before '=' token

 #define SIRENCYCLE = 2000;

                    ^

C:\Users\jakk_\Documents\Arduino\Test\Test.ino:102:36: note: in expansion of macro 'SIRENCYCLE'

   uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to

                                    ^

Test:102:47: error: expected primary-expression before '/' token

   uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to

                                               ^

Usando a biblioteca Adafruit_GFX na versão 1.0.2 na pasta: C:\Users\jakk_\Documents\Arduino\libraries\Adafruit_GFX
Usando a biblioteca MCUFRIEND_kbv na versão 2.9.8 na pasta: C:\Users\jakk_\Documents\Arduino\libraries\MCUFRIEND_kbv
Usando biblioteca TouchScreen na pasta: C:\Users\jakk_\Documents\Arduino\libraries\TouchScreen (legacy)
exit status 1
assignment of read-only variable 'aux'


I putted in here the libs used in the project if you want to.

About the code format, thanks for organize it. It's much better now. I confess that it was mess up a little hehe.

It should work like you said, when the alarm is armed by the button, should activate the sensor and when triggered, blink the leds and rings until the alarm button desarm has pressed.

Again, thanks a bunch for the help!  :)

MorganS

Quote
Code: [Select]
const int aux;
The keyword const means you promised not to change the value of aux. The error says you broke that promise.

You should probably remove "const".
"The problem is in the code you didn't post."

Deva_Rishi

yep all typos
Code: [Select]
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>

#define MINPRESSURE 200
#define MAXPRESSURE 1000

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define INTERVAL 1000;  // removing the '=' should take care of the last few errors
#define SIRENCYCLE 2000;

const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341
const int TS_LEFT = 907, TS_RT = 136, TS_TOP = 942, TS_BOT = 139;

const int buzzer = A14;
const int PIR = A13;
const int led = A15;
int aux = 98;  // this should not be 'const' and in fact also not 'bool' but 'int' or 'uint8_t' or something

MCUFRIEND_kbv tft;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 100);
Adafruit_GFX_Button on_btn, off_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars

void setup()  {
  Serial.begin(9600);
  uint16_t ID = tft.readID();
  Serial.print("TFT ID = 0x");
  Serial.println(ID, HEX);
  Serial.println("Calibrate for your Touch Panel");
  if (ID == 0xD3D3) ID = 0x9486; // write-only shield
  tft.begin(ID);
  tft.setRotation(0);            //PORTRAIT
  tft.fillScreen(BLACK);
  on_btn.initButton(&tft,  80, 330, 130, 40, WHITE, CYAN, BLACK, "ARMAR", 2);
  off_btn.initButton(&tft, 240, 330, 130, 40, WHITE, CYAN, BLACK, "DESARM.", 2);
  on_btn.drawButton(false);
  off_btn.drawButton(false);
  pinMode(PIR, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  bool down = Touch_getXY();
  int leitura = digitalRead(PIR);
  on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
  off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
  if (on_btn.justReleased())          on_btn.drawButton();
  if (off_btn.justReleased())         off_btn.drawButton();
 
  if (on_btn.justPressed()) {
    on_btn.drawButton(true);
    tft.fillRect(60, 100, 180, 100, GREEN);
    delay (100);
    tft.fillRect(60, 100, 180, 100, BLACK);
    aux = 98;
  }
  if (off_btn.justPressed()) {
    off_btn.drawButton(true);
    tft.fillRect(60, 100, 180, 100, RED);
    delay (100);
    tft.fillRect(60, 100, 180, 100, BLACK);
    aux = 99;
    StopAlarm();
  }
  if ((aux == 98) && (leitura == HIGH)) aux = 97;
  if  (aux == 97) AlarmRinging();
}

void StopAlarm() {
  noTone (buzzer);
  digitalWrite(led, LOW);
}

void AlarmRinging() {
  static int ledState = LOW;                // these variables are static & local now
  static uint32_t previousMillis = millis();  // which means they hold their value and are not destroyed
                                              // when the function ends (but not accessable outside the function)
 
  uint32_t currentMillis = millis();       // ths section is from Blink without delay example 
                                                      // the 'g' should not have been there
  if (currentMillis - previousMillis >= INTERVAL) {
    previousMillis = currentMillis;
    if (ledState == LOW)   ledState = HIGH;
    else ledState = LOW;
    digitalWrite(led, ledState);
  }

  uint16_t inCycle = currentMillis % SIRENCYCLE;    // this is how i would use millis() & modulo
  if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back
    inCycle = SIRENCYCLE - inCycle;
  }
  uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to
  tone(buzzer, freq);
}

bool Touch_getXY() {
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);   //because TFT control pins
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
    pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
  }
  return pressed;
}
removed the errors for you, though some you should have been able to find as well.
note : i changed 'unsigned long' to uint32_t which in fact is a different way of writing the same thing (but shorter), an unsigned 32 bit integer.
To 'Correct' you have to be Correct. (and not be condescending..)

daniloke

yep all typos
Code: [Select]
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>

#define MINPRESSURE 200
#define MAXPRESSURE 1000

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define INTERVAL 1000;  // removing the '=' should take care of the last few errors
#define SIRENCYCLE 2000;

const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341
const int TS_LEFT = 907, TS_RT = 136, TS_TOP = 942, TS_BOT = 139;

const int buzzer = A14;
const int PIR = A13;
const int led = A15;
int aux = 98;  // this should not be 'const' and in fact also not 'bool' but 'int' or 'uint8_t' or something

MCUFRIEND_kbv tft;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 100);
Adafruit_GFX_Button on_btn, off_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars

void setup()  {
  Serial.begin(9600);
  uint16_t ID = tft.readID();
  Serial.print("TFT ID = 0x");
  Serial.println(ID, HEX);
  Serial.println("Calibrate for your Touch Panel");
  if (ID == 0xD3D3) ID = 0x9486; // write-only shield
  tft.begin(ID);
  tft.setRotation(0);            //PORTRAIT
  tft.fillScreen(BLACK);
  on_btn.initButton(&tft,  80, 330, 130, 40, WHITE, CYAN, BLACK, "ARMAR", 2);
  off_btn.initButton(&tft, 240, 330, 130, 40, WHITE, CYAN, BLACK, "DESARM.", 2);
  on_btn.drawButton(false);
  off_btn.drawButton(false);
  pinMode(PIR, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  bool down = Touch_getXY();
  int leitura = digitalRead(PIR);
  on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
  off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
  if (on_btn.justReleased())          on_btn.drawButton();
  if (off_btn.justReleased())         off_btn.drawButton();
 
  if (on_btn.justPressed()) {
    on_btn.drawButton(true);
    tft.fillRect(60, 100, 180, 100, GREEN);
    delay (100);
    tft.fillRect(60, 100, 180, 100, BLACK);
    aux = 98;
  }
  if (off_btn.justPressed()) {
    off_btn.drawButton(true);
    tft.fillRect(60, 100, 180, 100, RED);
    delay (100);
    tft.fillRect(60, 100, 180, 100, BLACK);
    aux = 99;
    StopAlarm();
  }
  if ((aux == 98) && (leitura == HIGH)) aux = 97;
  if  (aux == 97) AlarmRinging();
}

void StopAlarm() {
  noTone (buzzer);
  digitalWrite(led, LOW);
}

void AlarmRinging() {
  static int ledState = LOW;                // these variables are static & local now
  static uint32_t previousMillis = millis();  // which means they hold their value and are not destroyed
                                              // when the function ends (but not accessable outside the function)
 
  uint32_t currentMillis = millis();       // ths section is from Blink without delay example  
                                                      // the 'g' should not have been there
  if (currentMillis - previousMillis >= INTERVAL) {
    previousMillis = currentMillis;
    if (ledState == LOW)   ledState = HIGH;
    else ledState = LOW;
    digitalWrite(led, ledState);
  }

  uint16_t inCycle = currentMillis % SIRENCYCLE;    // this is how i would use millis() & modulo
  if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back
    inCycle = SIRENCYCLE - inCycle;
  }
  uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to
  tone(buzzer, freq);
}

bool Touch_getXY() {
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);   //because TFT control pins
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
    pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
  }
  return pressed;
}

removed the errors for you, though some you should have been able to find as well.
note : i changed 'unsigned long' to uint32_t which in fact is a different way of writing the same thing (but shorter), an unsigned 32 bit integer.
Deva, thanks for the reply. I had some problems with internet and couldn't reply here. I fix some other issues that appears when I compiled the code but I've been able to make work exacly as you said it would. Thank you so much!

I've only change the defines INTERVAL and SIRENCYCLE to the values direcly on the code because with the defines been called on the code, an error is shown:

Code: [Select]

C:\Users\jakk_\Documents\Arduino\testeteste\testeteste.ino: In function 'void AlarmRinging()':

testeteste:17:22: error: expected ')' before ';' token

 #define INTERVAL 1000;  // removing the '=' should take care of the last few errors

                      ^

C:\Users\jakk_\Documents\Arduino\testeteste\testeteste.ino:92:41: note: in expansion of macro 'INTERVAL'

   if (currentMillis - previousMillis >= INTERVAL) {

                                         ^

testeteste:92:49: error: expected primary-expression before ')' token

   if (currentMillis - previousMillis >= INTERVAL) {

                                                 ^

testeteste:18:24: error: expected ')' before ';' token

 #define SIRENCYCLE 2000;

                        ^

C:\Users\jakk_\Documents\Arduino\testeteste\testeteste.ino:100:17: note: in expansion of macro 'SIRENCYCLE'

   if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back

                 ^

testeteste:100:28: error: expected primary-expression before '/' token

   if (inCycle > SIRENCYCLE / 2) {                   // iow if it is on the way back

                            ^

testeteste:18:24: error: expected ')' before ';' token

 #define SIRENCYCLE 2000;

                        ^

C:\Users\jakk_\Documents\Arduino\testeteste\testeteste.ino:103:36: note: in expansion of macro 'SIRENCYCLE'

   uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to

                                    ^

testeteste:103:47: error: expected primary-expression before '/' token

   uint16_t freq = map (inCycle, 0, SIRENCYCLE / 2, 1500, 1800 ); // use the map function to

                                               ^

Usando a biblioteca Adafruit_GFX na versão 1.0.2 na pasta: C:\Users\jakk_\Documents\Arduino\libraries\Adafruit_GFX
Usando a biblioteca MCUFRIEND_kbv na versão 2.9.8 na pasta: C:\Users\jakk_\Documents\Arduino\libraries\MCUFRIEND_kbv
Usando biblioteca TouchScreen na pasta: C:\Users\jakk_\Documents\Arduino\libraries\TouchScreen (legacy)
exit status 1
expected ')' before ';' token


I think that the code don't identifies the defines. Maybe I should change to int or other declaration?

TheMemberFormerlyKnownAsAWOL

Remove the semicolon
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

Deva_Rishi

To 'Correct' you have to be Correct. (and not be condescending..)

Go Up