text:
Arduino crashing during serial print for no obvious reason
I've written some Arduino Code which kept crashing and i couldn't find out why. Then i reduced the code as much as i could in order to see the problem.
The reduced code currently doesn't do anything extraordinary except printing some strings over the serial line.
This is the reduced code:
void setup()
{
  Serial.begin(9600);
  Serial.print("Begin\r\n");
  send_wifi_beacon();
}
void loop()
{
  delay(1000);
}
void send_wifi_beacon()
{
  send_wlan_chip_command("AT+CIFSR");
  Serial.print("notreached"); // this part is never reached
  send_data_over_network(); // can't remove this line otherwise the crash won't happen which is weird since this is never called
}
void read_response_from_serial()
{
  delay(2000);
  Serial.print("==-1\r\n"); // crashes here
}
void send_wlan_chip_command(char* command)
{
  Serial.print("Sending command to wifi module: ");
  Serial.print(command);
  read_response_from_serial();
  Serial.print("Command response: ");
}
// this function is never called, since the crash happens before the call, but it can't be removed otherwise the crash won't happen
// also it can't  be altered then, the crash also will not happen.
void send_data_over_network()
{
  char number[3] = "12";
  //char number[3] = "";
  char length_of_payload[20] = "0123456789012345678"; // 20 digits if assuming 64 bit integer is the maximum this code will ever run on
//  char length_of_payload[20] = "";
  char *command;

  command = malloc(26);
  command = "AT+CIPSSEND";
  strcat(command, number);
  strcat(command, ",");
  strcat(command, length_of_payload);
  send_wlan_chip_command(command);
  free(command);
}

This is the according output:

Begin Sending command to wifi module: AT+CIFSR==Begin
  Sending command to wifi module: AT+CIFSR==Begin
  Sending command to wifi module: AT+CIFSR==Begin
  Sending command to wifi module: AT+CIFSR==Begin

Which means that the arduino keeps crashing and resetting. This goes on forever.
The weird thing is, if I change the following two lines to: (in the"send_data_over_network" function as in example above)
char number[3] = "1"; // changed from => char number[3] = "";
char length_of_payload[20] = "123"; // changed from => char length_of_payload[20] = "0123456789012345678";

The output now changes to :

I call this behaviour weird since it shouldn't have any influence on the result because this function(send_data_over_network) is never called in the crash example from before.
Troubleshooting options i already tried:

Reinstalling Arduino IDE , i tried with mutliple versions 1.8 , 1.6, 1.4. 1.0
Different Arduino Boards (Arduino Uno and Arduino Mega)
Different Laptops (since i thought maybe it's related to power issues of my laptop)

Maybe it's something obvious and i just can't see it, but i already spent +16h debugging, so help would be really appreciated.

This code looks wrong:
  command = malloc(26);
  command = "AT+CIPSSEND";
  strcat(command, number);
  strcat(command, ",");
  strcat(command, length_of_payload);
  send_wlan_chip_command(command);

First you allocate 26 bytes, then a new string is created, which you strcat to it. This happens in memory that is not allocated (or overwrites other data).
Instead of
  command = "AT+CIPSSEND";

use
  strcpy(command, "AT+CIPSSEND");

Also check that 26 bytes is enough, change it to 128 bytes to be sure (check the correct amount you need later).

If you choose to use malloc() and strings, be sure to initialize the memory to zeros, or strcat will not function as expected.

Not "suspicious". It's "wrong". One can't append to a string constant....Also, you want strcpy, not strcat in your correction.

Ah i wasn't aware that i can't append to a string contant. But it makes sense since it's in a different memory area.
One thing i still don't understand is how this resulted in a crash exactly, since the function was actually never reached. Or was it ? Therefore i would assume that it would crash afterwards, not before the function call.
Can anyone explain this ?
Could this be due to some compiler optimization ?
I accepted your answer as the solution but the upvote doesn't count yet.
Thanks to both of you.

@JohnnyMopp Thanks for the good remarks, I improved the answer.

@KoKIA are you sure the function was not called? The easiest way is to add a print statement before and after the wrong code ... and preferably add a bit after each print command to be sure the information got flushed (not sure if the delay is absolutely necessary). But print statements help a lot (if debugging is not possible like in Arduino).

@KoKlA Also, even if your code worked, you would end up with a memory leak as you immediately re-assign the value returned from malloc. That memory is lost. Also because of the reassignment, you would error on the free().

@MichelKeijzers awesome. you are right, i simply added a delay(x)  between my serial outputs and now i could see that it's actually crashing in the function and the function is in fact called. This means that the Arduino was crashing faster then the serial could print it's characters. Now everything makes sense, i would have never thought of this. Thank you very much

Consider using alloca() instead of malloc(). It allocates on the stack instead of the heap and is automatically freed when the function exits and the stack frame is discarded.

@KoKIA You are welcome ... it takes mostly time to add print statements, but it can make the difference between guessing and knowing.

@Majenko thank you for the alloca() tip, I will definitely use it.

@Majenko and @KoKlA: alloca() is most useful when you do not know beforehand the required size. If that size is a compile-time constant, it's simpler to just declare char command[26].

You are almost certainly running out of memory and have a stack collision with the heap. Dynamic memory allocation and de-allocation is not a good idea when you have less than 2K RAM to work with. If you use malloc() use it only to allocate buffer space and then reuse the buffers. Put your test code entirely in setup and see what happens. Also check the amount of RAM allocated at compile time it may be more than you think.
char *buf1;
char *buf2;

void setup() {
   buf1 = (char *) malloc(10);
   buf2 = (char *) malloc(10);
   .
   .
   // test code here
}


text:
RFID does not respond after Ethernet.begin(mac, ip) initialization
Good day, I have this problem with my simple project. I have a database with all RFID number of employee. What I want to do is to use an rfID to check if it is registered in the database. If it is, it would return a value of 1 else would be a value of 0.
I tried with arduino HanRun Ethernet shield. I was able to get a response from the php web server to the serial monitor. Tried the seeedrfid it successfully get the rfcard number. However, when i tried to combine the two, it would hang on Ethernet.begin(mac, ip) initialization. My code is below.
#include <Ethernet.h>
#include <SoftwareSerial.h>
#include <SeeedRFID.h>

#define RFID_RX_PIN 10
#define RFID_TX_PIN 11

SeeedRFID RFID(RFID_RX_PIN, RFID_TX_PIN);

char state = '0';
char c;
byte mac[] = {0x60, 0xF8, 0x1D, 0xBA, 0x1D, 0x52};
IPAddress ip(192, 168, 20, 228);

EthernetClient client;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Serial set up");

  Ethernet.begin(mac, ip);
  Serial.print("My IP Address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {

  long rfID;
  // put your main code here, to run repeatedly:

  if (RFID.isAvailable()) {
    rfID = RFID.cardNumber();
    Serial.println(rfID);
  }
}

Serial.println(rfID) is not executed unless I remove the Ethernet.begin(mac, ip). Can anybody point me to the right direction?

It's NOT a HanRun Ethernet Shield! It's an unbranded Ethernet Shield happens to use a HanRun HR911105A RJ45 Socket with Integrated Magnetics on it. http://www.kosmodrom.com.ua/pdf/HR911105A.pdf

What pins did you connect the RFIC board to?

The Arduino Ethernet shield uses pins 4, 10,11,12,13. You have a conflict with the RFID pins.

SPI pins can overlap, SS should be independent. There's not too much info about the chipset used though.

can they overlap with software serial RX/TX?

SPI can't overlap with softserial.

source: Stack Exchange

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

sort: votes


text:
usb host shield + wireless mouse (Read 5 times)
hello guys i have a problem ,
i have a usb host shield v2.0 from circuits @home  attached to an arduino mega and to a usb wireless reciever mouse ,
this is the serial monitor  output :
x=0 dy=3
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=1
dx=0 dy=-2
dx=0 dy=-2
dx=0 dy=2
dx=0 dy=9
dx=0 dy=6
dx=0 dy=-1
dx=0 dy=2
dx=0 dy=-1
dx=0 dy=-1
dx=1 dy=0
dx=2 dy=0
dx=1 dy=0
dx=2 dy=0

and this is the code from the library usbhidbootmouse :
#include <hidboot.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class MouseRptParser : public MouseReportParser
{
protected:
    void OnMouseMove    (MOUSEINFO *mi);
    void OnLeftButtonUp (MOUSEINFO *mi);
    void OnLeftButtonDown   (MOUSEINFO *mi);
    void OnRightButtonUp    (MOUSEINFO *mi);
    void OnRightButtonDown  (MOUSEINFO *mi);
    void OnMiddleButtonUp   (MOUSEINFO *mi);
    void OnMiddleButtonDown (MOUSEINFO *mi);
};
void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
{
    Serial.print("dx=");
    Serial.print(mi->dX, DEC);
    Serial.print(" dy=");
    Serial.println(mi->dY, DEC);
};
void MouseRptParser::OnLeftButtonUp (MOUSEINFO *mi)
{
    Serial.println("L Butt Up");
};
void MouseRptParser::OnLeftButtonDown   (MOUSEINFO *mi)
{
    Serial.println("L Butt Dn");
};
void MouseRptParser::OnRightButtonUp    (MOUSEINFO *mi)
{
    Serial.println("R Butt Up");
};
void MouseRptParser::OnRightButtonDown  (MOUSEINFO *mi)
{
    Serial.println("R Butt Dn");
};
void MouseRptParser::OnMiddleButtonUp   (MOUSEINFO *mi)
{
    Serial.println("M Butt Up");
};
void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi)
{
    Serial.println("M Butt Dn");
};

USB     Usb;
USBHub     Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

MouseRptParser                               Prs;

void setup()
{
    Serial.begin( 115200 );
#if !defined(__MIPSEL__)
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
    Serial.println("Start");

    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");

    delay( 200 );

    HidMouse.SetReportParser(0, &Prs);
}

void loop()
{
  Usb.Task();
}

i wanna know the dx is equal to 1 when i press the left button on mouse and is equal to 2 when i press the right button on mouse and the dy is responsible for the x and y coordinates from - to + ? how a single value is responsible for x and y both ?

what is preventing you from reading the value of dx when you press the left mouse button? ... your question is somewhat unclear ... what single value are you talking about?

the dy value is responsible for both x and y co-ordinates together ... it should be responsible for only 1 movement so now how to extract the 2 coordinates? ithink there is a correction with the library i dunno

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


text:
NodeMCU LUA ESP8266 12E Issues with Programming
I recently bought the NodeMCU ESP8266 to work on an embedded project, and for whatever reason, the board will only allow me to upload Arduino sketches when I unplug and replug in the board via the Micro-USB cable. I don't have any jumper wires connected to pins in the board--just the Micro-USB cable. The IDE gives me the following:
esptool v0.4.13-1-gf80ae31 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
    setting board to nodemcu
    setting baudrate from 115200 to 115200
    setting port from COM1 to COM3
    setting address from 0x00000000 to 0x00000000
    espcomm_upload_file
    espcomm_upload_mem
    setting serial port timeouts to 1000 ms
opening bootloader
resetting board
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
resetting board
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
resetting board
trying to connect
    flush start
    setting serial port timeouts to 1 ms
An error occurred while uploading the sketch
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed

Like I said, it programs fine when I unplug and replug in the board, but it is quite a nuisance to do this every time. I'd like the board to automatically start running my code after uploading. Here's what I've tried/found:
-I've made sure the baud rates are matching in the device manager and the upload speed tab in the IDE.
-The device is in fact being picked up in the device manager with the correct driver: USB-SERIAL CH340.
-I've tried pressing the flash button before programming.
-I've tried connecting the ground pin on the NodeMCU to GPIO pin 0.
-Tried reinstalling drivers.
-Tried switching boards.
This may also explain why my serial monitor is so inconsistent as well; sometimes it outputs nothing and sometimes it outputs garbage, but that's a separate issue that I won't worry about for now. Can someone please help me out here? I've referenced a lot of other posts on here as well as tutorials but none have helped me thus far.
Thanks

what board or reset method do you select in Tools menu?

I selected the NodeMCU 1.0 (ESP-12E Module) for the board. There is no reset method option unless I select "generic ESP8266 module".

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


text:
Serial Output on ESP8266 doesn't work on 2/3 of my boards
I have 3 NodeMCU 1.0 12E ESP8266 boards.
Issues
Two of them require me to unplug and replug in the boards every time I want to flash code, and nothing appears on the serial output with this simple blink modified sketch I've shown below on those same boards. I don't have any special pin configurations on either of these boards, I simply have the NodeMCU boards connected to the PC through MicroUSB. The other board has no issues with uploading and displaying serial output also with no special pin configurations.
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);
  pinMode(4, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  Serial.println("ON");
  digitalWrite(4, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  Serial.println("OFF");
  digitalWrite(4, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Interestingly enough, the LED connected to the corresponding PIN behaves correctly, which would indicate flashing the code works fine, but serial output doesn't work on 2 of the boards.
What I've tried

Making sure the baud rate of the serial monitor is 115200.

Tried the sketch with different baud rates.

Made sure the correct board and ports are being recognized.

I have tried using certain pin configurations on some of my boards, (grounding GPIO pin 0, connecting Rx and Tx, etc), but like I said, I don't do this in general when uploading code. Maybe the ESP8266 requires some sort of initialization process that I haven't done?

I can't tell if my other two boards are defective or if I need to take extra steps for the two boards that are acting strange. Has anyone here experienced something like this?
Thanks

If you can upload code you should also be able to communicate via serial, it's the same interface. Do you see anything on the serial line? In general there is nothing more to do than calling Serial.begin() for initialization.

@SimSon I see a bunch of reverse question marks sometimes, and sometimes, I see absolutely nothing in the nonworking boards. As far as I can tell, in both the serial monitor and the Tools settings, the settings are exactly the same for both the working and nonworking boards. The LEDs still blink in the non-working boards.

@SimSon Also in the working board, the serial output of a simple program that prints "Message Sent" always prints garbage like "⸮Message ⸮⸮!H⸮", "MessagLR⸮⸮4:, etc". Its usually not perfect and has some soft of problems. Are my boards just simply not working?


text:
Battery life with Nano v3
Easy secret knock detector to trigger anything with only an Arduino and a few cheap components

First of all I need to state that I'm new to Arduino and electronics in general. My question is about a project where the Nano is being powered up with a 12v rechargeable li-ion 2800 mAh battery on pins VIN and GND.
I'm using the 5v Nano pin to power a SRD-05VDC-SL-C relay along with the ground pin from the Nano. The IN pin on the relay is from the D11 pin on the Nano. So far so good. I'm also using the same 12v battery to power up a solenoid latch, which energizes for just a few seconds.
When I tested this setup (less the relay AND solenoid) for battery life, my volt meter read 9.8v and 1 hour later 2.8v. causing the Nano to go off.
How can I increase battery life?
This is the link to the code I used:

I'm not having an issue with the code or the operation of the setup but the battery life is unacceptable.

please draw a schematic. there is a button for that when you edit your post. ... also, the arduino does not do anything by itself, i am sure there is a program involved. please post that.

I don't quite follow your schematic. What are T1 and T2?

Hi, you just added a link to a YouTube video without any introduction. Could you explain the purpose of the video?

Fritz, you edited my answer to (attempt to) add a link to a YouTube video about a "Easy Secret Knock Detector" and have now edited your question to add the same link. What is your purpose in doing this?

OK, it looks like the YouTube video is what this project is based on. You could edit your question to make all this clearer.

I'm a bit surprised you have the latch connected to what I assume is the NC output of the relay. That means the latch is energised most of the time. Is that right?

Nick T1,T2 are screw terminals on a circuit board to attach the latch and relay switch.

Draining a 12V  batterypack down to 2.8V is very bad for the longevity of li-ion batteries. Please add some kind of battery (undervoltage) protection to your project.

Something is wrong with your setup. I don't have a Nano to hand to test, but it would consume similar current to a Uno (probably less) which is around 50 mA. Thus, using a 2800 mAh battery you should have a life of 2800/50 = 56 hours.
Li-ion batteries come in multiples of cells, where individual cells have a nominal voltage of 3.6V (thus you probably have three cells giving 10.8V). Deeply discharged they will have a voltage of 3.0V per cell (a total of 9V for your three cells). If you started at 9.8V as you stated, then the cells would have been 90% discharged already which probably accounts for the short running time.
Assuming you haven't wired it in a strange way (and it would help to show the wiring and possibly a photo) I suggest you try with a fully-charged battery.

Another helpful thing to do would be to measure the current consumption of the battery using a multimeter. Make sure you read up on how to measure current with a meter or you may damage something (example here).
The basic idea is shown in this photo:

The meter is placed in series with the battery and the Arduino. The negative side of the battery goes to the Arduino in the usual way. The positive side of the battery goes into the "milliamps" input of the meter (which is set to 200 mA range in my case) and then the common (black) lead from the voltmeter goes to the positive (Vin) side of the Arduino.
You can see that in this particular case, with a 9V battery, the Arduino is consuming 57.7 mA.  I don't quite believe that reading as re-measuring with a more expensive meter gave a reading of 51.1 mA. Still, that gives you a ball-park figure. And it shows that spending a bit more on a better meter gives you more accurate results. :)

I have a page about power saving and you can also refer to the Wikipedia page about Li-ion batteries.

my volt meter read 9.8v and 1 hour later 2.8v. causing the Nano to go off.

For a 12V Li-ion battery get down to 2.8V there is something seriously wrong with its protection circuitry. It should cut the battery out at 3V per cell, that is at 9V if you have 3 cells in series.

Nick, I decided the battery needs to be changed out. Waiting for the replacement.

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


text:
How to use a coma as the decimal separator?
I have a LCD that displays a float variable. I would like to show a comma instead of a dot as the decimal separator.
float temp = 23.50;
lcd.setCursor(0, 0);
lcd.print(temp);

I want to show 23,50 instead of 23.50.
Is there any function to convert or format it?

Print the integer part, print a comma, then print the value minus the integer part.
float value = 123.45;
int ival = (int)value;
int frac = (value - ival) * 100;

Serial.print(ival);
Serial.print(",");
if (frac < 10) Serial.print("0");
Serial.println(frac);

May be overkill for this simple usage but, if you are printing numbers
in more than one place in your program, it may be convenient to
implement a filter that replaces all dots with commas.
Here is one such filter:
// Replace dots with commas.
class CommaForDot : public Print
{
public:
    CommaForDot(Print &downstream) : downstream(downstream) {}
    virtual size_t write(uint8_t c) {
        return downstream.write(c=='.' ? ',' : c);  // replacement
    }
private:
    Print &downstream;
};

And here is a simple test:
void setup()
{
    Serial.begin(9600);
    float a = 12.34;

    Serial.print("Through Serial:      ");
    Serial.println(a);

    CommaForDot filteredSerial(Serial);
    Serial.print("Through CommaForDot: ");
    filteredSerial.println(a);
}

void loop(){}

The output is:
Through Serial:      12.34
Through CommaForDot: 12,34


text:
WEMOS: How to install it?
I have been using an Arduino Uno for a year now, and I bought a WEMOS D1 Mini and a NodeMCU. I want to select WEMOS or NodeMCU from the Arduino Web Editor but it doesn't appear on the list:

I think I need to install a driver but it's only for the Arduino desktop editor (not for the web editor).

I don't believe you can. Only Arduino can do that sort of thing, since it's their web server.

You have to go to the website and download the driver. Also make sure you add the ESP8266 stable to ur preferences

I just read that it can't. It's a shame:
https://forum.arduino.cc/index.php?topic=441328.0


text:
How to get ESP8266 firmware version?
I am going to update the firmware of an ESP8266 module, but first I would like to know the current version or name.
How can I get it? Maybe with an AT command?
This is my ESP8266 module:

ESP8266 and the AT firmware are products of Espressif. They have everything documented on the web site.
The AT command for version is AT+GMR.


text:
Avoiding false rising and falling edge when using demultiplexer
I have 8 sets of 8 push buttons. There is a Teensy and a demultiplexer. The demultiplexer has 8 outputs. When an output is selected it is pulled low. Each output is connected to a group of 8 push buttons. The 8 push buttons are then connected to 8 pullup inputs on the Teensy.
Each group of 8 push buttons is connected to a unique demultiplexer output, but all the push buttons are connected to the same 8 inputs on the Teensy. That is, push button #1 in group 1 shares a Teensy input with push button #1 in group 2. The push buttons are isolated from each other with diodes.
I'm using bounce.h for debouncing. It looks for rising and falling edges.
The problem is this:

Push button #1 in group #1 is pressed, pulling that input low, causing a falling edge to be detected. This is good.
The demultiplexer shifts to group #2, where the #1 button hasn't been pressed, and thus is high.
Because both #1 buttons in group #1 and #2 share the same input line, the Teensy sees this change as a rising edge. This is undesired.

What is the better approach to this?
Thanks,
Dan

Why is a rising edge undesired when the switch going low is what you are looking for? Who cares if it goes high?

When you press a button there is an initial rising edge, and if you keep that button pressed until the demux cycles all the way around, it will detect another rising edge, and will keep doing this. It also detects a falling edge right as soon as the demux shifts away from the still-pressed button. These extra rising and falling edges don't accurately portray the state of the buttons, and so I'm trying to filter them out, or go about detecting the button states differently.

When you press a button there is an initial rising edge - When an output is selected it is pulled low - these statements contradict each other. When you press a button these is a falling edge.

Yes I have those backwards.

To do multiplexing with bounce.h you will need one bounce object per button. That's 64 bounce objects for an 8x8 matrix.
Then you only want to update the bounce objects for the group you currently have active.
That is:

Switch to group 1.
Update objects 1-8
Switch to group 2
Update objects 9-16
... etc ...

You need one object per button so that the internal data can track the state of that specific button, and you only update the 8 objects for the currently selected group otherwise the objects that aren't associated with that group will get confused by incorrect data.

What is the better approach to this?

write your code so it debounces each pin / group of pins separately.
looks like your code used global / static variables.


text:
ESP32-CAM camera: SD help
I'm struggling with making a simple sketch to take a photo with an ESP32-CAM and save to an SD card.
I have found a bunch of examples that that do what I want, but basically they just take a photo and go to sleep, so every time you reset the unit it runs some code to take a photo, then goes into deep sleep.
The thing is the photos suck, they are green and have no exposure control. I think that it is a known issue that the first photo is always green and the auto gain has not figured out the exposure yet. So because every photo is the first photo after waking up, they all suck.
I tried to move the setup stuff into the loop, and remove the sleep part, but it just straight up doesn't work, and I don't understand enough about coding to even get ChatGPT to help.
I will put the working code below, and then the part I changed. Any help would be great. I thought it would be so simple, I just want to take a photo when I push a button.
/*
ESP32 CAM Camera with MicroSD storage
  esp32cam-microsd.ino
  Take picture when button pressed
  Store image on MicroSD card

  DroneBot Workshop 2022
  https://dronebotworkshop.com
*/
// Include Required Libraries

// Camera libraries
#include "esp_camera.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"

// MicroSD Libraries
#include "FS.h"
#include "SD_MMC.h"

// EEPROM Library
#include "EEPROM.h"

// Use 1 byte of EEPROM space
#define EEPROM_SIZE 1

// Counter for picture number
unsigned int pictureCount = 0;

// Pin definitions for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

void configESPCamera() {
  // Configure Camera parameters

  // Object to store the camera configuration parameters
  camera_config_t config;

  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; // Choices are YUV422, GRAYSCALE, RGB565, JPEG

  // Select lower framesize if the camera doesn't support PSRAM
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //10-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  // Camera quality adjustments
  sensor_t * s = esp_camera_sensor_get();

  // BRIGHTNESS (-2 to 2)
  s->set_brightness(s, 0);
  // CONTRAST (-2 to 2)
  s->set_contrast(s, 1);
  // SATURATION (-2 to 2)
  s->set_saturation(s, 0);
  // SPECIAL EFFECTS (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_special_effect(s, 2);
  // WHITE BALANCE (0 = Disable , 1 = Enable)
  s->set_whitebal(s, 1);
  // AWB GAIN (0 = Disable , 1 = Enable)
  s->set_awb_gain(s, 1);
  // WB MODES (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_wb_mode(s, 0);
  // EXPOSURE CONTROLS (0 = Disable , 1 = Enable)
  s->set_exposure_ctrl(s, 1);
  // AEC2 (0 = Disable , 1 = Enable)
  s->set_aec2(s, 0);
  // AE LEVELS (-2 to 2)
  s->set_ae_level(s, 0);
  // AEC VALUES (0 to 1200)
  s->set_aec_value(s, 300);
  // GAIN CONTROLS (0 = Disable , 1 = Enable)
  s->set_gain_ctrl(s, 1);
  // AGC GAIN (0 to 30)
  s->set_agc_gain(s, 0);
  // GAIN CEILING (0 to 6)
  s->set_gainceiling(s, (gainceiling_t)0);
  // BPC (0 = Disable , 1 = Enable)
  s->set_bpc(s, 0);
  // WPC (0 = Disable , 1 = Enable)
  s->set_wpc(s, 1);
  // RAW GMA (0 = Disable , 1 = Enable)
  s->set_raw_gma(s, 1);
  // LENC (0 = Disable , 1 = Enable)
  s->set_lenc(s, 1);
  // HORIZ MIRROR (0 = Disable , 1 = Enable)
  s->set_hmirror(s, 0);
  // VERT FLIP (0 = Disable , 1 = Enable)
  s->set_vflip(s, 0);
  // DCW (0 = Disable , 1 = Enable)
  s->set_dcw(s, 1);
  // COLOR BAR PATTERN (0 = Disable , 1 = Enable)
  s->set_colorbar(s, 0);
}

void initMicroSDCard() {
  // Start the MicroSD card
  Serial.println("Mounting MicroSD Card");
  if (!SD_MMC.begin()) {
    Serial.println("MicroSD Card Mount Failed");
    return;
  }
  uint8_t cardType = SD_MMC.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No MicroSD Card found");
    return;
  }
}

void takeNewPhoto(String path) {
  // Take Picture with Camera
  // Setup frame buffer
  camera_fb_t  * fb = esp_camera_fb_get();

  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  // Save picture to microSD card
  fs::FS &fs = SD_MMC;
  File file = fs.open(path.c_str(), FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file in write mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
  }
  // Close the file
  file.close();

  // Return the frame buffer back to the driver for reuse
  esp_camera_fb_return(fb);
}

void setup() {
  // Disable brownout detector
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  // Start Serial Monitor
  Serial.begin(115200);

  // Initialize the camera
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");

  // Initialize the MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  // Take and Save Photo
  takeNewPhoto(path);

  // Update EEPROM picture number counter
  EEPROM.write(0, pictureCount);
  EEPROM.commit();

  // Bind Wakeup to GPIO13 going LOW
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);

  Serial.println("Entering sleep mode");
  delay(1000);

  // Enter deep sleep mode
  esp_deep_sleep_start();
}

void loop() {
}

I changed the set up and loop:
void setup() {
  // Disable brownout detector
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  // Start Serial Monitor
  Serial.begin(115200);

  // Initialize the camera
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");

  // Initialize the MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;
}

void loop() {
  // Path where the new picture will be saved on the SD Card
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  // Check if GPIO13 is low
  if (digitalRead(GPIO_NUM_13) == LOW) {
    // Take and Save Photo
    takeNewPhoto(path);

    // Update EEPROM picture number counter
    EEPROM.write(0, pictureCount);
    EEPROM.commit();

  }
}

Read this web page, in the section take photo to SD card
fb = esp_camera_fb_get();
dealy(1000)////

This is key to avoid an issue with the image being very dark and green. If needed adjust total delay time.
fb = esp_camera_fb_get();

Hope this helps,
I would suggest take some image buffers first wake the camera up then write the data later to SD card.

thanks, this helped with the green some of the time, but is way too delayed to be piratical, and does not address the exposure problem.  I really need to keep the ESP on and just trigger the photo capture code with a button.


text:
7-segment displays are not working

/*
MODIFIED TRAFFIC LIGHT SYSTEM W/ A COUNTDOWN TIMER FUNCTION
BY JOHN SEONG

THIS IS A QUITE ACCURATE SIMULATION OF TORONTO'S TRAFFIC LIGHT SYSTEM
WHICH INCLUDES TWO 7-SEGMENT DISPLAYS THAT SHOW THE SECONDS LEFT
TILL THE PEDESTRIAN LIGHT SWITCHES BACK TO RED.

ENJOY!
*/

const int redLED = 4;
const int yellowLED = 5;
const int greenLED = 6;
const int pedestrianRedLED = 13;
const int pedestrianGreenLED = A5;
const int buzzer = 12;
const int button = 7;

int segmentPins[] = {11, 10, 9, 8};

int buttonHitCount = 0;

void setup() {

  Serial.begin(9600);

  // Car Traffic LEDs
  pinMode(redLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);

  // Pedestrian Traffic LEDs
  pinMode(pedestrianRedLED, OUTPUT);
  pinMode(pedestrianGreenLED, OUTPUT);

  // 7-Segment Display Pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);

  // Piezo Speaker Pin
  pinMode(buzzer, OUTPUT);

  // Pedestrian Push Button
  pinMode(button, INPUT_PULLUP);

  displayNumber(9, 2);
  displayNumber(9, 3);
}

void loop() {

  // Read the state of the button
  int buttonState = digitalRead(button);

  Serial.println(buttonState);

  if (buttonState == LOW) {
    buttonHitCount = 1;
  }

  if (buttonHitCount == 1) {
    switchToRed();

  } else if (buttonHitCount == 0) {
    defaultState();
  }
}

void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(displayPin, LOW);
}

void switchToRed() {

  delay(5000);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // RED
  digitalWrite(redLED, HIGH);
  digitalWrite(greenLED, LOW);
  digitalWrite(yellowLED, LOW);

  // GREEN
  digitalWrite(pedestrianGreenLED, HIGH);
  digitalWrite(pedestrianRedLED, LOW);

  switchToGreen();
}

void switchToGreen() {

  // 15
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 14
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 13
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 12
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 11
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 10
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(0, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 9
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(9, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 8
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(8, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 7
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(7, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 6
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(6, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 5
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 4
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 3
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 2
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 1
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  noTone(buzzer);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // GREEN
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, HIGH);
  digitalWrite(yellowLED, LOW);

  // PEDESTRIAN - RED
  digitalWrite(pedestrianGreenLED, LOW);
  digitalWrite(pedestrianRedLED, HIGH);

  // Reset the value
  buttonHitCount = 0;
}

void defaultState() {

    // GREEN
    digitalWrite(greenLED, HIGH);
    digitalWrite(yellowLED, LOW);
    digitalWrite(redLED, LOW);

    // PEDESTRIAN - RED
    digitalWrite(pedestrianRedLED, HIGH);
    digitalWrite(pedestrianGreenLED, LOW);
}

Clearly something is wrong with my code and the 7-segment displays are off the whole time the program is running. I also posted a link below which directs to the tinkercad project I made.
https://www.tinkercad.com/things/7pnnbXoaqrG-improved-stop-light-john-seong/editel?sharecode=jR86i_srV7QgP11u1CxOFzeVwehzjIRr8wCC7vbbLaY

Please try to color code the wires more. With nearly all wires being green and overlapping at many places it is really difficult to follow the wiring diagram. Also you have some more components besides the 7-segment displays, that aren't really relevant here. It is a common debug method to remove all code and components, that aren't relevant to a specific problem, then getting the relevant problem solved and then add the rest of the code and components one by one, always checking for errors inbetween. You could try building the circuit for only the displays and check again

I debugged; which turns out, all the connections are right however when I press the button the segment displays turn off.

You are never touching the segment display anywhere in your loop() function. So if does something (like going off) but none of the LEDs act as intended (i.e. switching from green to red), then something in your wiring must be wrong or the pin numbers in the code don't match.

It's supposed to multiplex^

You could make it easier for anyone trying to help you by structuring the wires in a more logical manner (for example don't let wires of the same color overlap) and maybe enlarging the schematic (so that pin numbers are readable for example). It's very hard to understand at the moment.

displayNumber only show the number for 10µs. So you need to call this function a lot more times per second for you eyes to notice. You could also use a timer to periodically change between segments, but fast enough that it appears all two displays are lit at the same time.

Why not convert it to a schematic as you have wired it, we would understand that a lot easier. It is also much easier to follow your logic in that format. You can download several schematic capture programs for free. I use KiCad. Schematics are part of the basic language in electronics.

How about an annotated schematic, the language of electronics.

Not really a solution, but changing the code for the displayNumber function as shown below, will make it more apparent where the real problem is.
void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  // turn off both displays
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  /* // remove these two lines
  delayMicroseconds(10);
  digitalWrite(displayPin, LOW);
  */
}


text:
Best way to get JSON from struct vector class
I have a vector which consist of a struct, see below:
struct FileInformation
  {
    String name;
    size_t filesize;
  };

std::vector<FileInformation> FileInformations;

How do I get JSON out of it the easiest way?

for cycle and print?

Using ArduinoJson:
DynamicJsonDocument doc(2048);
for (const FileInformation& item : FileInformations) {
  JsonObject& obj = doc.createNestedObject();
  obj["name"] = item.name;
  obj["filesize"] = item.filesize;
}
serializeJson(doc, Serial);

This will produce a JSON document that looks like this:
[
  {"name": "command.com", "filesize": 1234},
  {"name": "config.sys", "filesize": 2345},
  {"name": "autoexec.bat", "filesize": 3456}
]

Please read the tutorial for more information.


text:
I have some problem with 433 MHz transmitter
I want to transfer float data between two Arduinos. This is what I sent:
0.00
0.00
0.00
0.00
-9.06
-9.80
16.85
16.24
0.00
-16.93
8.13
0.00
0.00

And this is what I received:
 0.001****8u
  0.001****8u
  0.001****8u
  0.001****8u
 -9.061****8u
 -9.801****8u
 16.851****8u
 16.241****8u
  0.001****8u
-16.931****8u
  8.131****8u
  0.001****8u
  0.001****8u

The code I have uploded in sender and receiver:
Sender:
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

RH_ASK driver;

void setup() {
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  Serial.begin(9600);    // Debugging only
  if (!driver.init())
    Serial.println("init failed");

  mpu.calibrateGyro();
  mpu.setThreshold(3);
}

void loop() {
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();
  char msg = "";
  dtostrf(normGyro.XAxis, 6, 2,msg);
  driver.send((uint8_t *)msg, strlen(msg));
  driver.waitPacketSent();
  Serial.println(normGyro.XAxis);
}

Receiver:
#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

void setup() {
  Serial.begin(9600);  // Debugging only
  if (!driver.init())
    Serial.println("init failed");
}

void loop() {
  uint8_t buf[12];
  uint8_t buflen = sizeof(buf);
  if (driver.recv(buf, &buflen)) { // Non-blocking
    int i;
    // Message with a good checksum received, dump it.
    Serial.println((char*)buf);
  }
}

Can anyone tell me what is wrong?

Please print the msg string in your sender code and then include that output in your question too. That way we can see what exactly you send over radio.

i had actually done this , the first msg was the printed one from the first arduino

Actually no, you printed normGyro.XAxis and not msg. You don't send normGyro.XAxis. You send a string representation of it, which is saved in msg. Thus please print msg in the sender code. That way we can see if the difference lies in the creation of the string representation or in the transmission.

look at this https://www.mediafire.com/view/mrb6c9ua3qfdwzb/%25D8%25AA%25D8%25B5%25D9%2588%25DB%258C%25D8%25B1_%25D8%25B5%25D9%2581%25D8%25AD%25D9%2587_2022-02-18_162300.png/file

Oh, I've overlooked an error in your receiver code char msg = "" needs to be char msg[10] = "". The first version is a single character, which you try to assign a string. The second version can actually hold a string (up to 9 characters + the terminating null character). Please try again with that change. And please don't post links to images of text. Instead you can edit your question and copy and paste the text directly in there, formatting it as code, just as you did before.

No links please. Edit your question

it fix the output of sender but the output of reciever is still the same as before

any one knows ?NO ONE ?


text:
RGB LED using potentiometer and push button
I'm currently working on an assignment which has to turn on an RGB LED using a potentiometer and button.
The problem I currently have is that the button is supposed to change the color I want the LED to display (press one time: red (pin9), press again: green (pin10), press again: blue (pin11)).
As I'm changing through the ports with the potentiometer, the potentiometer will read it with as analogWrite. For example, when I move the potentiometer all the way to the left and press the button the LED will display red, and when I move it back all the way to 0 and press the button twice the LED will stay red (do nothing). If I press it one more time it will turn off.
Another example, I turn on red again, then use green and turn off blue using the potentiometer and button giving me orange. How do I make it so to accomplish all of this while using both and combining colors?
This is a HW question. I am not asking for a whole solution but rather where to start because I already got stuck and I want to restart.

So - if I'm understanding that right - you want your button to be the set button, which is used 3 times sequentially to mix the colors red, green and blue with the value, that the poti has at the respective stages. So building the RGB color in 3 stages out of its components. Is that, what you want? And what exactly is your problem here? Reading the poti? Outputting 3 PWM signals for the RGB LED? calculating the values? Managing the program flow?

Oh, sorry for not making it clear. I'm kind of new to this (as shown). I believe my main problem is reading the reading the button and poti as to mix the colors as aforementioned.

Edit: The current problem I'm experiencing is the next: I'm running the simulation with if and counter for the button and my first color should be green. The next part in my code is to turn on blue but that's on two presses. On the first press it seems to skip green and go straight to blue.

So that means, that it actually is more of a software question. You need to show us your code (you can edit your question to include it there), so that we can help you with that

one thing that you need to realize is that the button and the potentiometer do not control the LEDs ... they are completely separate from the leds ... the Arduino program controls the LEDs ... the Arduino program reads the button state and reads the voltage level on the potentiometer slider .... keep the button reading and the potentiometer reading functions separate from the LED lighting function ... the button should only set a flag ... the same flag could also be set by a timer, or by a remote control ... the LED lighting function checks only the status of the flag, nothing else

The most common problem beginners have with buttons is coding it to be "If HIGH do this" and then wonder why it keeps happening rather than just happening once when the button is pressed. You have to learn to watch for a change in the state of the button - as in "If changed from LOW to HIGH do this".

If you solved your own question, please post the answer or how you fixed it.  That way someone who finds your question will know how you fixed it this question will show as
"Answered"

If the answer below worked for you then please tick it.

You method sound a bit more complicated that it needs to. What I would do is have the button switch between three colors, and have the potentiometer change the brightness of the currently selected color.
For example, when first starting up, the red led is selected. Turning the potentiometer changes the brightness of the red led (in real time). Let's say you turn it 50%, so the red led is at 50% brightness. When you're happy with that, you press the button, and now green is selected. (Since the potentiometer is still at 50% from the red, the green led will immediately turn on at 50% brightness.) You can then turn the pot to change the brightness of the green led. Let's say you turn it all the way of to 0%. Then press the button to select the blue led. Turn it to 100% and the combined color would be a dark purple. Press the button again to select red again.
Here is some proof of concept code:

byte selectedColor = 0; // 0:red, 1:green, 2:blue
byte oldButtonState = HIGH;

void loop() {
  byte buttonState = digitalRead(buttonPin); // read the button
  if( buttonState==LOW && oldButtonState==HIGH ) // see if the button is pressed, but wasn't pressed the last time
  {
    selectedColor++; // to to next color
    if( selectedColor==3 )
      selectedColor = 0;// after blue, go back to red
  }
  oldButtonState = buttonState; // remember the buttons state for the next loop

  int brightness = map(analogRead(potPin), 0, 1023, 0, 255);

  if( selectedColor==0 )
    analogWrite(redPin, brightness);
  else if( selectedColor==0 )
    analogWrite(greenPin, brightness);
  else
    analogWrite(bluePin, brightness);
}

PS I left out the pinMode stuff in the setup.
PPS make sure the led leads are connected to PWM pin on the Arduino (they have a ~ next to them on the PCB).


text:
How to restart ESP32 on any exception?
While developing a lot of projects (In Arduino IDE) for ESP32 one common issue I am facing is termination of program execution on unhandled exceptions. There are various exception I get.  For example: stack canary watchpoint triggered (looptask), invoke_abort, etc. I have no idea how to handle them, hence I prefer to restart the ESP manually.
Is there any way where I can restart the ESP32 automatically on all unhandled or unfortunate exceptions other than handling the exceptions ?

I know little of the ESP32's internals, but would using the watchdog timer work for this? Or  maybe changing the panic routine so that it resets the MCU?

@ocrdu hi . can u guide me with sample code for changing the panic routine so that it resets the MCU.

No, sorry, I have never done that on an ESP32. Sounds googlable, though. Watchdog not an option?

i have disabled watchdog as it is giving issues in my code flow.

it should reboot  whenever something blows up, I never see one just crashed out, so you must have changed something. don't disable the watchdog, fix the issues instead.

I have problems with the ESP8266 running for days then it would stop communicating with the I2C bus. My solution was to monitor a pin toggling on one of the port expanders and if it failed it would power down the whole system then restart it by killing power then turning it back on. Since my variables did not change very often I keep them in NVM. I hope this helps.

@Gil i had i2c issues too, but calling Wire.begin() again fixed it w/o a reboot.

Well, why not correct your application to never throw exceptions? That would be the only serious way to solve the issue. (Exceptions prove the rule, for example a remote application with high reliability requirements, but low quality. However, any restart should lead to an enhanced version.)

I don't know if I understand your question well, but if what you want to do is reset MCU programmatically, watchdog is good solution.
The orther way is connect IO port and reset port by using wire, and send a signal(send LOW or HIGH voltage to reset port) to reset port.
Or use asm code.

Hi.
watchdog is not only getting triggered.


text:
Using Leonardo as keyboard: add wake and sleep functions
I want to use a Leonardo with USB chip to emit some commands via USB port to a digital piano computer (running Windows 7) for various functions. I've gotten the Leonardo to emit page up and page down functions using a simple project I found on the web. What I need now is the following set of functions: left arrow, right arrow, F11, wake, and sleep. What I need help with is:

where is the complete list of functions available with keyboard.press?
are wake and sleep among those available?
if they aren't, what header file could be modified to include them?

Thank you for any suggestions.

google keyboard scan codes

Thank you, I have the needed scan codes. What I need is information about where to put them in the IDE.

you said that you are able to generate PgUp and PgDn keypresses .... you do other keypresses the same way

The functions for keyboard.press (RIGHT-ARROW) and left arrow work as expected. F11, WAKE and SLEEP  are not available or are not named that way, hence my questions about the list of available functions, or what the header file is named so that I can add to it.

names like RIGHT-ARROW and F11 are just numbers ... i would suspect that they are scan codes ... i would just use a scancode for PgDn to see if my hunch is correct

try some of these codes ... http://ts.thrustmaster.com/download/accessories/pc/hotas/software/TARGET/TARGET_SCRIPT_EDITOR_basics_v1.2_Appendix.pdf

@jsotola You were right about putting numbers directly in the keypress function. I found the name for F11, namely, KEY_F11. It also works with 0xCC as argument. However, the USB HID code for F11 is 44, and that doesn't work to toggle fullscreen with the Leonardo, so there is something else going on. The HID code for sleep is 82, but that is also used for caps lock. So, there's something else going on here. The doc you linked doesn't mention wake or sleep.

It turns out there is a library that can be added to compile the media and system functions for USB keyboard connection into the Leonardo, as well as other Arduino modules. It is available through 'tools','library manager'; it is HID-project by NicoHood. There is an example program called "system example" at github to test it for for wake and sleep. It works perfectly.
I expect it'll work for the other functions too.


text:
Using AccelStepper to move a set distance while a button is held down
I'm working on a project and using a nema 23 stepper motor and driver.

Need to be able to move the stepper 1/32 rotation when I press a button.

I need a small delay so I have time to release the button and not move the 1/32 rotation twice or more (its in a loop) before I can release the button.

I also want to the stepper to continue to move in 1/32 rotation increments as long as the button is held down.

I can get this to work with the move() and runToPosition() commands, but it accelerates and decelerates each time making the movement much slower then I need.   I would just use the runSpeed() command inside a while loop setting move() each time, but I need the acceleration as the pull in torque of the stepper is not great enough to start at the full speed needed.
Any ideas or suggestions would be greatly appreciated.

It is unclear to me, what your actual problem is. If the motor accelerates to slow, I think the AccelStepper library has a function to set the acceleration, so you could just set it to a bigger value. Or is the problem with reading the button for the described behavior?

it is absolutely simple ... do not move the motor when the button is pressed ... move the motor when the button transitions from not pressed to pressed

Currently If I press the button, the stepper moves 1/32 rotation using acceleration and deceleration.  If I press the button and hold it down, the stepper moves 1/32 rotation with acceleration and deceleration, delays for a short time (this is to allow me to release the button if I only want to move 1/32nd) and then goes into a while loop while the button is held down.  but since the commands i'm using are move(1/32) and moveToPosition() it accelerates and decelerates on each movement, and since each movement is short only 1/32 of a rotation it cant accelerate to much and so moves slow

Jsotola,     I understand what you are saying, but not sure how to implement that while retaining the needed 1/32nd step on a short press, and also the continues movement that I need to be in 1/32 steps while the button is held down.  What I want it to do is move one 1/32 rotation when I press the button and release it using acceleration and deceleration, but if I hold the button I want it to smoothly accelerate to maxSpeed, stay at maxSpeed until I releasethe button, and then stop on a even 1/32 rotation step with smooth deceleration.

If I understand your request properly (Move a little step for a short button press / Move continuously while pressed longer) you need to distinguish between long and short. This can only be detected when you release the button, or when the time distinguishing short/long has elapsed. -> You cannot start moving immediately when button is pressed.

I think I mostly got what I need, but haven't figured out how to end exactly on a 1/32 rotational location.  I don't have the code in front of me at the moment, but its something like:
if (button == 0){
move(400/32)
runToPosition()
delay(150)
read button
if( button==0){
move(34000)
while button ==0{
run()
read button
if (button == 1){
stop()
runToPosition()
}}
that is close at least.  It moves 1/32 on a short press, and on a button press and hold accelerates to max speed, when I release the button it smoothly decelerates as I want, but I need it to stop on an increment 1/32


text:
ADXL355 accelerometer code
I am doing a project which monitors vibrations using an ADXL355 sensor and an Arduino. I have used the MPU-9250 sensor before.
I am not able to find a library or tutorials for calibrating, filtering, and reading accurate data from the sensor. Can anyone who has worked previously with the sensor help me? I am mechanical engineer new to the field of electronics.
If library files are not available, how can I use the datasheet to write the entire code myself? Is there any tutorial available for this?
Sorry if the post seems confusing..

A quick google search gave me this library from Adafruit. It also has a calibration example. Applying filters has nothing to do with the sensor, but only with the already collected data. If you google something like "kalman filter library arduino github" you also get results for already existing libraries, that implement a kalman filter (often used with accelerometers/gyroscopes).

The above library uses Adxl 345.

I had a similar learning path  as yours and I also tried to use ADXL345 and ADXL355. The latter was a pain for the issues described in many posts like this.
I couldn't find any good tutorial on this topic and had to learn all by myself.
I also use a different approach because I program ESP32-wrover devices with MicroPython. Nevertheless the logic is the same for translating DataSheets -> code.

You have to decide which serial interface to use

I2C if you are constrained to limited wires
SPI for high frequency measures

in both cases you write/read to/from registers of the device which are identified by an address, indicated in the datasheet (look for the registers map section). In each address you read/write a byte, that is 8 bits (0 or 1), that are packed into an hexadecimal format (e.g. you can set power mode to 'measure' writing 0x01 in register with address 0x2d)

with both you normally have a library that implement 3 main methods:

init() for initializing the interface with the parameters you find in the datasheet:

SPI: polarity, phase, max_clock_frequency, first bit MSB or LSB
I2C: max_clock_frequency

read(register_address, nbytes) -> bytearray
write(register_address, bytearray)

before reading accelerations you must set range (e.g. ±2g), output data rate (e.g. 1000Hz), power mode (e.g. measure mode)

then you read acceleration data from corresponding registers. Consider that you can read multiple registers in one transaction reading multiple bytes starting from an address (e.g. you can read x,y,z measure in one transaction by starting from the first byte of x data and then reading 9 bytes = 3 axes * 3 bytes)

Then you have to convert from bytes to g units: in this accelerometer the value of one axis consist of 20 bits that are split in 3 bytes. You have to join the 3 bytes, shift away the trailing 4 bits, then apply two's components (that is for allowing negative numbers, look at this guide), then multiply by the scale factor indicated in the datasheet.


text:
ESP-NOW host not receiving data
I'm trying to set up a network like the following:
|Host| <-------> |Node x 3|
I want to have a two-way connection between a host and each node, but each node cannot communicate with other nodes. The host and nodes are all NodeMCU 1.0 ESP8266 12E with the same software on each node (has to be this way). The problem I'm dealing with at the moment is that I can send messages successfully, but my host is not receiving any messages from the nodes. Right now I'm only testing it with one node, and I'm only testing sending from the node to the host just to make sure the devices are connected properly. Here's my code for both the node and host:
#include <espnow.h>
#include <ESP8266WiFi.h>
#include <string.h>

//Macros

#define PORT 80
#define CHANNEL 1
#define ESP_OK 0

//-----Anonymous Project----//
//-----Author: Anonymous----------//
//
// Last Date Modified: 6/18/20
//
// Description: This project is designed to have several node arduinos connected to a host arduino. Whenever an
// event is triggered on a node arduino, the host reacts to this and activates the corresponding LEDs.
// The host arduino acts as a server while the node arduinos act as clients. Both the hosts and clients send data
// back and forth to each other to ensure arduinos are still active and are responding properly.
// All the software is the same on host and client arduinos, so whether an arduino is a host
// or client is determined by its MAC Address.
//
// Progress: At the moment, this project successfully establishes connections between the host and the nodes.
// I am currently working on figuring out why the nodes do not successfully send to the host.

//Global Variables
char hostMACAdd [18] = "XX:XX:XX:XX:XX:XX"; //change this MAC address to change the host node
String SSID = "NETWORK NAME"; //change this SSID to change the network name
String Password = "PASSWORD"; //change this to change the password required to connect. If node, connect to SSID with password given

bool isHost; //flag that controls whether host or node code executes
bool A = true; //flag for event A
bool B = false; //flag for event B

//Server-Specific Globals
bool haveMessage;        //global for detecting readings

//Client-Specific Globals

//Function Prototypes
uint8_t * MACAddrToInt(String MAC);
void configDeviceAP(void);
void initESPNow();
void wifiConnect();

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(500);

    //is it a host or node?
    if(strcmp(WiFi.macAddress().c_str(),hostMACAdd)){
      //node
      isHost = false;
      Serial.println("Client powered!");
      Serial.println();

      //set device in station mode if it's a node
      WiFi.mode(WIFI_STA); // Station mode for esp-now sensor node

      //Enable ESP Now
      initESPNow();

      Serial.println("Initialization successful!");

      //attempt to connect to host
      Serial.println("Connecting to " + SSID);

      esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
      if(esp_now_add_peer(MACAddrToInt(hostMACAdd), ESP_NOW_ROLE_SLAVE, CHANNEL, NULL, 0)!=ESP_OK){
        Serial.println("Error connecting to host.");
        //TODO: make this station a host and a node
      }

      Serial.println("Connection to host successful!");
    }
    else{
      //host
      isHost = true;
      Serial.println("Host powered!");
      Serial.println();

      //set device in AP mode if it's the host
      WiFi.mode(WIFI_AP);

      //Enable ESP Now
      initESPNow();

      Serial.println("Initialization successful!");
      esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

      int unsuccessfullyRegistered = esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data, uint8_t len) {

        String deviceMac = "";
        deviceMac += String(mac[0], HEX);
        deviceMac += String(mac[1], HEX);
        deviceMac += String(mac[2], HEX);
        deviceMac += String(mac[3], HEX);
        deviceMac += String(mac[4], HEX);
        deviceMac += String(mac[5], HEX);

        Serial.println("Message received from device: ");
        Serial.println(deviceMac);
        Serial.println(*data, DEC);
        //haveMessage = true;
      });

      if(!unsuccessfullyRegistered){
        Serial.println("Callback function registered!");
      }
      else{
        Serial.println("Callback function not registered.");
      }

      Serial.println("Waiting for clients...");
    }
}

void loop() {

  if(isHost){

  }
  else{

    String IP = WiFi.localIP().toString();
    uint8_t flagMsg;                  //message for events A and B.

    //             Inputs | Output
    //                    |
    //             A   B  |  flagMsg
    //             0   0  |  0
    //             0   1  |  1
    //             1   0  |  2
    //             1   1  |  3

    //FOR TESTING
    A = true;
    B = true;

    if(A){
      if(B){
        flagMsg = 3;
      }
      else{
        flagMsg = 2;
      }
    }
    else{
      if(B){
        flagMsg = 1;
      }
      else{
        flagMsg = 0;
      }
    }

    //String message = IP + " " + String(flagMsg); //maybe add pattern to this as well

    uint8_t * intMAC = MACAddrToInt(hostMACAdd);

    while(esp_now_send(intMAC, &flagMsg, sizeof(flagMsg))!=ESP_OK){
      Serial.println("Failed to send.");
      delay(2000);
    }

    Serial.println("Message Sent!");
    delay(5000);
  }

}

//convert MAC Address string to int
uint8_t * MACAddrToInt(String MAC){
  uint8_t hostMACAddArray [6];
  int values[6];

  sscanf(hostMACAdd, "%x:%x:%x:%x:%x:%x", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5]);

  for(int i = 0; i<6; ++i){
    hostMACAddArray[i] = (uint8_t) values[i];
  }
  return hostMACAddArray;
}

//set as Access Point
void configDeviceAP(){
  bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), CHANNEL, 0);
  if (!result)
  {
    Serial.printf("AP Config failed.");
  }
  else
  {
    Serial.printf("AP Config Success. Broadcasting with AP: ");
    Serial.printf("%s", SSID.c_str());
  }
}

void initESPNow(){
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else
  {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

void wifiConnect() {
  WiFi.mode(WIFI_STA);
  Serial.printf("");
  Serial.printf("Connecting... "); //Serial.printf("%s",SSID.c_str());
  WiFi.begin(SSID, Password);
  while (WiFi.status() != WL_CONNECTED) {
     delay(250);
     Serial.print(".");
  }
  Serial.print("\nWiFi connected."); //Serial.printf("%s",WiFi.localIP().c_str());
}

The code isn't near finished yet, but theoretically the nodes should send an integer to the host and the host should print it. The console output for the node shows that the message is being sent, but the last thing that shows up on the host console output is "Waiting for clients", which would indicate that the host isn't receiving anything. I'm pretty new to ESP_NOW but I've been reading a lot of documentation on it recently and my code shouldn't be breaking any rules, but here we are.
Some potential problems that I suspect:

I had to define ESP_OK in my file for whatever reason. In most examples I've looked at, this macro hasn't had to be defined, and it's possible the value isn't actually 0.
Maybe I need to set up the host as a WIFI_AP_STA instead of WIFI_AP. Not sure why this would cause problems, but I'm just speculating at this point.

imho, there is some poorly document connections between wifi settings and espnow. I found a way to avoid much of the config each boot by using "cached" wifi settings. That is, you flash each chip w/ a sketch that connects to your wifi, run it, then re-flash with your espnow sketch. The only wifi config in setup is then WiFi.mode(WIFI_STA);WiFi.disconnect();. Then the only espnow stuff in setup becomes esp_now_set_self_role,esp_now_add_peer,esp_now_register_send_cb, and esp_now_send.

@dandavis What do you think the issue I'm dealing with is? I don't have SendCB functions registered, but should that really affect anything?

The ESP-Now slave must be in AP mode because you can then set the MAC address. Your code did set the AP mode with       WiFi.mode(WIFI_AP); but it doesn't explicitly set the AP Mac address, so all the sensor nodes are sending data to a pre-defined remote hostMACAdd, but your AP is using the default physical MAC address, you need to set it to match the sensor node configuration with wifi_set_macaddr(SOFTAP_IF, &hostMacAdd[0]);. See my working example.

@hcheung Thanks for the help! Now I'm curious why you have to set the MAC address in the pattern you detailed. Shouldn't I be able to set the MAC address to whatever I want?

Connect with MAC is faster than connect with SSID, as SSID need to establish a connection which take up to 5 seconds or sometime even more. Another benefits of setting your own local-administrated MAC address is that if you for any reason to replace your board in future, you don't need to change the sketch to put in new MAC address of your board. If you looks at my example, you will see on the comment of the sketch on how to create a valid local administrated MAC address.

The pattern of the local administrated MAC address is defined in IEEE specification.


text:
Why is there a need of use delay() after using Serial.flush() in the program
This code is a part of a long code for understanding serial communication and the functions related to it.
char buffer[18];
int red, green, blue;
int RedPin = 11;
int GreenPin = 10;
int BluePin = 9;

void setup()
{
Serial.begin(9600);
Serial.flush();
pinMode(RedPin, OUTPUT);
pinMode(GreenPin, OUTPUT);
pinMode(BluePin, OUTPUT);
}

void loop()
{
if (Serial.available() > 0) {
int index=0;
delay(100); // let the buffer fill up
int numChar = Serial.available();
if (numChar>15) {
numChar=15;
}
while (numChar--) {
buffer[index++] = Serial.read();
}
splitString(buffer);
}
}

In void setup(), Serial.flush() is used. On internet, I have read that it flush out any character present in a serial line. After calling it we can be sure that all the data has been sent before moving on to the next line of the program.
In void loop(), in the first if condition, delay(100) ensures to fill the buffer. Basically, buffer is the place in memory where the received serial data is stored prior to processing.
The question is that is there any need of using delay(100), if we call the Serial.flush() initially because it ensures that all the serial data has been transmitted (as in serial transmission one bit is transmitted at a time)? Does it takes further time to store the transmitted data in the memory (buffer) and does this is the reason to use delay(100)? Please clarify why delay(100) is used after calling Serial.flush(), I am confused.

flush() changed usage in Arduino many years ago. the first use was to 'eat-up' all input. now it is flush the TX buffer. from change log for Arduino 1.0 "Serial.flush() now waits for transmission of outgoing data rather than discarding received incoming data."

Serial.flush() waits for transmission of outgoing data. But does this waiting time includes the storage of data in the buffer? As we use delay() in the further part of code.

No. The use of flush here is in appropriate.  It is not needed there.  This was written by someone who doesn’t understand what it does.  You can just remove that flush line.

The delay in loop is unrelated.  That’s waiting for the sender to finish sending.  This is a poor blocking method.  There are far better ways to write this code.  You should probably put this one in the rubbish bin and find something written by someone who knows what they’re doing.

flush() does nothing here. no data to flush are in transmit buffer at start. and how would it help with receiving?

The Serial.flush() is doing nothing. It delays until all bytes have been sent out of the UART. Since nothing has been sent it's not got anything to wait for.
The delay after the available call is very bad practice. It's a really really bad way of dealing with serial reading.
You should read this for a better understanding of serial communication.


text:
Error while inputting EEPROM.read() and EEPROM.write()
I am trying to store data in ATmega328 (Arduino Uno) using the following code using tinkercad:
#include <EEPROM.h>

void setup() {
  int addr, data=1;
  Serial.begin(9600);
  for (addr=0; addr<1023; addr++) {
    EEPROM.write(addr, data);
  }
  for (addr=0; addr<1023 ; addr++) {
    Serial.print(EEPROM.read(addr), DEC);
  }
}

When I simulate the code in the tinkercad, then i get the following error:
In function `main':
43: undefined reference to `loop'
 error: ld returned 1 exit status

Please help me where is the error in my code. I am not able to understand the error source.

Have you looked at any Arduino IDE example programs?
They all have a setup() and loop() function.
Apparently, Tinkercad is missing the loop() function in your code.
You can solve the issue by adding an empty void loop() { } after your void setup() { ... } code.

Thank you, now the code works. But I have a question in this code why there is use of the empty void loop() because it executes infinitely. It may be a silly question, I am a beginner to Arduino programming. But please tell what is the significance of empty void loop() in this code?

In most projects, Arduino code does not just execute once, but runs in a continuous loop, for example to service button presses, display data, take sensor measurements and act on them. The creators of the Arduino IDE have made the loop() function a standard part of every Arduino program to facilitate this. It's not part of standard C++. In your case your program just executes once and the loop() function does not have any significance. It's just doing nothing in a "controlled" way (continuous loop) and waiting for a reset.


text:
.toFloat() giving incorrect anwsers
I am broadcasting a fixed value float over a HC-12 radio which is then received by another HC-12 radio. I am then trying to convert that String to a Float which requires 6 decimal places. However, when I print the String value out and then the Float value out, I get two different answers.
Code:
    String lat=getValue(_msg, '|', 6); // Function to get lat value from incoming message
    Serial.println(lat);
    Serial.println(lat.toFloat(), 6);

This then results in the following values being displayed to the user:
51.507401
51.507396

The value 51.507401 is the correct value, so I would ideally like the float value to be the same.

A float is only an approximation. That is as close as it can get.

Is there anyway to get closer? Even .toDouble() gives the same result

There is no double on an Arduino. It's all float.

I would suggest not working in any form of floating point. Instead work in a fixed point. Use long and use the value x 1,000,000 or something like that.

Store 51.507401 degrees as 51507401 microdegrees

Thanks! I think I'll do that!

It seems the toFloat() method is being a bit sloppy in its conversion.
The float closest to 51.507401 is 51.5074005126953125, which is only
0.13 ulps off. The number you got is the float right before it,
namely 51.507396697998046875, which is 1.13 ulps off. Alas, the
avr-libc functions atof() and strtod() make the same error.
I would suggest first considering whether the error is really
significant for your application: it is only about 48 cm on the
surface of the Earth. If this level of accuracy is relevant for you,
then follow Majenko's suggestion and use an integer count of
microdegrees.


text:
RF522 version 0x12
I bought a bunch of the common RC522 boards from some AliExpress vendor. They (I tried multiple) seem to work at the register read-write level, but they don't seem to execute commands, much less recognise any RFID card.
But the really weird thing is that the version returns 0X12, which matches neither the rc522 1.0, nor the 2.0, nor the clone that should return 0x88.
I verified with my scope that the chip indeed answers to the SPI byte 1110_1110 (read register 0x37) with the value 0001_0010. The signal is crip, no clock skew, nice sharp edges.
I tried this with an Arduino Uno and an Arduino Due, using a recent version of the miguelbalboa library. But as I see this on my scope, it can't see how it can be a software problem.
Has anyone seen this, or better: found a solution?

Have you verified that your (unseen) code is actaully valid? i.e. does your (unseen) code work with other boards that are not 0x12?

All boards I have seem to respond in this way (I tried some 5 out of 100). For the code I tried a few repo's, last was I think https://github.com/miguelbalboa/rfid. But as I see the SPI 'command' byte & response on a scope, the question is mostly independent of the actual code.

Oh, ok. I meant ones that don't respond with version 0x12 which you say doesn't match any values you expected - Or, put another way, do you have any rc522 boards that return a version that "matches"  1.0, 2.0 or the 0x88? Perhaps these 0x12's require different code?

Looking at the MFRC522 library ... the version needs to be one of 0x88, 0x90, 0x91 or 0x92 ... anything else aborts PCD_PerformSelfTest - other than that there's nothing in the code that specifically requires a particular version ... however, given that the version you have is not one of those four, perhaps the issue is with compatibility

Put a delay(5) right after init() in setup() and firmware readout will work.


text:
ESP32 feedback from NTP
The basic example for ESP32 NTP is very rough:
void setup() {
  Serial.begin(115200);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

But it tells nothing about the success of the operation.
I need to know if it was able to update the time from the NTP server. Is there a method to know that?
I can't rely on the time struct because I must init it manually at startup, say to 1st Jan 2020 00:00.

Out of curiosity: why is the time set manually at startup, when you will be updating it using NTP anyway?

Because if the NTP is not reachable (i.e. no WiFi connection) the system must begin anyway the operations. The user can set the default datetime value for this scenario.

Did you follow that manual?
https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/
The printLocalTime(); function does all you ask for.
void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

getLocalTimereturns false on failure. Let the printLocalTime do the same.
boolean printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return false;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  return true;
}

Now the print function tells you if it failed (returns false) or not (returns true).

Please, look at the implementation of getLocalTime(). It just checks if the year if < 2016. But I said at power up I set the current time to a specific value (i.e. 1/1/2020). So I cannot rely on this. I need to know whether the NTP was ok or failed.

@Mark Sorry I completely misunderstood your problem. I also interpreted the code completely wrong. My answer does not fit to your question. I now have looked into the Arduino ESP code and probably there is a chance to find out if the time had formerly been set by a NTP Server call. But actually I have no time to evaluate that. I'll change my answer as soon as I could investigate a little bit. Hint: sntp_sync_status_t sntp_get_sync_status(void); in arduino-esp32/tools/sdk/include/lwip/sntp.h In any case the answer ocrdu gave is worth to try and should be the accepted answer if it works.

I'm not entirely sure there is a good solution for that with the normal ESP32 library, as it only checks to see if a valid year has been set, and the user has already set a valid year.
You could try using the NTPClient library or a similar one to get the time; its functions do a different check and actually return TRUE or FALSE.
On success, you can then use the newly retrieved time value to update the ESP32's RTC.

I'm going to try this solution, hoping the ESP32 framework is compatible with this library.

@Mark: I had a quick look at the code, and looks like it is compatible with all the Arduino-esk WiFi libraries. No guarantees, though 8-). I wonder why somebody downvoted my answer. Oh well. Please accept the answer so the question doesn't remain open. If it works and you actually do accept the answer, of course.

I upvoted your answer. To accept one of the answers I'm going to test them before.


text:
WebSocket Server for MKR1000
I was looking for a websocket server for my MKR1000 but nothing I found works.
I tried all the libraries that come with Arduino but half of those don't compile on the MKR1000 and those that do it don't work at all.
Your help would be greatly appreciated!

There is a dedicated  WiFi/Ethernet Shield that supports websocket server. But it is only worked with Uno and Mega. This shield name is PHPoC Shield

This relatively simple one has always worked for me on several Arduinos (but I haven't tried it on the MKR1000 specifically):
https://github.com/morrissinger/ESP8266-Websocket
I have forked it and made some changes, but nothing fundamental:
https://github.com/ocrdu/NINA-Websocket
Have a go; it will probably work for you. Note that it works on more Arduinos than the name suggests; it's quite universal.

Thanks for your answer, but devices based on ESP8266, doesn't work

IIRC (it's been a while), this websocketserver works on other Arduinos as well, it's more universal than the name suggests.

Thanks Ocrdu, https://github.com/ocrdu/NINA-Websocket works fine . I didn't use WiFinina I use instead WiFi101 and work ok.


text:
How to use ESP-01 GPIOs for input?
I'm trying to use one of ESP-01 GPIOs as an input, however, I'm always reading 1 and nothing attached to these pins.
Basically, I'm trying to detect high voltage from another sensor like a touch sensor or infrared to do some stuff (initial state will be low, so boot won't be affected).
So what I'm supposed to do to read the actual value 0?
Here is the code I'm running:
#define PIN0 0
#define PIN2 2
#define PIN3 3 // Using RX as GPIO

void setup() {
  Serial.begin(115200,SERIAL_8N1,SERIAL_TX_ONLY);
  pinMode(PIN0, INPUT);
  pinMode(PIN2, OUTPUT);
  pinMode(PIN3, INPUT);
  digitalWrite(PIN2, HIGH);
  digitalWrite(PIN0, LOW);
  digitalWrite(PIN3, LOW);
}

void loop() {
  Serial.print("PIN0: ");  Serial.print(digitalRead(PIN0));  Serial.print("\t");
  Serial.print("PIN2: ");  Serial.print(digitalRead(PIN2));  Serial.print("\t");
  Serial.print("PINRX: ");  Serial.print(digitalRead(PIN3));  Serial.println("");

  delay(500);
}

Here is the Serial Reading:
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1
PIN0: 1 PIN2: 1 PINRX: 1

esp-01S has pull-up on io 0

You are writing 0 to an input pin. From the Arduino reference:
"If the pin is configured as an INPUT, digitalWrite() will enable (HIGH) or disable (LOW) the internal pullup on the input pin. It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor."
Also, when you leave an input pin floating, ie. don't connect anything to it, and also don't enable (or explicitly disable) the internal pull-up or connect an external pull-up, the input pin can show 1, or it could show 0.
TL;DR: You shouldn't leave the input pins floating; floating pins are susceptible to electrical noise and can show anything or even fluctuate. If you want them to show 0 when nothing is connected, add an external pull-down resistor.


text:
Particle Spark (Arduino) How to flash 2 LED sequences at the same time?
I can't find any information that relates to my problem. The few things I did find confused me (I'm quite new to this).
I'm trying to flash 2 sequences of 4 lights at the same time. I can get 1 set flashing but I don't know how to run other sequences at the same time. My probably laughable attempt at the code is below:
int led1 = D0;
int led2 = D1;
int led3 = D2;
int led4 = D3;
int led5 = D4;
int led6 = D5;
int led7 = D6;
int led8 = D7;

void setup() {
  setupPart1();
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  setupPart2();
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
}

void loop() {
  loopPart1();
  digitalWrite(led1, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led3, LOW);
  digitalWrite(led4, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led4, LOW);
  loopPart2();
  digitalWrite(led5, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led5, LOW);
  digitalWrite(led6, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led6, LOW);
  digitalWrite(led7, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led7, LOW);
  digitalWrite(led8, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led8, LOW);
}

How about the example that comes with the IDE: BlinkWithoutDelay?

You could use a simple scheduler. Here is a multi-blink example: https://github.com/mikaelpatel/Arduino-Scheduler/blob/master/examples/SchedulerBlink/SchedulerBlink.ino

I cover this exact question in my web page: http://www.gammon.com.au/blink
Example code that blinks two LEDs at different rates:
// Which pins are connected to which LED
const byte greenLED = 12;
const byte redLED = 13;

// Time periods of blinks in milliseconds (1000 to a second).
const unsigned long greenLEDinterval = 500;
const unsigned long redLEDinterval = 1000;

// Variable holding the timer value so far. One for each "Timer"
unsigned long greenLEDtimer;
unsigned long redLEDtimer;

void setup ()
  {
  pinMode (greenLED, OUTPUT);
  pinMode (redLED, OUTPUT);
  greenLEDtimer = millis ();
  redLEDtimer = millis ();
  }  // end of setup

void toggleGreenLED ()
  {
   if (digitalRead (greenLED) == LOW)
      digitalWrite (greenLED, HIGH);
   else
      digitalWrite (greenLED, LOW);

  // remember when we toggled it
  greenLEDtimer = millis ();
  }  // end of toggleGreenLED

void toggleRedLED ()
  {
   if (digitalRead (redLED) == LOW)
      digitalWrite (redLED, HIGH);
   else
      digitalWrite (redLED, LOW);

  // remember when we toggled it
  redLEDtimer = millis ();
  }  // end of toggleRedLED

void loop ()
  {

  // Handling the blink of one LED.
  if ( (millis () - greenLEDtimer) >= greenLEDinterval)
     toggleGreenLED ();

  // The other LED is controlled the same way. Repeat for more LEDs
  if ( (millis () - redLEDtimer) >= redLEDinterval)
    toggleRedLED ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop

thank you very much, i dont understand it but i will sit down tonight and try to figure it all out from the guide on your site


text:
I2C Temperature Sensor Communication Issue
I'm currently learning I2C and having some issues displaying the correct temperature in the serial monitor.
I am using an Arduino Uno and an SI7021 temperature sensor from Sparkfun; here's the datasheet I'm looking at.
The datasheet says that its device address is 0x40 and the temperature register is 0xF3 (maybe I am looking at this wrong?). However when I print the result to the screen it reads -1 degrees F.
Here's my code:
// SparkFun Si7021 Humidity and Temperature Sensor
#include <SparkFun_Si7021_Breakout_Library.h>
#include <Wire.h>

//Weather sensor slave address
int WeatherAddress = 0x40;

#define Temperature_Register_DATA 0xF3

//initialize humidity and temperature variables
float humidity = 0;
float tempf = 0;

//create a sensor from the Weather library
Weather temp_rh_sensor;

void setup() {
  Serial.begin(9600);
  //create wire object
  Wire.begin();
  //begin weather sensor
  temp_rh_sensor.begin();
}

void loop() {
  //begin transmission to weather sensor
  Wire.beginTransmission(WeatherAddress);
  //ask particular register for data (temperature register)
  Wire.write(Temperature_Register_DATA);
  Wire.endTransmission();
  //request the transmitted single byte from the register
  Wire.requestFrom(Temperature_Register_DATA, 1);
  if(Wire.available() <= 1) {
    tempf = Wire.read();
  }
  Serial.print("Temp: ");
  Serial.print(tempf);
  Serial.println("F, ");
  delay(1000);
}

You have connected a 3.3V sensor to a 5V Arduino Uno via the sda and scl lines ? Did you use a i2c voltage level shifter ? Did you connect 5V or 3.3V to the + connection of the module ? The sensor could be broken by now.

Reading this sensor is a little more involved. You don't just select a register and then read the value from it. Instead you send it a command to begin a read of a parameter (e.g., temperature) and then you need to wait for it to perform that command before you can read the result.
You need to use command 0xF3 for read with no hold master mode which will return NACK from a read request if the command isn't completed (which you are doing) - you then need to keep retrying the read until you don't get a NACK.
Also you need to read two bytes, not one:
//begin transmission to weather sensor
Wire.beginTransmission(WeatherAddress);

//ask particular register for data (temperature register)
Wire.write(Temperature_Register_DATA);

Wire.endTransmission();

// Keep retrying the read until it succeeds, or times out
uint32_t start = millis();
while (Wire.requestFrom(WeatherAddress, 2) < 2) {
    if (millis() - start > 2000) { // 2 second timeout
        break;
    }
}

if (Wire.available() < 2) { // It timed out
    Serial.println("Timeout");
} else {
    // Read the two bytes
    uint8_t hi = Wire.read();
    uint8_t lo = Wire.read();

    // and combine them into a 16 bit value
    uint16_t temp = (hi << 8) | lo;

    // Now convert the returned value into a real temperature:
    tempf = ((175.25 * temp) / 65536.0) - 46.85
    Serial.print("Temperature: ");
    Serial.println(tempf);
}

Wire.requestFrom(Temperature_Register_DATA, 1);

This should have the WeatherAddress as parameter instead of the register.
Wire.requestFrom(WeatherAddress, 1);

Hi thanks for the response, I just gave this a shot but it is still spitting out a -1 for the temperature. Does this mean I'm just accessing the wrong register inside the sensor?

The datasheet says that its device address is: 0x40

there is no standard notation on how to code i2c addresses - it all depends on how the particular library is coded. In this case, try 0x80 and 0x40 and see which one works.

The datasheet is quite clear... "The 7-bit base slave address is
0x40". It even goes so far as to depict it in an entire byte showing the bits of the address (1000000) and the RW bit.