text:
Im trying to get a 3 button password sequence working
I'm trying get a password system working that when you click 3 buttons in a certain order (1, 2, 3, 3, 1) then an LED will light up. But as I'm going to implement this into a larger code I can't just have the void loop() going forever to wait for it.
I think my issue is in the while loops and making it wait for one of the buttons to be pressed but I don't know how to get it to work.
thanks
#define greenLED A0
#define redLED A1

int button1 = 5;
int button2 = 4;
int button3 = 3;

void setup() {
  // put your setup code here, to run once:
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  int total = 0;
  while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
    while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
      while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
        while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
          while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
            if(digitalRead(button1) == HIGH){
              total = total + 1;
            }
          }
          if(digitalRead(button2)==HIGH){
            total = total+1;
          }
        }
        if(digitalRead(button3)==HIGH){
          total = total + 1;
        }
      }
      if(digitalRead(button3)==HIGH){
        total = total+1;
      }
    }
    if(digitalRead(button1) == HIGH){
      total = total+1;
    }
  }
  if(total == 5){
    digitalWrite(A0, HIGH);
    delay(2000);
    digitalWrite(A0, LOW);
  }else{
    digitalWrite(A1, HIGH);
    delay(2000);
    digitalWrite(A1, LOW);
  }
}

you need each button pressed to push something to a stack, then examine the stack for patterns; no waiting, no blocking, no nesting, no complexity. a String could work as a stack, and it's got built-in tools to find patterns.

Without programming everything out, use something like this:

Initialization:

Create a (global) variable of string ("12331") which is the code
Create a (global) variable of int that shows the number of correct numbers so far (initially 0)

In the while loop:

Check which button is pressed
If it is the correct button
increase the int variable
If that variable is 5 (meaning all numbers ok), light up the LED
Delay
Make the variable 0 again
Clear the LED
If the wrong button is pressed
If it is equal to the first value ('1')

Set the variable to 1 (since the wrong number is the first correct number)

Else

Set the variable to 0

For something like this, a state machine would probably be useful. Since this is software, we can skip the register assignment and use a state table directly.
The table would look as follows:
1. If button 1 is pressed, 2. Else 1.
2. If button 2 is pressed, 3. Else 1.
3. If button 3 is pressed, 4. Else 1.
4. Run task, go to 1.

The code would require you to add an integer or byte outside setup or loop.
This would then contain the state number.
Inside loop, you can add the if statements for reading the button pins.
If one of the buttons is pressed (the if-statement fires), you can compare the state with the condition listed above. If the state and the correct condition match, set the state to the new state.
Otherwise, reset it to the initial state (0 is default if you do not explicitly change it when programming, and most things are 0-indexed. You can also use 1, but you have to remember to initialize it to 1 when declaring the state variable. i.e. byte state=1;)
The below sample code presumes that the buttons are connected between GND and the GPIO input pin on the Arduino. Since it's using the internal pullup resistors, no external ones are needed. The one minor issue is that it inverts the state of the buttons -- 0==pressed, 1==released (not pressed).
byte state = 0;
bool pressed=false;//used to prevent repeats

void setup(){
  pinMode(pin1,INPUT_PULLUP);
  //Repeat for other pins. Replace pin# with the number.
}

void loop(){
  if (digitalRead(pin1)==0 && !pressed){
    pressed=true;
    if (state==0){
      state=1; //go to next state.
    }
    else{
      state=0; //reset state. Needed even here since the button might be
               //pressed later at the wrong time. Add 'else if (state==#)'
               //sections if the button needs to be reused again in later states.
   }
   if (digitalRead(pin1) && pressed){
     pressed=false;
   }
   //Add more if statements here, following the pattern, for any more buttons you need.
}

Further improvements may involve getting independent press-detection variables (one for each button), but being only able to register one button press at a time is probably a good thing, actually.

You can split this into two different problems, and I suggest you track
them one at a time.
The first problem is to detect the button presses. This is not as
trivial as it sounds. For once, digitalRead() tells you whether the
button is pressed, but that's not quite what you want. You want to
detect the discrete press “events”. In other words, you have to remember
the previous state of the button, and record a press event only when the
state changes from HIGH to LOW. This is called “edge detection”.
When doing this on mechanical buttons, you absolutely must do some
kind of debouncing.
I will not elaborate on this topic, as there are a few Arduino libraries
available for debouncing buttons that also do edge detection. Once you
have sorted this out, each of your buttons will have a .fell() method
that tells you whether that button has just been pressed. Then, inside
loop(), you can do something like
char key = 0;  // key pressed by the user, 0 = none
if (button1.fell()) key = '1';
else if (button2.fell()) key = '2';
else if (button3.fell()) key = '3';
if (key) {  // some key has been pressed
    // process key...
}

The “process key...” part should initially be a simple
Serial.write(c);. This way you can use the serial monitor to check
that this part of the program is working properly. Only when this is the
case you can move to the second part.
The second problem is to process the key presses in order to detect
whether the correct code has been entered. There are various possible
approaches. One of them is to store in an array the 5 last keys
entered by the user, and compare that array with the correct code to
know whether the entry was correct. This is not very elegant, as it will
require storing more information than necessary, and shifting the array
each time a new key is typed.
A more elegant solution is given by Michel Keijzers. Let me paraphrase
it in C++. Inside loop():
if (key) {  // some key has been pressed
    if (check_code(key)) {  // correct code typed
        digitalWrite(LED, HIGH);
        delay(1000);
        digitalWrite(LED, LOW);
    }
}

where the logic for checking the correctness of the typed code is:
bool check_code(char key)
{
    const char code[] = "12331";
    const uint8_t length = sizeof code - 1;
    static uint8_t i = 0;  // number of correct characters so far

    if (key == code[i]) {  // correct key
        ++i;               // one more correct character
        if (i == length) {
            i = 0;         // reset
            return true;   // report entry is correct
        }
    } else {               // wrong key
        if (key == '1')
            i = 1;
        else
            i = 0;
    }
    return false;
}

Note that the part that handles a wrong key press is specific to that
particular code. If you want the program to be generic, so that you can
change the secret code just by changing the string code, it can get
more complicated. For example, if the correct code is “12313” and the
user has so far typed “1231”, he has so far 4 correct keys. Then,

if he types 1, he now has 1 correct key press
if he types 2, he has 2 correct keys (namely “12”)
if he types 3, he completed the code.

Handling this generically requires walking back the code string and
searching for the longest possible match. Here is my take at it: replace
the else part in the function above with:
// ...
} else {               // wrong key
    for (int j = i-1; j >= 0; j--) {
        if (key == code[j]) {
            int k;
            for (k = 0; k < j; k++) {
                if (code[k] != code[i-j+k])
                    break;
            }
            if (k == j) {  // found a partial match
                i = j + 1;
                return false;
            }
        }
    }
    i = 0;  // no partial match
}
// ...

Here j is the position, within the code string, where the key typed by
the user may match.

As Edgar Bonet mentions in his answer, button debouncing is a critical component, and there are libraries available to simplify this part of the requirement. I used the Bounce2 library with three N.O. push button switches. The following sketch works, but it still needs one or two improvements.
One issue occurs if the user enters 4 button presses, then leaves and comes back in 1 hour. All they have to do press the last correct button in the sequence, then they are authenticated. This could easily be fixed by introducing a millis() based timer that starts on the first button press, and stops after 5 seconds, for example. This timer would reset the counter variable and the buttonsPressed[] byte array.
Perhaps a "enter" code button and/or a "cancel" button would be useful.
#include <Bounce2.h>

const byte sequenceLength = 5;
byte sequence[sequenceLength] = {1, 2, 3, 3, 1};

byte buttonsPressed[sequenceLength];
byte counter = 0;
const byte ledPinCodeAccepted = 2;
const byte ledPinCodeDenied = 3;
const byte button1Pin = 10;
const byte button2Pin = 11;
const byte button3Pin = 12;
const unsigned long debouncerInterval = 50;

Bounce button1 = Bounce();
Bounce button2 = Bounce();
Bounce button3 = Bounce();

void setup(){
  pinMode(ledPinCodeAccepted, OUTPUT);
  pinMode(ledPinCodeDenied, OUTPUT);
  button1.attach(button1Pin, INPUT_PULLUP);
  button1.interval(debouncerInterval);
  button2.attach(button2Pin, INPUT_PULLUP);
  button2.interval(debouncerInterval);
  button3.attach(button3Pin, INPUT_PULLUP);
  button3.interval(debouncerInterval);
}

void loop(){

  if(button1.update()){
    if(button1.read() == 0){
      buttonsPressed[counter] = 1;
      counter++;
    }
  }

  if(button2.update()){
    if(button2.read() == 0){
      buttonsPressed[counter] = 2;
      counter++;
    }
  }

  if(button3.update()){
    if(button3.read() == 0){
      buttonsPressed[counter] = 3;
      counter++;
    }
  }

  if(counter == sequenceLength){
    counter = 0;
    digitalWrite(ledPinCodeAccepted, LOW);
    digitalWrite(ledPinCodeDenied, LOW);
    for(byte i = 0; i < sequenceLength; i++){
      if(sequence[i] == buttonsPressed[i]){counter++;}
      else{break;}
    }
    if(counter == sequenceLength){
      digitalWrite(ledPinCodeAccepted, HIGH);
    }
    else{
      digitalWrite(ledPinCodeDenied, HIGH);
    }
    counter = 0;
  }
}

There is a small issue here: if the user types “1231” oops! Then “12331”, this program will not accept his input as valid. The expected behavior for any kind of keypad lock is to accept it.

Perhaps a "enter" code button and/or a "cancel" button would be useful.

Keypad locks are a very common form of user interface. This ubiquity creates user expectations, including simplicity and ease of use. If you require the user to press a “cancel” button when he oops, you are violating this expectation and thus making a poor user experience.

The OP says they are making a "password system" in the question. Is that the same as a Keypad Lock? I don't know. I don't even know what a "password system" is :) The enter/cancel buttons are very common here in Canada. Look at bank "cash" machines for example. The user is forced to press an enter button when they have completed entering their password. There is also a cancel button, and a "timeout" period where keypad inactivity causes your bank card to be ejected from the machine.

I don't know if the bank cash machine forces you to press the cancel button, then enter your passcode again, or whether you can just enter your passcode after incorrect digits and press enter.


text:
Please explain the void loop() section of the sketch
#include <VirtualWire.h>

int PWMB = 5; //Speed control

void setup(){
  Serial.begin(9600);

  //receiver setup
  vw_set_rx_pin(2);
  vw_set_ptt_inverted(true);
  vw_setup(2000);
  vw_rx_start();
}

void loop(){
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    int column = 0;
    String message;
    int commands[30];

    for (i = 0; i < buflen; i++)
    {
      //DEBUG:
      Serial.print(char(buf[i]));

      if(char(buf[i]) == '|'){
        commands[column] = message.toInt();
        message = "";
        column++;
      } else {
        message += char(buf[i]);
      }
    }

  commands[column] = message.toInt();
  }
}

This topic is the receiver side of my last topic: please explain the sketch attached
that one sending date and this is a receiver.
questions:

The transmitter transfer date array of [60] like: 523 | 487, here int commands[30]; just 30, is it OK?
if(char(buf[i]) == '|') / commands[column] = message.toInt();, seems just convert the date before '|'?
What is the result of message += char(buf[i]);?

Thanks

The transmitter transfer date array of [60] like: 523 | 487, here " int commands[30];" just 30, is it OK?

If you have a maximum of 59 characters (59 printable characters plus the NULL at the end equals 60), and each number is separated by a | character, then the maximum possible numbers you can have, if they are all single digit, is 30. So yes, an array of 30 integers is fine.

" if(char(buf[i]) == '|') / commands[column] = message.toInt();", seems just convert the date before '|'?

Yes. It takes whatever has been placed in message and converts it to an integer, then empties message ready for the next number.

what is the result of " message += char(buf[i]);"? Thanks

It adds the current character from the buffer (pointed to by i) to the end of the message string.
It's not the best way of doing it, and it can make a mess of your heap causing your Arduino to crash after a while.
Personally I would use strtok() directly on the buffer:
int i = 0;
char *part = strtok(buffer, "|");
while (part) {
    command[i] = atoi(part);
    i++;
    part = strtok(NULL, "|");
}

This of course assumes that buffer is properly NULL terminated.

@ Majenko♦ Thank you Majenko♦, would you please ref to: https://arduino.stackexchange.com/questions/62576/please-explain-the-sketch-attached/62579?noredirect=1#comment134324_62579 and see what's the date sent? and see if there are match?

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Run website / Javascript game from a Arduino UNO device?
I apologise if this is a dumb question, but I'm trying to find information on whether or not this is possible. I'd like to build a arcade machine to play my custom Javascript 2D game. The game currently runs in the browser (of course), but is it possible to execute the code in the Arduino. I'd like to make an arcade machine that runs from the Arduino and connect the game controls to a joystick. Can anyone tell me is this is possible, or any suggestions about how I can achieve this without rewriting the application.
I found the below link that has some information but this is for a PI
https://www.raspberrypi.org/forums/viewtopic.php?t=194808

You're probably better off using a Raspberry Pi (or actual small PC). It is not going to run on Arduino w/o re-writing it to Arduino/C/C++.

The Arduino cannot run Javascript, no.
It could serve Javascript from an SD card to a web browser running on a PC / Pi / Phone, etc, but there is no way it can run it itself.

Thanks for the reply, So it is possible to run the game from an SD card in the browser that would be on the device. I just need to figure out if I can read the input from a joystick and read that input in the browser

There is no browser on an Arduino. The Ardunio would just be a (slow) web server to some other device. Which is pretty pointless, since whatever device it sends the javascript to would be a far better candidate for serving the javascript.

Think about it - you can't even connect a monitor to an Arduino. How could you run a browser? How would you see it?

this is true, thanks for your help. I think the best solution is to run the application from a laptop. But thanks for the fast answer!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
16 X 2 LCD display blank with Arduino Uno
So I am following this tutorial to make my arduino display hello world and millis(), I got it to work for a minute, but then it stopped updating the milliseconds, and when I pushed the reset button it went blank. since then, It has been blank but I have double, triple, and qaudruple checked checked my wiring, and it is flawless. I tried it with both of my 16 segment displays, but to no avail. I have redone the wiring, but it is still blank. Does anybody know what I could be doing wrong?
I followed this diagram
this is my code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}

This is the result (the screen is lit up, but there is no text even when turning the potentiometer)

i'm having trouble scrolling down in your code listing .....  lol .... please list the text of the complete sketch .....remove the picture of the code

that is not a 16 segment display .... this is http://www.embeddedadventures.com/images/uploaded_images/DSP_16S04H_2_600.jpg

Please do not post images of code, paste the code itself, select it all and then press {} to properly format it. Also this display is 16x2 character one, not a segment one.

ok, I didn't have it formatted right, my code is in text now

I have no idea what I did, i added a serial println to see if for some reason the program wasn't getting into the loop, and it started working :) EDIT: then I removed the println and it is still working... I guess it was a problem with the compiler or something... but I also checked the code so many times, and it was perfect

Sorry for all the notifs, I fixed my code, and thanks for informing me that the display isn't a 16 segment display. Do any of you have an idea as to what may have been wrong?

I suspect that you wiggled a loose Dupont wire back to it's place. They're quite flimsy. In addition to that, please post your best theory as the answer and click on the check mark button to mark it as the correct answer, adding (SOLVED) to the title is not how Arduino SE works.

Alright, I will do

It won't let me accept my own answer for two days, but I will check it then.

Do any of you have an idea as to what may have been wrong?  ..... perhaps the upload was failing and you did not see the error messages for some reason .... so you were re-running the same sketch over and over

I rewrote the sketch twice, I think it had to do with hardware, if you look at my answer below

It is most likely that I wasn't providing enough power to the arduino, and or had the potentiometer set to the wrong point. according to this post, you shouldn't run the arduino and display off of USB, because it may not actually be providing 5 volts. So I plugged it into the wall using a DC adapter. It now works.

If it solved your problem, you can accept your own answer to mark the question as answered.

It won't let me accept it until tomorrow


text:
Switch Statement stuck in loop
I am writing a code for a user to enter a 4 digit pin, then use this pin later to unlock a box. The loop is stuck between the "ready to unlock box" and "enter pin" it just keeps flipping between values but i want both to be displayed, just at different times.

#include <Keypad.h> //install keypad library
#include <LiquidCrystal.h> //install LCD screen library

const byte ROWS = 4; //include four rows of keypad
const byte COLS = 4; //indclude four cols of keypad

char keys[ROWS][COLS] = { //set keypad array equal to numbers on keypad
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

int pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8;
int code[] = {pin1, pin2, pin3, pin4};

byte rowPins[ROWS] = {45,43,41,39}; //connect to the row pins of keypad
byte colPins[COLS] = {37,35,33,31}; //connent to the column pins of keypad

LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //set up pins lcd will be connected to
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //set keypad up to use as variable

int solenoidPin = 1; //connect motor pin to code

bool in_press = false;
void setup() {
   Serial.begin(9600); //start code
   lcd.begin(16,2); //start screen with dimensions
}

void loop() //loop of functions to run through
{
  int key; //initialize key as integer

  lcd.setCursor(0,0);
  lcd.print("Press # to lock,");//welcome screen
  lcd.setCursor(0,1);
  lcd.print("or * to unlock.");

  key = keypad.getKey(); //let arduino know it is waiting for a value

    while (in_press && key == NO_KEY) //check if they want to begin
    {
      in_press = false; //if no key was clicked
      return; //exit the loop and restart
    }

    while (key != NO_KEY){ //if a key was clicked
      switch(key){
      case '#':
        lcd.clear();
        lcd.setCursor(0,0);
        *lcd.print("Ready to lock"); //let user know ready for next step of process
        lcd.setCursor(0,1);
        lcd.print("keys!");
        delay(1000);
        EnterPin1();
        break;*

      case '*':
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Ready to unlock"); //let user know ready for next step of process
        lcd.setCursor(0,1);
        lcd.print("keys!");
        delay(1000);
        EnterPin5();
        break;

       default:
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("No input");
       lcd.setCursor(0,1);
       lcd.print("detected.");
       break;
  }
 }
}

void EnterPin1()
{
  Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
  bool in_press = false;
  int pin1;

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter your pin.");//let user know you are waiting for input
  delay(1000);

  pin1 = keypad.getKey(); //let arduino know it is waiting for a value

    while (in_press && pin1 == NO_KEY) //check if they want to begin
    {
      in_press = false; //if no key was clicked
      return; //exit the loop and restart
    }

    while (pin1 != NO_KEY) //if a key was clicked
    {
      switch(pin1){
      case '1':
        pin1 = 1;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*"); //let user know ready for next step of process
        EnterPin2(); //go to enter pin function
        break;

      case'2':
        pin1 = 2;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*"); //let user know ready for next step of process
        delay(1000);
        EnterPin2();
        break;

      case '3':
        pin1 = 3;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '4':
        pin1 = 4;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '5':
        pin1 = 5;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '6':
        pin1 = 6;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '7':
        pin1 = 7;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '8':
        pin1 = 8;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '9':
        pin1 = 9;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;
   }
  }
 }

The logic may be incorrect.  Also try to make a https://en.wikipedia.org/wiki/Finite-state_machine which may avoid needing to define multiple functions EnterPin1, EnterPin2 3 etc.

Your primary loop code sets key, and then has a while (key != nokey) {} loop after, but the value of key never changes inside the while loop. Thus, if key is not equal to noKey, the while loop will never exit.
key = keypad.getKey();

while (key != noKey) {
  //code that does not change key
}

That is an endless loop. The fact that there’s a switch statement inside the while loop is immaterial. None of that code changes the value of key, so the loop will never exit.
Write it like this instead:
EDIT
key = keypad.getKey();
while (key != noKey) {
  //Your current code
  key = keypad.getKey();
}

You have the same logic problem in your enterPin1 function. You don’t provide the code for your enterPin2 function, but I would guess it also has the same logic problem.

That gives me error "expected ')' before ';' token", is there another part i should add in there?

Ok, I wasn’t sure if that syntax was legal or not. Apparently not. I’m at a tablet where I don’t have access to a C compiler. You could use your code, but add a final  key = kaypad.getKey() as the last statement in your while loop to fetch another value for key before looping back again.

See the edit to my answer. There’s a more elegant way to do this but I don’t have access to a compiler at the moment to get it right for you.


text:
Force TCNT to stay below OCRxA on ATmega328P
I'm using a timer and the TIMERx_COMPA ISR to generate a signal in "the background".
This ISR is triggered when the timer reaches a certain value (OCRxA), which in turn can be changed by the user.
Once the ISR triggers, the timer is reset and the next waiting period occurs.
If the compare value (OCRxA) is changed to a value below the current timer value before having hit the old compare value, the timer keeps running until it overflows back to 0 and hits the new OCRxA value. This results in no signal being generated until the timer has looped around, which can be quite long for the 16-bit TIMER1 timer.
There are multiple way to get around this:

Reset TCNTx to zero whenever OCRxA. Easy, but one signal will always be off-clock
If TCNTx is greater than OCRxA (after changing OCRxA), reset it to just below OCRxA
If TCNTx is greater than OCRxA, trigger the interrupt manually, where the signal is generated and TCNTx is reset

I belive the third option would be the cleanest, both in checking whether the issue has occured as well as for the signal quality.
This is certainly an X -> Y problem, so I'm open for other approaches.
My question, for now, would be:
Can I manually jump to an ISR regardless of its "normal" trigger?

@Juraj True, I suppose the "Electrical Engineering" SE would've been more appropriate?
I am programming an Arduino Uno with the Arduino IDE though.
I've always felt the line between those two SEs is very thin, especially when using the Arduino as nothing but a simple way to program the AVR.

I ask AVR specific questions on https://www.avrfreaks.net/forum/

Can I manually jump to an ISR regardless of its "normal" trigger?

This should be possible, but is probably not the best solution.

This is certainly an X -> Y problem, so I'm open for other
  approaches.

It would seem you are using the timer in CTC mode. In this mode, when
you write to OCRxA, the register is updated immediately, which leads
to the problem you are experiencing. The solution is to instead set the
timer to “fast PWM” mode. In fast PWM mode, the OCRxA register is
double buffered: you will be actually writing to a buffer register, and
OCRxA is automatically updated from that buffer on the same timer
clock cycle that clears the counter.
It may sound counter-intuitive to use a PWM mode when you do not need
the PWM feature. However, as long as the “compare output mode” is set to
“normal port operation” for both channels, the timer will not generate
any PWM output, and you can legitimately use the fast PWM mode only for
its double buffer feature.

That's absolutely gorgeous.
It seems to work perfectly with my test code, without ever checking whether TCNT has reached past OCRxA.
The buffers delay would be irrelevant with OCRxA only being updated once per millisecond.
I'm a bit ashamed to admit I wasn't even using CTC though, the entire code had been in "normal" (mode 0), with me resetting TCNT as the first action in the ISR.
You were refering to "mode 4" where I could have just omitted the TCNT reset, right?

I had some code which would check for how long TCNT was larger than OCRxA and output that over serial.
This now "always" displays some of that "lag".
Am I right in assuming it's comparing my real TCNT value to the buffered OCRxA and not the active OCRxA and that this metric would now be meaningless / expected?
If so, is there any way of reading the "active" OCRxA vs. the  one in the buffer which is not yet "active"?

@TobiasWeiß: Re “the entire code had been in "normal" (mode 0) [...].”: Since the ISR prologue takes some time, and may even be delayed by other interrupts, your interrupt period is likely to be larger than you want. “You were refering to "mode 4" [...], right?” Right. “Am I right in assuming it's comparing my real TCNT value to the buffered OCRxA [...]?” Judging from the section “Output Compare Units” of the datasheet, it would seem this is the case. “Is there any way of reading the "active" OCRxA [...]?” Not that I am aware of.


text:
Reading NFC card (PN532) with Arduino Uno
I am trying to detect a RFID card using the NFC-PN532 module and Adafruit_PN532 library.
Initialization code:-
#include <Adafruit_PN532.h>
#include <Wire.h>

#define SCK  (13)
#define MISO (12)
#define MOSI (11)
#define SS   (10)
Adafruit_PN532 nfc(SCK, MISO, MOSI, SS);

void setup()
{
  Serial.begin(9600);
  Serial.println("Initializing please wait.......");
  delay(3000);
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata)
  {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }

  Serial.print("Device Found PN5 Chip");
  Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware version > ");
  Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.println((versiondata>>8) & 0xFF, DEC);
  nfc.SAMConfig(); //Set to read RFID tags
  Serial.println("Waiting for RFID Card ...");
}

Main loop:-
void loop()
{
  uint8_t success = 0;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
  uint8_t uidLength;
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  if (success)
  {
      Serial.println("Card Detected!");
  }
  else
  {
      Serial.println("Card Not Detected or Removed!");
  }
}

Whenever i place a valid card on the PN532, Card Detected! is printed on the serial monitor.
However, when i remove the card, Card Not Detected or Removed! does not get printed.
How can i make the program  to loop in such a way that it can detect when the card is present/removed?

once you fix this (not sure why it is behaving this way)  you wont detect when a card is removed ... you'll detect when a card is not present ... there's a difference :p

@JaromandaX yes, you are right. But then how do i modify the code to detect "card inserted"and "card removed"?

you'd achieve that with code that only prints card removed if this is the first loop after card was present, ... try adding nfc.setPassiveActivationRetries(0x10); to your setup just before nfc.SAMConfig(); - this should stop the code waiting for a card :p

The default behaviour of readPassiveTargetID is to wait "forever" for a card - which is why your code only sees when there is a card present
So, in setup() add nfc.setPassiveActivationRetries(0x10); as follows - comments came from my own code, but I'm sure they were originally in some example or other :p
// Set the max number of retry attempts to read from a card
// This prevents us from waiting forever for a card, which is
// the default behaviour of the PN532.
nfc.setPassiveActivationRetries(0x10);

// configure board to read RFID tags
nfc.SAMConfig();

As for "detecting" removal
void loop()
{
  static bool wasSuccess = false;
  uint8_t success = 0;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
  uint8_t uidLength;
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  if (success)
  {
      wasSuccess = true;
      Serial.println("Card Detected!");
  }
  else if (wasSuccess)
  {
      wasSuccess = false;
      Serial.println("Card Removed!");
  }
  else
  {
      // you may want to remove this, it will flood the output :p
      Serial.println("Card Not Detected!");
  }
}

@Patrick - including the detection of remove? I ask, because I've been meaning to write some code for my PN532 :p


text:
my LM35 temperature sensor gives weird measurements,
Board: esp32
I know my wiring is correct because I get data from the sensor, but the data is a bit weird.
At 22 celcius I get 140, even though if I do the voltage calculation (* 0.473372) it still doesn't work.
the number 0.473372... comes from taking the voltage 4.7v / 1024 * 1000 / 10
My code:
 Serial.print("temp: ");
 float temp = (analogRead(A13) * 0.473372781065088);
 Serial.println(temp);
 delay(2000);

Any answers?

What is the voltage into the analog input when you get that reading? Explain why you multiply by 0.473. Show your schematics. I think the LM35 needs decoupling capacitors (if I remember correctly). Have you omitted them? Add the info into your question - not in the comments.

Your "conversion" from ADC value to temperature looks far too simple.  You have to convert the ADC value to volts, then from the voltage you can calculate the temperature.  This is a simple excercise, and a quick google search turns up examples (with explanations) for using the LM35 with an ESP32.

What JRE says: remember that 0 = 0 V but 1023 = VCC (unless you chose a different reference voltage).

qustion is now updated

@JRE, im not sure what you mean, a short tutorial told me that i should make the conversion: analogRead value * (voltage to the sensor / 1024 * 1000 / 10)

what do you mean? @Bimpelrekkie

analogRead value * (voltage to the sensor / 1024 * 1000 / 10) I think it should be: Actual Voltage = analogRead_value * (ADC reference voltage / 1023), see: https://www.arduino.cc/en/Tutorial/ReadAnalogVoltage

I mean like this.

@JRE thanks, i worked, i guess my voltage conversion was wrong

how do i close this question?

You write an answer detailing what was wrong and how you fixed it (for the benefit of people in the future that have the same problem), wait the prescribed period, then accept it as the right answer.

btw: the esp32 is operated at 3.3V. so, if you really have a voltage of 4.7V at the analog inputs you are out of specs!

@SimSon what do you mean?

Normalizing voltage with 4.7v / 1024 * 1000 / 10 makes me believe that you measured/supplied a voltage of 4.7V. That's to much for the esp, the maximum permitted voltage is 3.6V as the esp32 must be operated at 3.3V

hmm idk, the documentation for the sensor said it needed 4.4 volts, so i just hooked it up with the vin pin

but i doesnt output 4.4 voltage, so i guess im fine

ok, the problem is that i used to the wrong voltage conversion, just use:
RawValue = analogRead("your analog input pin");
Voltage = (RawValue / 2048.0) * 3300;
Serial.println(Voltage);

this should print the tempeture in celcious

try this one i have worked with lm35 using this code and circuit. i have done this thing with arduino uno but you can try it with esp32

i dont need the sensor to measure minus decrease, so i use a diffrent setup


text:
Parsing data in arduino?
I just started working with Arduino and in my project I am trying to achieve the COMM between two Arduino using HC-05 in master and slave mode respectively, I configured it all successfully.
Now I want to send three HCSR-04 distance sensors data from master Arduino to slave Arduino via HC-05. I am sending each sensor data separated by " | ". following is the example format., which I got in serial monitor by connecting the master Arduino directly to PC via USB.
168|200|76
167|200|68
166|200|76
168|200|77
Now the problem is I am not able to read and parse this on the slave side. I tried with serail.readbytesuntill but I could not succeed. Please help me out that how I can read it and parse it.
Thanks in advance.

what does this mean? not able to read and parse ...... you either get no data, so there is nothing to parse or you get data, but you are unable to parse it    .............. what does this mean? I could not succeed ..... please describe what actually happens

it would be helpfull if you add the parts of your code ment for sending and reciving the data. Without it is difficult to find an answer.

As you can see from the comments Birender Brar, we need more information to be able to help you.
One way to accomplish your goal would be to:
Use Serial.readBytesUntil('\n', buffer, length) on the slave device to "read" the data in to a char array. The serial monitor can be set to automatically send a \n character for testing purposes, but your code on the master will have to do this. Send the data 168|200|76 with a \n appended to the end of the data: 168|200|76\n
Parse the data. Here is a example sketch that parses the data in to a integer array.
// Use Serial.readBytesUntil('\n', buffer, length)
// to fill the char array / string.
char str[] = "168|200|76\n";

// Set array size to maximum number of integers you will receive.
uint16_t myArray[3];

void setup(){

  Serial.begin(9600);

  int counter = 0;
  char* pch = strtok(str, "|");

  while(pch != NULL){
    myArray[counter] = atoi(pch);
    pch = strtok(NULL, "|");
    counter += 1;
  }

  // Print out the contents of the integer array.
  for(int i = 0; i < counter; i++){
    Serial.println(myArray[i]);
  }
}

void loop(){}


text:
How to use 2 serial port when WifiEsp library uses one of both
I try without success to receive datas from DataPort and transmit them to my computer via WifiPort, using ESP8266 wifi module. Each second, serial datas income on DataPort from another device.
Initialization as follow:
#include <SoftwareSerial.h>
#include "WiFiEsp.h"
SoftwareSerial DataPort(10, 11); // RX, TX
SoftwareSerial WifiPort(8, 9); // RX, TX

In setup:
Serial.begin(9600);
DataPort.begin(9600);
WifiPort.begin(9600);
WiFi.init(&WifiPort);

In loop, i do:
//WIFI PART
WifiPort.listen();
WiFiEspClient client = server.available();
if (client) {
 //.... bla...bla...bla...
}

//INCOMING SERIAL PART
DataPort.listen();
while (DataPort.available() > 0)
{
   char c = DataPort.read();
   str += c;
   if(c == '/')
   {
      Serial.println(str);
      str="";
      break;
   }
}

WIFI PART runs fine if i isolate INCOMING SERIAL PART and INCOMING SERIAL PART runs fine without WIFI PART.
So how can i receive datas on DataPort and transmit them when my computer ask them via the ESP8266 on WifiPort ?

please post the code in one block, not in chunks

Yes Juraj, but how to switch on DataPort from WiFiPort or getting via wifi the serial incoming datas? What is the good code?

DataPort only receives serial datas each second. Tx is not used. And I want to get this data with the ESP8266.

The esp8266 AT firmware doesn't wait until you listen on the SoftwareSerial instance. If there is a connection to the server it sends +IPD and data. If the SoftwareSerial instance doesn't listen the information about client connection is lost.
You must listen to esp8266 all the time, so you can't use two SoftwareSerial instances.
You could use the RX pin of Uno to received data over hardware Serial, if you only receive on DataPort and only print to SerialMonitor.

I saw an example of instance of SoftwareSerial here: https://www.arduino.cc/en/Tutorial/TwoPortReceive. I think I could make it with Esp8266...

it is what you have now. You must listen to esp8266 all the time, so you can't use two SoftwareSerial instances.

Sorry, but I don't understand and see how can I solve my problem.

wire the DataPort device to RX pin of Uno, remove SoftwareSerial for DataPort and read data from the device with Serial.read()


text:
Simple code to define pins used for Shift Register control - Error: a function-definition is not allowed here before '{' token
I'm simply trying to light up some pins on a customized circuit board via Arduino.
 My code below has the seemingly common error "a function-definition is not allowed here before '{' token".  I've scoured my code for open/close curly brackets and semi-colons. I also regularly do a quick ctrl+T to format it.  Now I am at a loss - any info/advice greatly appreciated!  The error occurs at the '{' after the 'void loop()' line towards the bottom:
// serially read in 32 bytes at a time to send to shift registers.
// currently updating every 0.1s in Matlab

// Define which pins will be used for the Shift Register control
int dataPin = 2;
int latchPin = 3;
int clockPin = 4;

#include <SPI.h>

void setup()
{
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);

  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPI.begin();

  //Configure each IO Pin
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  Serial.begin(115200);
  delay(1000);

  int seq
  [32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

  int timeElapsed = 2000;
  int timeOld = 0;
  int interval = 100;

  void loop()
  {
    Serial.flush();
    Serial.println('K');
    for (int i = 0; i < 32; i++)
    {
      while (Serial.available() == 0);
      {
        seq[i] = Serial.read();
      }
    }
    digitalWrite(latchPin , HIGH);
    digitalWrite(latchPin , LOW);
    for (int i = 0; i < 32; i++)
    {
      SPI.transfer(seq[i]);
    }
    digitalWrite(latchPin , HIGH); //necessary to tramsit to board
  }

You forgot to close your setup() function.

There's no closing bracket for your setup() function and your loop() function is inside setup(). Close off setup() with a }and then start loop()!

Ahh thank you.  I actually did that before then got a "initializing" error.  But I believe you just mentioning this helped me figure out where to put the "}"


text:
Need help with DAC to show more than one output with SPI (stuck and need help please)
I want to take 2 different outputs from my DAC from void setDacOutput function (and it should be switching with/like the timer for both outputs. One output of 2.9375V for 0.9ms from ISR if statement and other of 2.5V for 1.6ms from else statememt) but my DAC only gives one output (in ISR - interrupt service routine only one of the if statement dacfunction or the else statement's (when if statement is commented) runs, not both). I want the DAC to give value for both if and else statement in ISR. For the given code it is only giving 2.9375Volts (called in isr-if statement). Not giving 2.5V (called in isr-else statement).
My timer is giving correct output when I connect oscilloscope to Pin9 and gnd (0.9ms on and 1.6ms off).I am using TLV5616 DAC from TI. And I’ve tried to print something in both if and else of ISR and they work but Dacfunction runs only once giving only one output. Maybe something wrong with SPI. Any help will be extremely appreciated please.
This is my code:
// TLV5616 DAC communication using SPI
#include <SPI.h>

/*  TI TLV5616CP (2.7 to 5.5V) LP 12-Bit Digital to Analog Converter
For sensor details see: http://www.ti.com/lit/ds/sbas415c/sbas415c.pdf

Circuit:
TLV attached to Uno pins as follows:
TLV Pin         Uno Pin
1 (DIN)         11 (MOSI - Output)
2 (SCLK)        13 (SCK - Output)
3 (/CS)          8 (Chip selec8t - Output)
4 (FS)          10 (SS - Output)

Note: TLV5616 has no provision for MISO pin 12, output is in volts

// Pin 8 = /CS, Pin 10 = SS
const int chipSelect = 8;
const int slaveSelect = 10;

// Variables for TLV5616 Testing
const unsigned int control = 0x4000;
const unsigned int msbMask = 0xFF00;
const unsigned int lsbMask = 0x00FF;
unsigned int command, data;
byte commandMsb, commandLsb;

//Variables for timers setting
uint16_t timerOneVal[] = {14400, 25600};
uint8_t timerTwoVal[] = {90, 160};
bool timerOneItr = 0;
bool timerTwoItr = 0;

void setup(void)
{
  Serial.begin(9600);
  /* To "condition" the hardware we begin with the call: SPI.begin()
  which configures the SPI pins (SCK, MOSI, SS) as outputs. It sets
  SCK and MOSI low and SS high. It then enables SPI mode with the
  hardware in master mode which has a side effect of setting MISO as
  an input.

  The SPI.transfer call does the actual transfer of bytes. I must
  set /CS and SS at the appropriate time */

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2);       // Freq SPI_CLK = 8MHz
  SPI.setDataMode(SPI_MODE1);                // CPOL = 0, CPHA = 1
  pinMode(chipSelect, OUTPUT);
  pinMode(slaveSelect, OUTPUT);

  pinMode(9, OUTPUT);

  digitalWrite(9, LOW);

  setTimers();

}

void setTimers()
{
  cli();

  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 0xFFFF;                   // set compare match register first time to full value (change values later on in the Interrupt service routine - ISR)
  TCCR1A = 0x40;                    // toggle OC1A on compare
  TCCR1B = 0x09;                    // Set CS10 and WGM12 bits for no prescaling and turning on CTC mode
  TIMSK1 = 0x02;                    // enable timer compare interrupt

  sei();

}

void setDacOutput(unsigned int dacValue)
{
    digitalWrite(chipSelect, LOW);             // Enable TLV5616 /CS
    digitalWrite(slaveSelect, LOW);            // Enable TLV5616 FS

    /* The TLV5616 control bits are D14 and D13, D15 and D12 is don't care. The data
    to be written to the TLV5616 is in Bits D11 to D0. commandMsb is the (8-bit) MSB
    and commandLsb is the (8-bit) LSB of the 16-bit TLV5616 control word */

    command = control | dacValue;
    commandMsb = (command & msbMask) >> 8;
    commandLsb = command & lsbMask;
    SPI.transfer(commandMsb);
    SPI.transfer(commandLsb);
    delayMicroseconds(1);
    digitalWrite(slaveSelect, HIGH);            // Disable TLV5616 FS
    digitalWrite(chipSelect, HIGH);             // Disable TLV5616 /CS
//    SPI.end();
}

ISR(TIMER1_COMPA_vect)
{

  OCR1A = timerOneVal[timerOneItr];

  if(!timerOneItr){
    setDacOutput(0x0966);     // 2406/0x0966 for 2.9375V; 2045/0x0800 for 2.500V;
    timerOneItr = !timerOneItr;
  }
  else{
    setDacOutput(0x0800);
    timerOneItr = !timerOneItr;
  }

}

Majenko I accidentally deleted your answer. Can you kindly post again please?

Majenko Sir, I accidentally deleted your answer before even being able to read. Can you please post it again kindly?

you are mistaken about the answer from @Majenko .... you cannot delete someone's answer ... the answer would still be here

Perhaps Majenko removed the answer because it was not right? to be honest, you're asking about Dacfunction running once, but since there's no function called Dacfunction or even just Dac only you could possibly guess what you are referring to

@MuhammadUzairArif I did not write an answer. I edited your question to place your code in a code block. That is all.

The function name is void setDacOutput @JaromandaX


text:
WifiClient and aREST on esp32 - loop until new instructions recieved?
I've created a simple sketch for an esp32 that hosts a REST API that can be accessed via HTTP. Based on the instructions received from the client, the esp32 controls some neopixels with some various animations I've written.
Everything worked as expected until I got to an animation that runs in a while loop. The loop breaks when a new client is detected so that the light can switch functions. However, when the new client is detected, the client seems to be discarded or consumed, and i just end up back in the loop() function until I make a second HTTP request, then the changes to show up.
I'm sure it's something obvious, but what have I done wrong?
Code:
#include "WiFi.h"
#include "FastLED.h"
#include "aREST.h"
#include "ArduinoJson.h"

#define NUM_LEDS 64
#define DATA_PIN 18

CRGB leds[NUM_LEDS];
int LED_COUNT = 64;
int MAX_BRIGHTNESS = 200;

const char* ssid = "wifi";
const char* password = "password";
aREST rest = aREST();
WiFiServer server(80);
WiFiClient client;

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, LED_COUNT);
  flashAll(CRGB::Black);
  // Bind urls to the handling functions
  rest.function("random-strobe", randomStrobe);
  rest.function("solid-color", solidColor);
  rest.function("reset", reset);

  // Connect to WiFi and wait until we're connected to continue
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    flashAll(CRGB::Cyan);
    delay(500);
    flashAll(CRGB::Black);
    delay(500);
  }
  server.begin();
  flashAll(CRGB::Green);
  delay(2000);
  flashAll(CRGB::Black);
}

void loop() {
  if (checkForTask()) {
    rest.handle(client);
  }
}

boolean checkForTask() {
  // I have tried making this reassignment conditional
  // when the global 'client' is false, but it did not help
  //if (!client) { client = server.available(); }
  client = server.available();
  if (client) {
    return true;
  }
  return false;
}

int randomStrobe(String params){
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:application/json");
  client.println();
  client.stop();
  StaticJsonDocument<200> jsonDoc;
  Serial.println(params);
  Serial.println("params recieved. parsing...");
  auto error = deserializeJson(jsonDoc, params);
  if (!error) {
    // some setup stuff
    while(!checkForTask()){
      // do stuff in here
    }
    return 0;
  }
}

I have tried making this reassignment conditional how?

@JaromandaX Something like: if (client) {...} else { client = server.available();
if (client) {...} -- i couldn't find any good documentation on checking for a client without that reassignment part, but i'm sure there is a better way..

@Juraj I fail to see how this is different than what i have, really. could you elaborate?

Okay, I've managed to resolve the issue with some general direction from @juraj.
I now have TWO WifiClient instances:
WiFiClient client;
WiFiClient newClient;

This allows me to use the newClient instance to check for a new client:
boolean checkForTask() {
  newClient = server.available();
  if (newClient) {
    Serial.println("new client detected.");
    return true;
  }
  return false;
}

and only reassign the main client instance when a new client is actually detected:
void loop() {
  if (!newClient.connected()) {
    checkForTask();
  } else {
    client = newClient;
    runTask();
  }
}

This seems to work without any discernible side effects or additional resource usage, but if there is a more efficient way to accomplish this, please share. Thanks!

I show a simpler solution in my answer

server.available() doesn't return an already 'claimed' connection again. It returns a new connection or an empty WiFiClient object.
The esp8266 and esp32 Arduino core WiFi library close the underlying connection if the last referring WiFiClient instance is freed. The assignment of empty WiFiClient object frees the previous reference to underlying socket and if it was the last referrence, the library closes the socket.
You get a client with server.available() in checkForTask() and then you call server.available() again. It returns an empty WiFiClient object and you assign it to your WiFiClient object. The library closes the referred connection.
The solution is not to check server.available until WiFiClient is valid.
if (!client) {
  client = server.available();
}

Thank you for your help. How might I check for a new client to exit the loop, and then execute the client's instructions? What should me checkForTask() method look like? (I suspect the 'if' condition just needs to be revisited, though you should note that the client is declared globally, and should only be 'destroyed' by the reassignment, if i'm understanding correctly.) I have more experience with other languages, but my c++ is limited to arduino. sorry if i'm missing something obvious.

@shadowkrazee, I edited the answer. I don't understand why I didn't see the client is global. I solved all kind of similar traps with networking libraries in my project with Telnet server and WebServer on WiFi and Ethernet libraries https://github.com/jandrassy/Regulator/blob/8262f28b7452df0b75aa6c5a7bc676e14cd0cd26/Regulator/Telnet.ino#L23


text:
Any idea why my LED fails to operate with the if statement
I have tried several workarounds without success.
#include <LiquidCrystal.h>
float tempC;
int tempPin = 0;// BS E D4 D5 D6 D7
int buzzer = 4;
int LED =2;
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
unsigned char i;
void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Temp        C ");
pinMode(LED, OUTPUT);
pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
}
void loop()
{
tempC = getTemperature();
lcd.setCursor(6, 0); // Display Temperature in C
lcd.print(tempC);
delay(500);
}
float getTemperature()
{
int tempReading = analogRead(tempPin); // This is OK
double tempK = log(1000000.0 * ((1024.0 / tempReading - 1)));
//Temperature in Kelvin
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
return (tempK - 273.15);

if (tempC>0)
digitalWrite(LED,HIGH);
else
digitalWrite(LED, LOW);
}

two possible reasons ... 1. the led is incorrectly connected and it does not light no matter what you do ... 2. the if statement evaluates to a result that does not turn on the led

I edited your question and used the {} button for code formatting, but your code doesn't have any indentation. You need to edit your code to use proper indentation. Without that it is very hard to read.

Your code to look at temperatures is messed up. You have a global variable tempC. The function getTemperature() doesn't change the value of tempC, but it uses it to decide if the LED should be lit or not. That means that that function will make it's decision based on the previous value of tempC.

You should rewrite your getTemperature() function to put the Celsius temp into a temporary variable, use that to decide what to do with the LED, and then return the temporary value. That way getTemperature() will set the LED based on the just-calculated temp value, not on the old, now-out-of-date temp reading.

Also note that if tempReading is 0, your code will crash with a divide-by-zero error. You should add some error handling code to deal with that case.

The LED fails to operate with the if statement because calling the return statement Terminates a function and returns a value from a function to the calling function, if desired. Try your sketch with the return statement as the "last thing" in the function.
#include <LiquidCrystal.h>

float tempC;
int tempPin = 0; // BS E D4 D5 D6 D7
int buzzer = 4;
int LED = 2;
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
unsigned char i;

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Temp C ");
  pinMode(LED, OUTPUT);
  pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
}

void loop() {
  tempC = getTemperature();
  lcd.setCursor(6, 0); // Display Temperature in C
  lcd.print(tempC);
  delay(500);
}

float getTemperature() {
  int tempReading = analogRead(tempPin); // This is OK
  double tempK = log(1000000.0 * ((1024.0 / tempReading - 1))); //Temperature in Kelvin
  tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
  if (tempC>0) digitalWrite(LED,HIGH); else digitalWrite(LED, LOW);
  return (tempK - 273.15);
}

If that code fix doesn't work I suggest you write a sketch that forces the LED to high, delays, forces it to low, delays, and loops. See if the LED flashes. If not, you have a hardware problem with the wiring of your LED. if it does work, then you have a problem with reading your temperature sensor and need to debug that part of your project.

Thank for the assistance and responses.  It does appear as if I have a physical problem of some kind.  My LED did function after shifting my breadboard a bit.  My temperature value constantly fluctuates sporadically and applying heat to my thermistor does not result in changes in the displayed temperature value. However the LED does illuminate when values rise above the limit which means the code is good.  Thanks again

Thanks Duncan.  You have been of great assistance and I certainly have a lot of learning to do and I look forward to it :)

One of the challenges of building Arduino projects is that you have to debug hardware and software problems. Work in steps. Hook up an LED, write a sketch that toggles the output pin on and off on a timer, and make sure that it works. After that, you know the LED works. Then integrate that working LED pin into your code, and if the code doesn't work, you know it's a code problem, not a hardware problem. If you get screw results from your code, add a bunch of Serial.println() statements displaying the values as you go along until you find your problem


text:
Webserver on Arduino Mega with Ethernet Shield
I am working with an official Arduino Mega. I have mounted an officiel Ethernet Shield rev 2.
Everything works great, i have wrote a very basic webserver.
I wanted to host a bootstrap css file on my webserver. This file has a size of about 150 kilo-bytes. So i have inserted an SD card on the Ehternet Shield. I have put my css file on this SD card.
I am writing the content of my css file with this code:
File myFile = SD.open("bootstrap.min.css");
if (myFile)
{
    byte clientBuf[2048];
    int clientCount = 0;
    while (myFile.available())
    {
        clientBuf[clientCount] = myFile.read();
        clientCount++;

        if(clientCount > 2048-1)
        {
            client.write(clientBuf,2048);
            clientCount = 0;
        }
     }
     if(clientCount > 0) client.write(clientBuf,clientCount);
     myFile.close();
 }

It works, but it is very slow.
It takes about 30-40 seconds to load file into my browser.
I have tried to change clientBuf size but this is the optimal value i've set.
Any idea ?
Thanks

you should set Expires: header to let the browser cache the file. and set the content-length header to let the browser know how many bytes to expect. https://github.com/jandrassy/Regulator/blob/8262f28b7452df0b75aa6c5a7bc676e14cd0cd26/Regulator/WebServer.ino#L112

I agree but it will be slow for first load...

sorry, my largest file is only 10 kB. can you load framework files from Internet?


text:
Program Upload Loading problem
Please help me about this program uploading problem.
 Arduino: 1.6.13 (Windows 10), Board: "Arduino Nano, ATmega328P"
Sketch uses 930 bytes (3%) of program storage space. Maximum is 30,720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.
avrdude: ser_open(): can't open device "\.\COM1": The system cannot find the file specified.
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

did you select the right port in Tools menu?

It can have many options, the main reason is it cannot communicate with the Nano.
I try to create a list with options:

Hardware issues

Nano is broken (solution: change Nano)
USB cable is broken (solution: change cable)
USB port is broken (solution: change USB port)

Software issues

USB port 'corrupt' (solution: use another USB port)
USB connection incorrect (solution: reconnect USB cable)
IDE is corrupt (solution: reinstall IDE)
Nano in illegal state (solution: reset/reconnect power of Nano)
Serial communication is used (remove RX/TX wires)


text:
Control Air Pump Depending on Pressure Sensor
I am working with an Arduino Mega, a 12V micro air pump, and a MP3V5050 air pressure sensor. The sensor outputs an analog voltage depending on the pressure reading in an inflatable member. I'd like to turn on the micro air pump when the pressure is too low and turn off the pump when the pressure exceeds a determined threshold (exact pressure ranges are currently undetermined).
I have been looking for similar tutorials but this is my first experience working with Arduinos and most existing tutorials are either sensing or pump control, not both. I only have minor coding experience with MATLAB, so any help with this is appreciated. Thank you!

So you basically want a hysteresis control for the air pump.
const int lowerLimit;//fill in as needed
const int upperLimit;

void loop(){
    int pressure = readPressureSensor();
    if(pressure < lowerLimit) turnPumpOn();
    if(pressure > upperLimit) turnPumpOff();

}

The helper functions I used should be easy to implement based on the tutorials you found.

Nice, simple answer that should point the newbie in the right direction! (voited)


text:
Verifiy NTP server update - at start
I have function to start an NTP service, right after obtaining wifi connection ( using ESP8266 board ).
from time to time, I get an error saying date and time is01-01-1970... which I assume is due to not reaching the server as intended.
A retry counter was added to give few more retries, but somehow I does not do the trick since I never get the expected message NTP CHECK: # and retry number ( while get an invalid date ).
I know that NTP.begin() returns a bool to describe success/ failure obtaining a NTP server
EDIT1: using NtpClientLib
How can it be done ?

void startNTP() {
        int counter = 0;
        while ( !NTP.begin("pool.ntp.org", 2, true) && counter <=2){
          Serial.print("NTP CHECK: #");
          Serial.println(counter);
          counter +=1;
          delay(1000);
        };
        NTP.setInterval(clockUpdateInt); // in seconds
}

which NTP library are you using? never get the expected message NTP CHECK: # and retry number - that suggests that that NTP.begin returns true

if you are using https://github.com/gmag11/NtpClient library, then the only reason begin returns false is if you pass in invalid arguments

@JaromandaX - I'm using NtpClientLib- and YES I know that result is true but still date is as noted...

the point is there's no point in running begin over and over again, since it only returns false if you pass in invalid arguments - as you are passing valid arguments, there's no need to check ... the way I would do it, in the code that relies on valid time, check NTP.getLastNTPSync() and skip the code if the result is 0

But those are the arguments- which are not invalid

As I said, they are valid, therefore there's no point in checking if .begin returns true ... it does ... but .begin doesn't return true when the time has been synchronised! it returns true before there's even an attempt to synchronise the time - so you need to check for when the time is synchronised

Having read the NTPClientLib code, I would say that the first sync is not even attempted for 1 second after NTP.begin() is called anyway.

You could do this
void startNTP() {
    NTP.begin("pool.ntp.org", 2, true);
    delay(2000); // there seems to be a 1 second delay before first sync will be attempted, delay 2 seconds allows request to be made and received
    int counter = 2;
    while ( !NTP.getLastNtpSync() && counter <=2) {
        Serial.print("NTP CHECK: #");
        Serial.println(counter);
        counter +=1;
        delay(1000);
    };
    NTP.setInterval(clockUpdateInt); // in seconds
}

or, you could do this
void loop() {
    // code that doesn't rely on valid time
    //
    // lets say this bit of code requires sync'd time
    if (NTP.getLastNtpSync()) {
        // this will only run once NTP has been sync'd at least once
    }
    // more code that doesn't require sync'd time
}

Now, you may want to check how long time hasn't been sync'd for in your code and do something if it's been too long


text:
Correct Pins for Nodemcu 8266
I am building a small electronic project, and I am incorporating module nodeMcU 8266 in a box.
I would like to know which pins are for "flash" and for "reset"
I know there are 2 buttons on the module for those 2 actions, but I would like to add 2 external buttons for those function on the case of the project, like that I will not need to open the box everytime. I looked on the net, and I guess that for "reset", I must connect to pin "Rst" and pin "Grd", I mean those 2 pin must be shorted, but I prefere to get confirmation before to go further.
And also for the "flash", what are both pins that I must connect the external push button to, to replicate the button present on the module itself.
Also I would like to connect an external LED to the module, following the state of the blue SMD led.
The thing is that there is an SMD blue led on the module, I want to know what are the 2 pins that are similar to the contacts of the blue SMD led.
I want the External LED that I plan to incorporate to the case of the project, to light up when the SMD blue led on the module is on, and when the led to be off when the blue SMD led is off. I want that both follow the same state.
Blue SMD led "On" >>> external led "On"
and
Blue SMD led "Off" >>> external led "Off"
Sorry for the little confused explanation, and thanx in advance for any help and support.

What nodemcu version? There are several board revisions: v0.9, v1.0, v3

some info here https://circuit-diagramz.com/esp8266-12e-pinout-schematic-circuit-diagram/ ......... https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/master/NODEMCU_DEVKIT_V1.0.PDF .............. https://www.esp8266.com/wiki/lib/exe/fetch.php?media=schematic_esp-12e.png

The v0.9 and v1.0 NodeMCU boards have 2 LEDs: One on the AIthinker module, and one on the actual NodeMCU board.
The AIthinker module's LED is connected between Vcc (3.3V) and GPIO2 (labeled D4 on nodeMCU). It turns ON when D4 is set LOW.
The NodeMCU LED is connected between Vcc (3.3V) and GPIO16 (labeled D0 on nodeMCU).  It turns ON when D0 is set LOW.
The pin labeled RST is the Reset signal from the AIthinker module, and is active-high, meaning you connect RST to GND to put the device in a reset state.
The pushutton labeled FLASH is connected between GND and GPIO0 (labeled D3 on nodeMCU). When the this pin is LOW when the ESP8266 comes out of a reset state, the chip is in flash-bootloader mode, meaning it is ready to receive a new sketch. On a NodeMCU, however, the ESP8266 chip is placed in flash mode by the USB chip and the flashing software, so there is not a need to manually press this button.

Thank for the reply and the great information.
I think I have the NodeMCU board, on its back side it is righted "NODEMCU Amica"
unfortunatly I could not get any info on the version.
so for the additional Reset switch I follow your instruction, and the point is resoved.
About the additional Flash button, I think I will go without it, as you instructred.

About the additional external LED,so I followed your instruction and added a LED between PIN D0 and GND. It is ON when the blue Led on the Board is off, and turns off when the Board's Led light up.
so or external LED or included LED board is on. Me I am looking that they follow the same state,
Included LED ON >>> external LED ON
I fund some line the the sketch that I am supposed to flash to the board, maybe iit has something to do with it. maybe somebody can take a look.
void setup() {
#ifdef USE_LED16
pinMode(16, OUTPUT);
digitalWrite(16, LOW);
#endif

To swap the on/off for your external LED: If the legs are between GND and IOPIN, then reverse LED (anode - cathode) and connect between VCC and IOPIN.

I do not find PIn IOPIN, I looked on the board, and also tryed the different picture I could find, like from this site:
https://circuit-diagramz.com/esp8266-12e-pinout-schematic-circuit-diagram/
I see there are different GPI, maybe you meant GPIO0, so writed Pin D1 on the Board itself?

I mean whatever I/O Pin you are controlling it with

After a few combination, it is working!!
Here what I did:
anode to 3.3V
and
catode to D4
my additional Led light up following the included Blue Led on the Board!!
Exactly what I was looking for!
Thanx a lot ;)


text:
Compare incoming message from ESP8266
If there's one thing I never managed to do: it's comparing strings.
So I have the incoming message saved here
String Message2 = IClient[i].readStringUntil('\n');

And every time I try to compare it with
strcmp(Message2.c_str(),"Red"); //Hopefully comparing the Message2 with "Red"

I never get 0 returned.
I know from printing the Message2 to Serial that Message2 contains the word "Red".
I've tried using different methods (string.equal(string2); etc.) but it never said that they are equal. What am I missing out on?

Might want to remove the extra characters ("..."). Or compare with ""Red"".

Found the answer!
After testing around with changing the terminator of the readStringUntil('\n') method it appears that there were leading and trailing white spaces, though not being displayed on the serial monitor they still had an impact on the strcmp(string1, string2) method.
I could solve this problem by "trimming" the received string before comparing it by using the String1.trim(); method.
In the end looking like:
String Message2 = IClient[i].readStringUntil('\n');

Message2.trim();

strcmp(Message2.c_str(),"Red");

a week ago https://arduino.stackexchange.com/questions/62546/wifi-connection-times-out-if-credentials-retrieved-via-serial-terminal#comment134274_62546


text:
ESP8266 WiFiClient Slow Over LocalHost
Appears to be something to with Apache configuration, swapping to Nginx solved my issue.
I'm getting slow responses when using localhost with a NODEMCU 1.0 and esp8266 WiFi library.
If I GET a PHP file on a remote server the response is almost instantaneous and the output of the PHP file is printed extremely quickly after the HTTP headers. If I GET the same PHP file on localhost the response takes over 5 seconds even if that PHP files is echoing just a single character.
I've tried with XAMPP and a local server configuration on a Raspberry Pi but both have the same slow response speed.
void loop() {
  WiFiClient client;

  if (wiegand.available()) {
    // Convert the code into a suitable type and construct the GET request
    double readWiegand = wiegand.getCode();
    String readWiegandStr = String(readWiegand, 0);
    String httpGet = "GET /verify.php?code=" + readWiegandStr;

    Serial.printf("\n[Connecting to %s ... ", host);

    if (client.connect(host, 80)) {
      Serial.println("connected]");
      Serial.println("[Sending a request]");
      client.print(httpGet + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n" +
                   "\r\n"
                  );
    }

    Serial.println("[Response:]");

    while(client.connected() || client.available()) {
      if(client.available()) {
        String line = client.readStringUntil('\n');
        Serial.println(line);
        if(line == "ACCEPT") {
          Serial.println("Code accepted");
        } else if (line == "DECLINE") {
          Serial.println("Code declined");
        }
      }
    }
    client.stop();
    Serial.println("\n[Disconnected]");
  }

seems the issue is with the server if two different servers behave differently - perhaps your local server (not localhost, as that actually means something else) isn't closing the connection after sending the response

Thanks for the response, any ideas how I'd go about checking this?

check the local server is closing the connection in a timely manner - without knowing anything at all about your local server, the best I can do is suggest you "fix it" :p

I 'fixed it' by uninstalling Apache and installing Nginx, instant response with Nginx, thank you for the suggestions.

So much can be fixed by removing Apache :p


text:
HD44780 display incorrectly black-on-blue instead of white-on-blue
I have a generic HD44780 compatible 16x2 LCD display, with an already soldered on PCF8574 module. Its backlight is blue, and the characters are supposed to be white (on blue).
It is connected to a generic "Lolin" ESP8266 module which is working fine and is not related to the problem, I hope.
Using the LiquidCrystal_I2C library available at https://github.com/lucasmaziero/LiquidCrystal_I2C, I uploaded the simple "Hello, World" sketch provided, and it works. Used the most current libraries and Arduino IDE as of 2019-03-20.
However, the text displayed is a very dim black-on-blue instead of a bright white-on-blue.
I do not have any clue on why it happens and how to fix it (and that's my question).
What I know is that if I somehow "glitch" the display (for example by disconnecting and reconnecting the power lead) it will sometimes display gibberish, but in a very clear white-on-blue, so I know the LCD hardware is not defective per se.
I also tried a few other libraries to the same effect: LiquidCrystal_PCF8574 and LiquidCrystal_I2C (the version available directly from the Arduino IDE, source at https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library)
Below, the example sketch used to generate the problem. Be aware it is for the first LiquidCrystal_I2C library I referred above, but with changes, works with the others I tried.
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
  // initialize the LCD
  lcd.begin(); // Init with pin default ESP8266 or ARDUINO
  // lcd.begin(0, 2); //ESP8266-01 I2C with pin 0-SDA 2-SCL
  // Turn on the blacklight and print a message.
  lcd.backlight();
  lcd.setCursor(0, 0);

#if defined(ESP8266)
  lcd.print("ESP8266");
#else
  lcd.print("ARDUINO");
#endif

  lcd.setCursor(0, 1);
  lcd.print("Hello, world!");
}

void loop()
{
  // Do nothing here...
}

And a photo of the anomalous display. Turning the constrast potentiometer does not help.

what's the operating voltage on that device? How have you connected the power on it?

Operatin voltage seems to be 3.3V. If I connect the VCC line of the display to the Vin of the ESP8266 (5V in my case), nothing works, nothing is displayed.

Just tried connecting the i2c interface via a level converter (display side 5V, ESP8266 3.3V) and it doesn't power up. However if I power both sides of the level converter on the 3.3V rail it works "wrong" (So, no bad converter or wrong connections).

I had a similar problem.In my case it was contrast settings. Some of these displays require negative voltage to drive contrast pin (especially when powered from 3.3V). Because this pin doesn't draw much of current, a simple 2 diode and 2 capacitors fed with square wave (can be generated from your Arduino, or 555) will be sufficient.

@smajli, care to provide some details on how you achieved that? Free GPIOs on my project are at a premium, but it is worth the try!

There is a chance that this LCD would need a negative voltage on contrast PIN. Below there is a simple schematic. You would need to provide pulses on the 'Pulse in' branch. Use Negative voltage branch and potentiometer to feed your contrast pin.

It's so simple that's worth a try. Will post the result as soon as possible.

It worked nicely. However, not very practical. Why? Because the I2C module is soldered onto the LCD module, and to apply the negative voltage to the contrast pin I would need to cut its connection to the PCF8574 board and then solder an external connection to the negative voltage generator. Anyway, problem was solved, thank you very much.

This answer is just to complement @smajli's answers posted (and accepted) before.
The problem lies in that the contrast pin has to be fed negative voltages when the module is powerered via a 3.3V supply to be able to show text in the correct white-on-blue setting and not on the faint black-on-blue.
@smajli correctly showed how the negative voltage may be generated from the normal positive supply and a pulse generator. However, in my scenario, the pulse generator was connected to the +3.3V rail instead of +5V and the pulses where generated via the ESP8266's PWM feature. Using a duty cycle of 50% it generates about -2V. I'll not reproduce his schematic here, though, but below is a photo of it assembled and in action.

The updated code is exactly the same, with only the PWM generation added inside the setup() function:
  pinMode(D8, OUTPUT);
  analogWrite(D8, 512);   // 10-bit!

Finally, the photo below illustrates the final result.

Again, thanks again to @smajli for the previous insights and answer.
P.S.: Keen readers will notice the module used now is NOT the same used when I asked the question originally. It is another generic HD44870 module, but without the I2C interface, working in 4-bit mode. However, the exact same problem (black-on-blue text) occurs when the contrast pin is set to anywhere between +3.3V and GND and is promptly solved when using negative voltage.

Good to see your explanation. Good effort and nice effect.

I have a similar LCD display (I assume it's virtually identical, hard to confirm).  In my case, driving the display VCC (and SCK and SDA) at 3.3v produced the same behaviour you described (dim black text on blue background), but setting VCC to 5v gave me the correct white-on-blue display (even with SCK and SDA still driven at 3.3v, since those are the outputs of the MCU I was using).
It's curious that setting the VCC to 5v did not work in your case.


text:
Mqtt not subscribe on topic that's converted from String to char array
I am still not sure what should be the exact Title for this question, because I don't know where the problem is.
I am using #include <MQTTClient.h> mqtt library to subscribe on a topic.
This topic is created dynamically depending on the name of the device. Currently I am testing with device name myDeviceAbc.
String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
String espInTopicStr  = baseTopic + "/" + config.machineName + "/espIn"; //config.machineName is a string "myDeviceAbc"

const char* espInTopic  = "";
espInTopic = espInTopicStr.c_str();

const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn";

int rc = client.subscribe(espInTopic, MQTT::QOS0, messageArrived);
if (rc != 0) {
  Serial.print("rc from MQTT subscribe is ");
  Serial.println(rc);
  return;
}
Serial.println("MQTT subscribed");

Serial.print("size of hardcoded topic: ");
Serial.println(strlen(hardCodedTopic));
Serial.print("size of actual topic: ");
Serial.println(strlen(espInTopic));

Serial.print("hardCodedTopic >>>");
Serial.print(hardCodedTopic);
Serial.print("<<<");
Serial.println(".");

Serial.println("---");

Serial.print("espInTopic topic >>>");
Serial.print(espInTopic);
Serial.print("<<<");
Serial.println(".");

I have defined two variables for same topic
arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn
. one is hardcoded hardCodedTopic and other is created dynamically espInTopic.
when I subscribe on espInTopic, I get MQTT subscribed message on serial console BUT nothing is received on this topic when I publish from AWS portal.
but when I subscribe on hardCodedTopic I then receive all published messages. I cannot figure out what is the issue. I checked the mqttClient subscribe method inside the library header file, which is defined like this
int subscribe(const char* topicFilter, enum QoS qos, messageHandler mh);

/** MQTT Unsubscribe - send an MQTT unsubscribe packet and wait for the unsuback
 *  @param topicFilter - a topic pattern which can include wildcards
 *  @return success code -
 */
int unsubscribe(const char* topicFilter);

It does takes const char* as topic name. I though maybe due to conversion from String to char array, there might be some unknown characters appended in the char array espInTopic, but I also checked the size and content of both topics which is exactly the same.
size of hardcoded topic: 52
size of actual topic: 52
hardCodedTopic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.
---
espInTopic topic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.

Full Code:
#include <Arduino.h>
#include <Stream.h>
#include <EEPROM.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFiMulti.h>
#include "helpers.h"
#include "global.h"

//AWS
#include "sha256.h"
#include "Utils.h"

//WEBSockets
#include <Hash.h>
#include <WebSocketsClient.h>

//MQTT PAHO
#include <SPI.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>

//AWS MQTT Websocket
#include "Client.h"
#include "AWSWebSocketClient.h"
#include "CircularByteBuffer.h"

#define ACCESS_POINT_NAME  "VM"
#define ACCESS_POINT_PASSWORD  "12345678"

extern "C" {
  #include "user_interface.h"
}

//AWS IOT config, change these:
char wifi_ssid[]       = "TALKTALKAF521F";
char wifi_password[]   = "xxxxxxxx";
char aws_endpoint[]    = "xxxxxxxxxxxxxxxx.iot.us-east-2.amazonaws.com";
char aws_key[]         = "xxxxxxxxxxxxxxxx";
char aws_secret[]      = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char aws_region[]      = "us-east-2";

String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
//const char* espInTopic  = "";        // was global before, but later I also tried to keep this local on subscribe() method
const char* espOutTopic  = "";
int port = 443;

//MQTT config
const int maxMQTTpackageSize = 512;
const int maxMQTTMessageHandlers = 1;

const char response[] = "{\"response\": {\"request_id\":, \"data\":}}";

String nodeName = ""; // Name needs to be unique
String nodeMac = "";

ESP8266WiFiMulti WiFiMulti;

AWSWebSocketClient awsWSclient(1000);

IPStack ipstack(awsWSclient);
MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> client(ipstack);

//# of connections
long connection = 0;
unsigned long timer = 0;
unsigned long maxTimeOut = 7000;  //7 seconds

//generate random mqtt clientID
char* generateClientID () {
  char* cID = new char[23]();
  for (int i=0; i<22; i+=1)
    cID[i]=(char)random(1, 256);
  return cID;
}

//count messages arrived
int arrivedcount = 0;

//callback to handle mqtt messages
void messageArrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;

    Serial.print("Message ");
    Serial.print(++arrivedcount);
    Serial.print(" arrived: qos ");
    Serial.print(message.qos);
    Serial.print(", retained ");
    Serial.print(message.retained);
    Serial.print(", dup ");
    Serial.print(message.dup);
    Serial.print(", packetid ");
    Serial.println(message.id);
    Serial.print("Payload ");
    char* msg = new char[message.payloadlen+1]();
    memcpy (msg,message.payload,message.payloadlen);

}

//connects to websocket layer and mqtt layer
bool connect () {

    if (client.isConnected ()) {
        client.disconnect ();
    }
    //delay is not necessary... it just help us to get a "trustful" heap space value
    delay (1000);
    Serial.print (millis ());
    Serial.print (" - conn: ");
    Serial.print (++connection);
    Serial.print (" - (");
    Serial.print (ESP.getFreeHeap ());
    Serial.println (")");

   int rc = ipstack.connect(aws_endpoint, port);
    if (rc != 1)
    {
      Serial.println("error connection to the websocket server");
      return false;
    } else {
      Serial.println("websocket layer connected");
    }

    Serial.println("MQTT connecting");
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 4;
    char* clientID = generateClientID ();
    data.clientID.cstring = clientID;
    rc = client.connect(data);
    delete[] clientID;
    if (rc != 0)
    {
      Serial.print("error connection to MQTT server");
      Serial.println(rc);
      return false;
    }
    Serial.println("MQTT connected");
    return true;
}

//subscribe to a mqtt topic
void subscribe () {
   //subscript to a topic
  String espInTopicStr  = baseTopic + "/" + "myDeviceAbc" + "/espIn";
//  String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
  const char* espInTopic  = espInTopicStr.c_str();
//  espOutTopic = espOutTopicStr.c_str();

  const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxxxx:thing/myDeviceAbc/espIn";
  Serial.print("size of hardcoded topic: ");
  Serial.println(strlen(hardCodedTopic));
  Serial.print("size of actual topic: ");
  Serial.println(strlen(espInTopic));

   Serial.print("hardCodedTopic >>>");
   Serial.print(hardCodedTopic);
   Serial.print("<<<");
   Serial.println(".");

   Serial.println("---");

   Serial.print("espInTopic topic >>>");
   Serial.print(espInTopicStr.c_str());
   Serial.print("<<<");
   Serial.println(".");
   int rc = 99;
   while (rc != 0){
      rc = client.subscribe(hardCodedTopic, MQTT::QOS0, messageArrived);
      if (rc != 0) {
        Serial.print("rc from MQTT subscribe is ");
        Serial.println(rc);
        return;
      } else {
        Serial.println("");
        Serial.println("MQTT subscribed");
      }
      Serial.println("rc: " + String(rc));
      delay(500);
   }

}

//send a message to a mqtt topic
void sendmessage (const char* topic, String msg) {
    //send a message
    MQTT::Message message;
    char buf[100];
    strcpy(buf, msg.c_str());
    message.qos = MQTT::QOS0;
    message.retained = false;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
    int rc = client.publish(topic, message);
}

void setup() {

    wifi_set_sleep_type(NONE_SLEEP_T);
    EEPROM.begin(1024);
//    for (int i = 0; i < 1024; ++i) { EEPROM.write(i, 0); }
    Serial.begin(115200);
    ardMegaSerial.begin(9600);

    delay (2000);

    //////////////////////////////////////////
  if (!ReadConfig())
  {
    // DEFAULT CONFIG
    config.configMode = true;
    config.ssid = "N.A";
    config.password = "N.A";
    config.machineName = "N.A";
    config.dhcp = true;
    config.IP[0] = 192;config.IP[1] = 168;config.IP[2] = 1;config.IP[3] = 100;
    config.Netmask[0] = 255;config.Netmask[1] = 255;config.Netmask[2] = 255;config.Netmask[3] = 0;
    config.Gateway[0] = 192;config.Gateway[1] = 168;config.Gateway[2] = 1;config.Gateway[3] = 1;
    WriteConfig(true);
    Serial.println("default configs applied");
    //////////starting web config server hotspot
        Serial.println("No configuration stored, starting access point.");
        ESP.eraseConfig();
        WiFi.disconnect();
        WiFi.setAutoConnect(false);
        WiFi.setAutoReconnect(false);
        WiFi.mode(WIFI_AP_STA);
        nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
        WiFi.softAP(nodeName.c_str() , ACCESS_POINT_PASSWORD);
        Serial.print("Connect to ssid " + nodeName + " to configure Node on IP: ");
        Serial.println(WiFi.softAPIP());
        ConfigureWifi();
        server.on ( "/favicon.ico",   []() { Serial.println("favicon.ico"); server.send ( 200, "text/html", "" );   }  );
        server.on ( "/", send_gateway_node_config_html  );
        server.on ( "/admin/values", send_gateway_node_config_values_html );
        server.on ( "/admin/connectionstate", send_connection_state_values_html );
        server.on ( "/style.css", []() { Serial.println("style.css"); server.send ( 200, "text/plain", PAGE_Style_css );  } );
        server.on ( "/microajax.js", []() { Serial.println("microajax.js"); server.send ( 200, "text/plain", PAGE_microajax_js );  } );
        server.onNotFound ( []() { Serial.println("Page Not Found"); server.send ( 400, "text/html", "Page not Found" );   }  );
        server.begin();
        Serial.println( "HTTP server started" );
  } else {
      nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
      Serial.println("Device already configured");
      Serial.println("Wifi SSID: " + config.ssid);
      Serial.println("Wifi password: " + config.password);
      Serial.println("Node name: " + config.machineName);

      setupWifiAndAws();
  }

    //////////////////////////////////////////

}

void setupWifiAndAws() {
    char ssidBfr[500];
    strcpy(ssidBfr, config.ssid.c_str());
    char passBfr[100];
    strcpy(passBfr, config.password.c_str());
    //fill with ssid and wifi password
    WiFiMulti.addAP(ssidBfr, passBfr);
    Serial.println ("connecting to wifi");
    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
        Serial.print (".");
    }
    Serial.println("\nconnected");
    ardMegaSerial.println("ESP Started\n");
    //fill AWS parameters
    awsWSclient.setAWSRegion(aws_region);
    awsWSclient.setAWSDomain(aws_endpoint);
    awsWSclient.setAWSKeyID(aws_key);
    awsWSclient.setAWSSecretKey(aws_secret);
    awsWSclient.setUseSSL(true);

    if (connect ()) {
        String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
        espOutTopic = espOutTopicStr.c_str();
        subscribe();
        sendmessage (espOutTopic, "{\"device\":\"connected\"}}");
    }
}

void loop() {

  receiveFromArduino();
  //responseTimeOutCheck();
  //keep the mqtt up and running
  if (awsWSclient.connected ()) {
      client.yield(50);
  } else {
    //handle reconnection
    if (connect ()){
      subscribe ();
    }
  }

}

in that case, the difference should be clearly shown in Serial.print(espInTopic) ?
but I will paste in my full code today.

how can I check weather its valid later ?

its not global.

The c_str() function of the String class returns a pointer to current internal char array. This pointer is valid only until the String exists and is not changed.
Variable espInTopicStr is defined in a function and is destroyed at the end of the function. It frees the memory allocated for the internal char array.
You send a pointer to the internal char array of the espInTopicStr to client.subscribe. The MQTT library doesn't copy that char array, it only stores the pointer. Later the library uses the pointer to call the topic, but the memory on that location already changed and doesnt't contain the name of the topic.

placing the string espInTopicStr global, worked !... thank you so much Juraj for pointing out the issue :)


text:
Reaction timer using millis
I've written this code for a reaction timer game. The reaction time is to be displayed in milliseconds to the serial monitor as accurately as possible. The reaction time is not being displayed correctly. I'm including my timer setup routine and where I increment milliseconds.
TCCR1A=0;
TCCR1B=0;
timer1_counter=65536;
TCNT1=timer1_counter;
TCCR1B |=(1<<CS12);

TIMSK1 |=(1<<TOIE1);
interrupts();
}

ISR(TIMER1_OVF_vect)
{
  TCNT1=timer1_counter;
  int_flag=1;
 }

  digitalWrite(LED,LOW);
  randomSeed(analogRead(A1));
  NumSecs=random(1000,7000);
  delay(NumSecs);
  digitalWrite(LED,HIGH);
  while(digitalRead(PUSHBUTTON) == HIGH)
  {
  }
  if (int_flag==1){
  millisecs++;
  int_flag=0;
  }

You're over-thinking this:
  digitalWrite(LED,LOW);
  randomSeed(analogRead(A1));
  NumSecs=random(1000,7000);
  delay(NumSecs);
  digitalWrite(LED,HIGH);
  unsigned int startTime = millis();
  while(digitalRead(PUSHBUTTON) == HIGH)
  {
  }
  unsigned int elapsed = millis() - startTime;

After that code, elapsed will contain the number of milliseconds it took the user to press the button. Note, however, that the user could cheat and simply press the button the whole time while waiting for the LED to change states. You could add logic to make sure the button isn't pressed just before you change the LED state, but I'll leave that up to you.

Your ISR is not counting the elapsed milliseconds. Instead, it just sets
a flag and lets the main program do the counting when it sees the flag.
Here:
while(digitalRead(PUSHBUTTON) == HIGH)
{
}

you are waiting for the user to press the button. The program does
nothing else during the wait. It doesn't event count the time. Here:
if (int_flag==1){
    millisecs++;
    int_flag=0;
}

you increment once the millisecond count after the wait.
The obvious solution is to count the milliseconds while waiting for the
button press:
millisecs = 0;  // don't forget to reset the stopwatch!
while (digitalRead(PUSHBUTTON) == HIGH) {  // button not pressed
    if (int_flag) {
        millisecs++;
        int_flag = false;
    }
}

(side note: int_flag should be a bool).
There are still many issues with this program. First of all, it should
check that the user did not press the button before the LED came up.
Then, the interrupt period is not one millisecond, because the interrupt
takes some time to be processed by the CPU and to go through its
prologue. By the time you do TCNT1=timer1_counter; you are at least
several tens of cycles late. You should instead configure the timer to
keep the correct period by itself, typically using CTC mode.
Also, there is no point in letting the main program count the
milliseconds when the ISR could do it. E.g.
ISR(TIMER1_OVF_vect)
{
    millisecs++;
}

// Avoid a race condition when reading millisecs.
static inline unsigned int getMillisecs()
{
    noInterrupts();
    int millisecsCopy = millisecs;
    interrupts();
    return millisecsCopy;
}

Note that the time keeping variables should be unsigned in order to
avoid undefined behaviour on overflows.
Finally, it may be a good learning experience for working with
interrupts, but in the end just using millis() or micros() would be
the easiest way to achieve what you want.

Ok thank you. I'll give millis() a try.


text:
Play computer *.wav files through Arduino
I am doing mice behavioral training.
I have an arduino-controlled box for that.
The sounds are play using Mp3 player controlled b the arduino.
However, the mp3 player is not good enough for my needs.
I need two clear sounds of 10 msec duration and freqiencies of 5000Hrz and 1000Hrz.
(I prefer pure sine waves but can compromise on triangle or, for now, even square).
The problem is that the mp3 is not fast enough and the volume is too low for 10 msec durations. When I tried to build gain circuit it became too noisy.
I tried to use the Tone function but it is again not good for 10 msec sounds. espacially in the jigj frequency/
I created the wavefiles in Matlab.
The PC plays the file in the right volume with no nose.
However, I don't know how to make the arduino play the files from the computer.
Is there a relative simple way to do it, without bying extra hardware?
If now, is there ANY way of doing it?
or another option, Is there a way for the arduino to play files from a wave generator? (I have these in my lab)
Thanks!

what was wrong with tone()? for me it makes nice high beeps

When I play 10000Hrz sound with 10msec duration I hear only click. I dont hear the sound. It is important since in the experiment I am conducting, The mice must hear and discriminate between the 5000Hrz, to 10000Hrz frequencies. The Mp3 was fine for 200 msec duration bur not for 10 msec. The computer is doing a very good job but I need the Arduino to control it..

Two options:

Write software for the PC to react to serial commands sent by the Arduino, or
Use a more powerful Arduino-like board with a DAC and do wavetable synthesis.

The Arduino Due and many of the other smaller ARM-based boards (like M0 boards) are a good candidate for option 2 because they are faster than a traditional Arduino and have a built-in DAC.  However, a proper I2S CODEC chip attached to a powerful MCU would be the preferred method for high-quality playback.
Note that your amplification system is of critical importance. It's common for many cheap amplifiers to limit higher frequencies. You need an amplifier with a good flat response over and above the maximum frequency you want to reproduce. Just slapping together any old "gain" circuit is probably not going to be good enough. Most op-amp based solutions have a ratio (Gain Bandwidth Product) that reduces the bandwidth as the gain increases.

Yes, I might order a more powerful module.. Thanks!

This code will create a steady 20 KHz output. Adjust the duration to reflect the period of your frequencies.
byte triggerOut = 19;

unsigned long currentMicros;
unsigned long nextMicros;
unsigned long duration = 25UL; // flip every 50uS = 20KHz pulse
unsigned long elapsedMicros;

void setup() {
  pinMode (triggerOut, OUTPUT);
}
void loop() {
  while (1) {
    currentMicros = micros();
    elapsedMicros = currentMicros - nextMicros;
    if (elapsedMicros >= duration) {
      nextMicros = nextMicros + duration;
      PINC = PINC | 0b00111111; // toggle D19 output by writing it input port.
    }
  }
}

Add some lines to start the output after a button push, and count the number of cycles to only output the time duration you want.
10,000 KHz = 0.1mS period, 10ms/0.1ms = 100 cycles.
Divide the 0 to 5V output down to 1V, and drive a computer self powered speaker to create the noise you want.

I will try that. Thanks!


text:
Analog pins giving off the same value
So recently I made code that used two custom sensors that are connected to the analog pin A0 & A5. Schematic can be seen here (http://inmoov.fr/test-your-finger-sensor/).
const int ono = A0;
const int twe = A5;

int one;
int two;

void setup() {
  Serial.begin(9600);

  }

void loop() {
  one = analogRead(ono);
  two = analogRead(twe);

  Serial.print(one);
  Serial.print(" ");
  Serial.println(two);

}

So after I follow the schematic i did the code, but the data value from the Serial Plotter of both sensors are always equal even though I was only pressing down on one sensor. So is this a code problem or the circuit? if so is there any fix for it? Thx.

Try using pinMode(one, INPUT); and pinMode(two, INPUT); in setup()

Ok ill try that, ill get back to you in a bit

Could you show us some of those values?

It sounds like a circuit problem. Care to share your circuit, not a link to some circuit you think you made?

Ok i edited my post

@PurnawanBrillian This connection is wrong. You havecto connect it like resistor voltage divider.

how many Ohms do you recommend? I did try 1K and 10K it still doesnt work, look at image 3

@PurnawanBrillian It's good to use +- similar resistivity as sensor has.

@Matej yup I did try that did a 220 Ohm resistor on both the - and +, still didnt work

I also did try changing my arduino and my breadboard and the problem still occurs, so it should not be any hardware problems

When the sensor isn't a FSR, what is it?