text:
Project concerning wireless communication between Raspberry Pi and Arduino Uno using NRF24L01
We are trying to send a message using NRF24L01, with a Raspberry Pi as transmitter and an Arduino Uno as receiver.
Our concern is that the receiver Arduino might not be working because we are not getting the proper output message on the serial monitor.
Code for the transmitter side (Python code):
import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev

GPIO.setmode(GPIO.BCM)

pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 17)

radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)

radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()

radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])
radio.printDetails()
#radio.startListening()

message = list("GETSTRING")
while len(message) < 32:
    message.append(0)

while True:
    start = time.time()
    radio.write(message)
    print("Sent the message: {}".format(message))
    radio.startListening()

    while not radio.available(0):
        time.sleep(1/100)
        if time.time() - start > 2:
            print("Timed out.")
            break

    receivedMessage = []
    radio.read(receivedMessage, radio.getDynamicPayloadSize())
    print("Received: {}".format(receivedMessage))

    print("Translating our received Message into unicode characters...")
    string = ""

    for n in receivedMessage:
        if (n >= 32 and n <= 126):
            string += chr(n)
    print("Our received message decodes to: {}".format(string))

    radio.stopListening()
    time.sleep(1)

Code used for the receiver side (Arduino):
#include<SPI.h>
#include<RF24.h>

// ce, csn pins
RF24 radio(9, 10);

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

  radio.begin() ;
  radio.setPALevel(RF24_PA_MAX) ;
  radio.setChannel(0x76);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  const uint64_t pipe = 0xE8E8F0F0E1LL;
  radio.openReadingPipe(1, pipe);

  radio.enableDynamicPayloads();
  radio.powerUp();
}

void loop(void) {
  radio.startListening();
  Serial.println("Starting loop. Radio on.");
  char receivedMessage[32] = {0};
  if (radio.available()) {
    radio.read(receivedMessage, sizeof(receivedMessage));
    Serial.println(receivedMessage);
    Serial.println("Turning off the radio.");
    radio.stopListening();

    String stringMessage(receivedMessage);

    if (stringMessage == "GETSTRING") {
      Serial.println("Looks like they want a string!");
      const char text[] = "Hello World!";
      radio.write(text, sizeof(text));
      Serial.println("We sent our message.");
    }
  }
  delay(100);
}

why would you single out the receiver as being the cause of the problem?

I am getting the output in raspberry pi as successfully sent the message. But the message is not showing in arduino serial monitor. That's why I think the problem is with the receiver side.Maybe the receiver is not decoding the message properly.

What is "Proper output" you're expecting with your code?

I am trying to send the message "GETSTRING" in the form of a list from raspberry pi which I want to get in the serial monitor of the arduino. In the arduino I am giving the command Serial.println(receivedMessage), but it is not getting printed.


text:
Use Low Power Arduino with Solar Panel
I am trying to create an arduino system with radio-transmitters and radio-receivers. The system runs from a rechargable battery that is charged with a solar panel. I am using a 1.1W 6V solar panel.
My problem is that I don't know how to make such a connection and I don't know what batteries to choose to power the arduino, assuming that I need it to run for 5-7 days without solar power and that the solar panel is good enough to recharge the batteries while they power the arduino. We are also assuming that the solar panel has 8 hours of sunlight.
To the arduino are connected the following sensors:

Flame Sensor
Light Resistor x2
Smoke Sensor
Radio Transmitter
Radio Receiver
DHT11 Temperature & Humidity Sensor

I am also looking to see if I can power down most sensors and power them on later if an event occurs. So probably all the sensors could be sleeping except the DHT11 and the Radio Receiver. Preferably though, if at all possible, the rest of the sensors should be on, if we can handle 5-7 days without the solar panel. I don't know if more information is needed but I'd be pleased to help out in the comments, or provide more information by editing the question. :)

Why do you want the DHT11 to be always on?

Have a look at https://thecavepearlproject.org/ . It goes into great detail on how to run the Arduino and sensors at very low currents.

@Gerben the DHT11 needs to be one because it will be the one providing information when asked to and alert when the temperature rises. So it always needs to be on

No. The Arduino needs to be "on". The Arduino polls the DHT11, say once per minute. You could remove the power from the DHT11 when it isn't used. Then re-apply power when you need a new temperature measurement. (Though you might need to add some delay between powering up, and getting a reading).

@Gerben Yeah that was the plan, although I measured the circuit without it and constantly reading from it and it was below 1mA, so I assumed that 1mA was the average draw just to be sure, before rewriting that part of the code, taking measurements every minute instead of taking every 2 seconds without powering off.

You have far too many variables and unknowns there. Primarily you need to know what the average current draw for your circuit is. Secondly you need to decide how long the solar powers are allowed to take to recharge the battery. You have to think not only about runtime but also charge time. The charge time dictates the maximum capacity of the battery, and that then dictates the runtime of the Arduino. So here's some napkin maths to illustrate:
Assuming you want the battery to charge from almost flat to full within 8 hours, and with a 1.1W 6V solar cell, that gives you a peak of 183mA.
Assuming the Arduino circuit takes 83mA on average (let's give ourselves nice round numbers here) that leaves 100mA peak for charging the battery.
If you're charging at, say, 0.2C, that gives a full charge in 5 hours. 100mA / 0.2C = 500mAh capacity (at peak sunlight and current).
At 500mAh capacity and 83mA average current draw that would give you (0.5/0.083) 6 hours of runtime without the solar panels.
So that's just not going to work.  It'll be dead by morning.
Now assume that you can turn off everything for 99% of the time.  That effectively reduces our average current draw to 0.083*0.01 = 830µA. Let's plug that into the same reasoning as above.

Current draw = 0.00083A
Incoming peak current = 0.183
Available charge current = 0.183-0.00083 = 0.18217
Charge at 0.2C = 910mAh.
1Ah battery would charge in about 5.5 hours of peak sunlight.
1Ah would last about 1200 hours, or 100 days.

None of this takes into account varying light levels or light incidence angles. As a rule of thumb, take the light as averaging 50% over the course of the 8 hour period. You will only get 1.1W when the angle of incidence is 90° to the solar panel. At all other times it will be reduced. So if we reduce the current from 183mA to, say, 100mA, the charge capacity changes to:

Incoming peak current = 0.100
Available charge current = 0.100-0.00083 = 0.099
Charge at 0.2C = 496mAh
A 500mAh battery would charge in about 5 hours.
A 500mAh battery would run for about 50 days at 830µA average current.

So you see everything really hinges around the current consumption of the Arduino. How much current it consumes dictates how much is available to charge the battery, which in turn dictates the size of battery you can support, which dictates the amount of current you can draw for your desired runtime, which in turn dictates the amount of charge current available, which determines the size of battery you can support, which dictates ... etc.  You get the idea.
You can support larger batteries, of course - I illustrated this at 0.2C charge rate (that's 20% charge per hour to give a 5 hour charge time). As long as the net charge over time increases (so during the periods between the 5-7 days of complete darkness you gain more charge than is expended during the dark period - something which has not been specified) then it should function fine.
Also note that your battery voltage should be below your solar panel voltage. A 6V solar cell would be able to charge a 4.5V lead acid battery (assuming low dropout schottky protection diodes). Also the capacity of the battery depends also on what you determine your "cut-off" voltage to be. That's how low the battery voltage is allowed to go before your system is determined to be unworkable. This could be at a point where the battery is in danger of being damaged by over-discharge, or at a point where your circuit no longer receives enough voltage to function (which could be linked to oscillator frequency on ATMega chips), etc. For this reason it is often better to choose a board that is designed to run at a lower voltage (3.3V) and use high efficiency switching regulation to get the most out of your battery. A 5V Arduino is seldom a great choice.
Finding that right balance is now entirely up to you.
And, in answer to your other question, yes there are ways to turn things on and off. You can "sleep" the Arduino. You can use high efficiency power circuits. You can add power switching circuits (P-MOSFETs) to switch power on and off to other modules. All things can (and mostly should) be done to save power when running on batteries.

Thank you for your answer it was really helpful. I think I have some more questions. What would you suggest to do, if I needed the receiver and temperature module to be on always but other sensors off? What ways are there to do this and how would I connect the solar panel to the battery and the battery to the arduino?

First: you would connect the solar panel to the charger, then the charger to the battery. The battery then connects (via the charger) to the power supply, which then connects to the Arduino. You can't just wire a solar panel to a battery and hope it will work - charging takes management.

Second: you choose an RF solution that has a low quiescent current in receive mode and has the ability to wake the Arduino from sleep when needed.

Ok I will look more into the charging part of the battery. I used the RadioHead library for the radio modules and looked into the docs and found a method that will sleep the receiver or transmitter, I believe. Would that be acceptable? Also how would I "Sleep" the rest of the sensors? digitalWrite(pin, LOW)?

It depends on the sensors. Some you won't need to, some you will be able to instruct to "sleep", and some you will need to cut the power to. A P-channel MOSFET can be used for that, which you can control with a digital IO pin.

Well in that case I have to first make the circuit, calculate it's Amp output and then calculate what battery will it need if the circuit runs as it is and the recalculate Amp output with most modules sleeping and then see what battery I could use. As you said the solar panel gives an output of 183mA so a battery of 183mAh will charge in 1 hour. How could I effectively charge the 500mAh battery you were talking about that would last about 50 days, if the dht11 and rf receiver are on?

Let us continue this discussion in chat.

Current consumption of DHT11 depends on how often you sample it. Receiver current depends on what the receiver is. Note that a solar panel is a current source, and batteries of different types may need a voltage source, current source, or a managed combination of the two. That's what the charge controller is for. For example you will need to convert the solar current source into a voltage source for lead acid batteries.

You just said a lot of stuff I am not familiar with :P Maybe I could sample the DHT11 every minute? So every 60 seconds the DHT11 sends me the current temperature and humidity and that is stored in my computer, so when I ask it to send me info about the weather then it just shows me the last input I got from the dht and not the actual current weather condition. So I guess the dht11 could be used only once every minute. The receiver is a 433mHz rf module, the most common one. Could you suggest a charge controller that will work in my situation?

So I found out that my circuit draws up to 1mA so I could use 2 batteries of 3.7V connected upside-down (that is 7.4V) and 500mAh to power the circuit for at least 500 hours, so 20.8 days.

You won't charge those with your solar panel.

Why won't they charge?

You said the solar cell will produce 183mA in 8 hours so, 183mA - 1mA = 182mA left for charging. 182mA / 0.2C = 910mAh capacity. So isn't that enough to power the 500mAh battery??

You would need to boost the voltage. You only have 6v max...

How would I boost the voltage?

With a boost regulator - however that then reduces your available current. This is why I suggested a 3.3V Arduino and a switching regulator since it is more suited to running from the kind of batteries that a 6V solar panel is capable of charging.

If I had an Arduino UNO R3, but only used it's 3.3V pin, would that be ok?

No. You can't run a 16MHz Arduino at 3.3v.

I still need batteries above 5V though and all I can do is get 5 1.2V batteries to get to 6V, to be able to power them with the solar cell. Could that work?

No. You need a higher voltage than the batteries in order to be able to charge them. I suggest you do a little reading and learning before you start this project.

I had to find out today what type of battery I needed, that's why I posted such a question here. Could I manage with 4 1.2V batteries to just make it work for a bit?

4.8V is fine for a 16MHz Arduino. Read the datasheet for the chip. In the electrical characteristics there's a graph that shows the relationship between the voltage and the maximum supported frequency.

I saw that the arduino regulates the power so anythin 4V-20V would anyways be regulated so it's fine until the battery drops below 4V?

No. You do not want to use the built in regulator. That is a terrible regulator and will waste lots of power, and won't allow you to run at anything under 6.2V.

What regulator would I have to use? I just need this to work in theory and probably for a smaller amount of time than days, maybe hours. Wouldn't I be able to charge the battery and run the arduino on 4.8V?

You don't need a regulator at all. 4.8v is within the specifications of the chip.

OK then the final circuit will consist of the solar panel connected to the lithium charger, that will be charging the 500mAh 4.8V battery, that will be powering the arduino's circuit that draw 1mA at max estimation. So that will work? Am I could after 1 day of searching for batteries? :P

The only problem with that scenario is that you shouldn't power a circuit from a lithium battery that is being charged. You risk confusing the charger and over-charging the battery.

What would you suggest? Charging the battery until it's full and simultaneously powering the arduino, from the solar cell? And if the solar cell goes out then the arduino should draw power from the batteries?

That is the normal way, yes. The circuit I usually use is the one shown in this question. Most of it is your Li-Ion charger. It's the portion around the battery - Rpull, Q1, and D1 - that forms the interesting part that switches the load's supply for you automatically.

Ok thank you so much for your help and patience. Would getting x2 3.7V batteries lowered down to 5.5V with like a potentiometer work?

No, but using a high efficiency switching regulator with them would. But then you can't charge them with just 6v.

So it still wouldn't work? My only option is to find Li-Ion 1.2V batteries?

No, you have plenty of options. The best one is to not use a 5v Arduino and instead pick one of the more modern 3.3v ones. Then you can use a single li-ion battery.

Could you name one? I am also in a budget and batteries go for like 9$ which is 27% of it.

I'm thinking maybe I could get 1 lithium battery and use a boosting circuit to get the voltage to 5V to power the arduino. Will the draw increase? Even if it does we should probably be good?

There are arduinos specifically designed for low power use of lithium batteries. Check the website.

source: Stack Exchange

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

sort: votes


text:
Why does Arduino IDE recommend storing 0-255 numbers in "byte" instead of "char"?
I bumped into byte datatype recently. My knowledge of C/C++ is shallow, but I know char and I couldn't find much on byte in C++ docs. I looked it up in the Arduino docs:

It’s recommended to only use char for storing characters. For an
  unsigned, one-byte (8 bit) data type, use the byte data type.

Is byte datatype a solely Arduino construct? If so, why is it recommended over char? Both are 8-bit so why would it make any difference?

char is configured as signed in compiler setting of Arduino Arduino cores

Whenever I make something bigger than just 50 lines, I always use the most specific types like: uint8_t, int8_t, uint16_t, int16_t, uint32_t and int32_t to know exactly what is signed or unsigned and if it is 8, 16 or 32 bits. And I use char for characters, and bool for booleans. In this case you never have to think what fits (or should fit) in a variable.

Is byte datatype a solely Arduino construct?

Yes. Much of the Arduino "language" is "bent" to look like Java, since it originated from Processing, which is Java. So we have data types the "look like" Java ones, including "byte" for "unsigned char" and "boolean" for "bool".

If so, why is it recommended over char?

Personally I don't ever recommend using it, since it's non-standard. Instead you should use uint8_t which is essentially the same thing, but portable.
It is recommended to use "hard signedness" data types for portability.  The problem with char is that whether it is signed or not is entirely down to the compiler implementation. Some systems have it as signed, some as unsigned. By using byte (or better, uint8_t) you are always going to get an unsigned 8-bit value.
For just storing of binary data it doesn't really make any difference, but when it comes to doing mathematics with the stored data you may find you suddenly have negative values when you don't want negative values (a char might be storing your number as -128 to +127, not 0 to 255).

Great explanation. I will stick to specific unit8_t in the future and will go back and refactor my "chars". I prefer to stick to C/C++ syntax than to wander into Java and have another language to be shallow at.

Just a little add-on to Majenko's answer:
If a function has a char* parameter, it's usually expecting a zero-terminated text.
If a function has a byte* parameter, it's usually any binary data, eventually containing '\0' bytes. The buffer size needs to be an additional parameter in this case.
If there's nothing else to consider, why not use that for your variable definition too:
Use char only if it contains an 8bit character. Or something like char text[]="hello";
For binary data it might be relevant if it's signed (int8_t) or unsigned (uint8_t).

"usually" implies of course that you should read the doc.

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


text:
Arduino with NRF24L01. Getting correct data from unkown transmitter
I want to use my Arduino with this: VAC8010F measure unit. It communicates with NRF24L01. The problem is I simply don't know which band or information it is receiving. Can somebody help me with this?
Thanks for any suggestions!

What does your favorite search engine reveal? What did the data sheets and documentation tell you? What is it what you do not understand in their contents? -- Please take the [tour] and read "[ask]". Then show some effort and come back to [edit] your question.

You need to know the channel and the pipe-id (and speed, though my guess would be 1Mbps). To find the channel https://github.com/nRF24/RF24/blob/master/examples/scanner/scanner.ino might help. Not sure how to find the pipe-id.

One possibility is sniffing the SPI bus and seeing how the module is configured. Another is using an SDR and decoding the communication on-air. Third method is dumping the unit's firmware and reverse-engineering it. Any other methods are probably too slow, I'm not aware of a promiscuous mode on the nRF24L01+ and checking all speeds, channels and pipes is way too slow.

Sniffing the SPI bus is probably the easiest, you could possibly even attach your own wires to the bus and possibly read out all the registers.

Don't have full details yet. But the VAC8010F uses modbus RS485 protocol.
My research shows that the NRF24 just transmitts and receives the MODBUS protocol to and from master/slave. I have found modbus libs and samples of code on the net. There is a command driven program to communicate with MODBUS free for linux, which is the o/s I use. I don't know about win. Anyway, once I receive the MAX485TTL interface for my ARDUINO MEGA I will write code for data  logging to p.c. then modify to use the NRF24, as I should be able to extract the ADDRESS, and CHANNELS etc, and packet construct.
Hope this is of some help.
Patrick

Nordic has an app to connect to nRF
https://www.instructables.com/Send-Data-to-Mobile-Using-NRF24L01-Using-NRF-As-a-/
The app is available for all platforms.
Did not try it myself. Hope this helps.
I going to do the same, but want receive it on Android.
If you got some news, please let me know.
Thanks

Have got a cheap Logic Analyzer to use with Saleae Software. Many protocols can be choosen including modbus. @Patrick: Do you know the baudrate? is it RTU/ASCII? Who is Master/Slave?


text:
Streaming audio to ESP8266 over WiFi
I am thinking of making a wireless speaker using the ESP8266 chip. I have some questions regarding this.

Which pin of the ESP8266 chip can be used as I²S output? I have an ESP chip of this type :

Which ESP chip would be the best choice for this purpose?
I know about the MAX98357A which is used to convert digital I²S data to analog. But, for stereo output I need to use 2 of those. Is there any alternative to this chip which supports stereo output by default?
I have found many tutorials which shows how to play audio from SD card of ESP8266. But, how can I stream audio over standard WiFi connection?

Which pin of the ESP8266 chip can be used as I²S output?

I uses GPIOs 2, 3, and 15. You only have GPIO2 available, and that's also one half of the UART interface.  Also you usually need to generate a "master" clock (usually something like 256x the bit clock) for oversampling. So you can't with that module.

Which ESP chip would be the best choice for this purpose?

ESP32, without a shadow of a doubt.

I know about the MAX98357A which is used to convert digital I²S data to analog. But, for stereo output I need to use 2 of those. Is there any alternative to this chip which supports stereo output by default?

Yes, there are plenty. The search term you want is "CODEC". Personally I use the TLV320DAC3101.
You never use two separate mono CODECs for stereo, since I²S is a (normally) stereo protocol for connecting to a stereo CODEC. Reliably splitting a stereo I²S stream into two mono ones is not easy.

I have found many tutorials which shows how to play audio from SD card of ESP8266. But, how can I stream audio over standard WiFi connection?

By implementing a suitable protocol, and that depends entirely on what your audio is and how it is generated.

For number 3 I am thinking of this technique : https://electronics.stackexchange.com/questions/295889/using-two-mono-amplifiers-to-make-one-stereo-amplifier

Can you please elaborate on the last answer? I simply want to stream MP3 audio.

There is no such thing as "simply" streaming MP3. Streaming involves buffering, then decoding (in a timely manner) the audio from compressed MP3 format into a PCM format. Then feeding that through other buffers to the I²S hardware. If you are streaming a live stream (radio, for example) then you have to be able to cleanly handle "xruns" (buffer under- or over-runs) where the sender isn't sending at the same speed as you're playing. So your project really comprises three parts: 1. Getting the data. 2. Decoding the data. 3. Sending the data to I²S. All three of those are difficult tasks.

What did you mean by usually something like 256x the bit clock) for oversampling. So you can't with that module.?

You don't have the required pins available. So you can't with that module. On top of that you have to usually generate a master clock. And there's no pin for that on that module. So you can't with that module. You just can't with that module.

Will the ESP32 be able to fulfil all those requirements?

More than likely, yes. Google for some projects.


text:
Print 2 numbers stored in 24-bits in decimal format
An implementation function from the nice little Wiegand library YetAnotherArduinoWiegandLibrary prints a hexadecimal representation of a facility # & card # (8-bit facility #, 16-bit card #) — 24 bits of a 26-bit stream that comes across the wire.
Example encoded 24-bit number: 7111097 (decimal). Hex equivalent: 6C81B9. The 6C portion is the facility # (decimal: 108). 81B9 is card # (decimal 33209).
This function from the library's example usage serial prints the hexadecimal format of the number:
void receivedData(uint8_t* data, uint8_t bits, const char* message) {
    Serial.print(message);
    Serial.print(bits);
    Serial.print("bits / ");
    //Print value in HEX
    uint8_t bytes = (bits+7)/8;
    for (int i=0; i<bytes; i++) {
        Serial.print(data[i] >> 4, 16);  //1st, 3rd, 5th hex digit
        Serial.print(data[i] & 0xF, 16); //2nd, 4th, 6th hex digit
    }
    Serial.println();
}

What I've tried to do unsuccessfully so far is to loop over the bits to also serial print the two decimal formatted numbers (facility:card) in the final output form:  108:33209

why do you need to loop over bits? ... the for loop already manipulates bytes of data

@jsotola With or without a for loop how do you output the two separate logical numbers in decimal format?

how do you convert 3 bytes to a single number? .... think about this ... what mathematical process do you follow to convert 4 hundreds , 6 tens and 8 units to 468?

I wonder why that sample code prints each nibble of a byte separately? Doesn't Serial.print(255, 16); output FF? So couldn't the inside of the for loop just read Serial.print(data[i], 16);

Your code loops from the high order byte to the low order byte, printing each byte as 2 hex digits.
If you want instead to print the first byte as a decimal value, and then the remaining bytes as another decimal value, then do this:
Print byte 0 in base 10:
    Serial.print(data[0]);  //first byte
    Serial.print(":");

Then loop through the remaining bytes, building a result as a decimal value, and print that:
unsigned long total = 0;
for (int i=1; i<bytes; i++) //Skip the first byte
{
    total = total << 8;  //Shift the previous total by 8 bits.
                         //(The same as multiplying by 256, but faster)
    total += data[i];    //Add in the new value
}
Serial.println(total);

The sample code you posted is written to handle a variable number of bytes. The code above does the same thing with decimal results. It's much simpler if you know you will always have 3 bytes or 4 bytes:
For 3 bytes:
    Serial.print(data[0]);  //first byte
    Serial.print(":");
    long total = long(data[1])*256 + data[2]);
    Serial.println(long(total);

I wrote the second version of the code using long ints, since I started out with printing an 8-bit value followed by a 24 bit value. If the second value is only 2 bytes (16 bits) you could change the data type to unsigned int

This is great and makes sense of it for me, thank you.


text:
How to set a not plugged in pin to ground or Low
I have digital pin 7 when set to High it does and when set to low it does not.
The only way I can get consistent High or Low is to use a 2 position 3 pin switch with my pin 7 in the middle and ground on one side and 5v on the other.
Is there a way I can use an simple Open/Close switch and still get the same function?
As of not if I dont "pull" pin 7 to ground I get both open and close randomly.

Have you configured the pin as input? Please provide the code and your wiring diagram. A not connected pin, that is set as input, catches random noise, thus changes state rapidly.

Yes the pin is set to input, is there a way I can remake the circuit were it does not catch noise when it is open?

output+dwrite(low) doesn't ground it?

Seems like you already found the solution. Without a pull-down of pull-up resistor, the voltage at pin 7 will float to some random voltage, when the switch is open.
Either add an (external) pull-down resistor. Or flip things around and use the internal pull-up resistor inside the ATMega328p. Then connect the other side of the switch to GND. Whenever the switch is pressed, your digitalWrite gives you a LOW.
To use the internal pull-up use pinMode(7, INPUT_PULLUP);

This worked perfectly thanks for the advice it was super helpful.


text:
when i compile my code i get th is error stating "checkbutton" not declared in this scope
// After 2 seconds have passed, stop ignoring the button.
  // If the button is pressed, call the checkbutton function.
  if (millis() > ignore && digitalRead(0) == LOW)
  {
    checkbutton();
  }
}
// This function waits for the button to be released,
// then waits for it to be pressed to start the next run.
void checkbutton(){
  delay (50);  // Button pressed, debounce.
  while (digitalRead(0) == LOW) // While button is pressed,
  {}                            // do nothing while waiting.
  delay (50);                   // Button pressed, debounce.
  while (digitalRead(0) == HIGH)// While button is released,
  {}                            // do nothing while waiting.

  ignore = 2000 + millis();     // Set the now ignore time,
}                              // and return to the main loop.

Please update your sketch to add a setup() and loop() function, then add your code to it with proper formatting.

please do not be offended, but i downvoted your question because you posted a complete mess ... did you not look at what you posted? ... please format your code ... use the {} button to do the formatting ... also, please ask a question

You need to provide a fully functional code, not only a snippet of your code. That will not work alone. Also you need to include the complete error message, including the line number, where the error happened.

Are you using the Arduino IDE to compile? It will automatically add function prototypes to the top of your code. When you are using something else to compile, you need to declare every function above where you are using it

You are using checkbutton() before you have told the program what checkbutton() is.
You need to move the whole method definition void checkbutton(){ ... } more to the top, i.e. in front of any call to it (checkbutton();).
Another option would be a forward declaration, but I doubt it's widely used in Arduino projects.

@jsotola: that's true. I don't think this is widely used in Arduino projects. Anyway, I added that to the answer

The only reason it isn't widely used is because the IDE does it for you - invisibly. While that helps people just learning C and C++ to get something up and running quickly, they miss learning about forward declarations, which inevitably bites them when they move to another environment.


text:
Arduino Nano 33 IOT issue
Nano 33 IOT is not detecting by windows . When i plug the usb cable only green light on the board.
Board is installed from the board manager. the cable is usb DATA cable and not charging cable. I tried the double press on the reset button but nothing happen. The L light is Off and the green light isnt flashing.
I plugged the board into another usb port, the same issue. I tried the board on my friend computer also but no luck. I dont have ATmel ICE or any other debugger like j-link.
https://www.youtube.com/watch?v=C0tXa0uxv5c
I hope someone can explain what is the issue, is it hardware or software.

much clearer ... the first sentence describes the problem, the rest of the post is more or less irrelevant because it depends on proper windows detection ... may be a missing windows driver or may be hardware .... try plugging into a linux machine and looking at the kernel messages (dmesg) .... you can use a linux liveCD like Knoppix or Linux Mint to boot your PC

Windows 10, 64bit. The second board ( Nano 33 ble sense) working on the same usb port. after I spent time on google I found that the problem related to missing bootloader for some reason. Many faced the same issue but few of them were successful to recover the board by double press on the reset button.

Not an answer to your problem, but just some information you might want to know. Nano 33 BLE Sense is a very different board from Nano 33 IoT, even their name suggesting they belong to the same family, but they use different MCUs. Nano 33 IoT is based on Microchip's SAMD21 32-bit ARM Cortex-M0 MCU. But Nano 33 BLE is actually use the MCU within the uBlox module which is a Nordic ARM chip. Both MCU have on-chip USB supports.

One way to solve the Nano 33 IoT reset problem is to replace the 100k resistor connected to the reset pin with a 10k resistor.

I mentioned the Nano 33 ble sense because i bought them from the same store and not to forget. I got Seeed wio lite w600 wich has the same MCU  SAMD21 . Both broads with different mcu working fine and to eliminate the issue between the three boards. I had to mention the names.

I guess i have the same issue.
Did you solve the issue?
If yes could you please share the hardware and software you used to do it or the link to the process you follow?
thank you.

@y78, it is in the answers

If you upload to a SAMD board like the MKR boards or the Nano 33 IoT with Nano 33 BLE selected in Tools menu of Arduino IDE, the upload is executed and deletes the bootloader of the SAMD MCU.
The problem is that bossac uploader doesn't check the chip, because it was developed only for the SAMD chips, but Arduino created a bootloader for the Nano 33 BLE nRF52 MCU to use the SAMD bossac uploader.
The SAMD boards use the native USB support of the MCU, so without a bootloader or good sketch running the USB doesn't work.
You have to restore the bootloader on Nano 33 IoT. It is done over the SWD pads on the bottom side of the board. You can use a SWD programmer or other Arduino board with the Adafruit DAP library.
You can use your Nano 33 BLE or some other board and a SD card with Adafruit DAP library as programmer.
I had this problem with MKR Zero and I used a LPC-Link2 programmer to burn the bootloader. Once before I lost the bootloader for other reason and back then I didn't have the programmer so I used the Adafruit DAP library with an Arduino M0.

HI Juraj.  My problem is that the board is not detected by windows and only green light when i plug the usb cable. and second , I dont have ATMEL ICE or any deubgger like j-link.

@HussamMj, yes, without the bootloader the board doesn't create an USB port. you can use the Nano 33 BLE or the other SAMD board and a SD card with Adafruit DAP library as programmer

I have Seeed Wio Lite W600 which is fully  Arduino Zero Compatible and I am wondering what the possibility to use this board to burn the bootloader on the Nano 33 IOT.

@HussamMj, yes, you can use it with the AdafruitDAP library, but you will need a SD card too

I am going for the STM32 black pill.

After I waited to get my order on ebay. I managed to restore the bricked board.
The issue was related to bootloader fail. either the producer shipped it without a bootloader or some kind of static discharge caused to erase or stop the booloader from working and that why windowws didnt detect the board.
I used a converted cortex m3 to swd programmer debugger and one line cmd command.
Thank for all who contributed  solutions.
If anyone experience the same hardware failure, it is due to missing or corrupted bootloader.


text:
Keyboard.write writing ASCII integer value as a String
I have the following code:
#include <SoftwareSerial.h>
#include <Keyboard.h>

SoftwareSerial ttySerial(10, 11); // RX, TX
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  Serial.println("Serial Initialized");

  //Set the data rate for the SoftwareSerial port
  ttySerial.begin(115200);
  ttySerial.println("tty Initialized");

  Keyboard.begin();
}

void loop()
{
  while (ttySerial.available())
    //Serial.write();
    Keyboard.write(ttySerial.read());

//    if (Serial.available())
//      ttySerial.write(Serial.read());
}

my problem is that ttySerial.read() is an int and I thought that the Keyboard.write method could hand integer arguments: Keyboard.write(32) should write "< space >" not "32".
Any ideas what is going on?

i do not see Keyboard.write(32) in your code ... what are you doing to send byte 32 to the sketch?

@jsotola thats because I am writing byte 32 to the RX Pin using SoftwareSerial. The ttySerial.read() is where I recover that and want it to be written using Keyboard.write. Simply put ttySerial.read() == byte 32 (but can also take on the form of other bytes)

And what is the problem? Is this program misbehaving? If so, what it it doing? What behavior do you expect instead?

it writes 32, because you send "32". Send 32 or ' ' to simulate space bar press.

@Juraj How can I convert "32" as received fromstring to int? I tried using ttySerial.read().toInt()) but I get a compilation error

@EdgarBonet The keyboard is writing the ASCII integer values instead of the ASCII character corresponding to that integer. My expectation is a write of the ASCII character

two separate characters are received. you can print debug messages to Serial Monitor while using HID

@Juraj should I be using ttySerial.readString() then? How can I read the two separate characters into a single integer value? Note sometimes the integer will be 1 digit, sometimes 2, sometimes 3

you could use parseInt. or send bytes not text. what is the sender? send ' ' not "32"

@Juraj Yes it looks like parseInt() is what I am looking for, thanks! Ill try it out tonight. Unfortunately the js serial-port library I am using only allows transmission of buffers and strings, not integers. Also, handling modifiers could become difficult by not sending the ASCII integer value. It looks like parseInt() will read chars and automatically convert the data type to int so that should be perfect.

why not send the characters you want to press and not the ascii codes?

@Juraj > "handling modifiers could become difficult by not sending the ASCII integer value"

You can send arbitrary data with a JavaScript buffer. For instance, both Buffer.from([32]) and Buffer.from(' ') will give you a buffer holding a single byte with the numeric value 32.

@EdgarBonet for some reason that isnt working but I will mess around with it some more

@Juraj parseInt() works but is incredible slow - any alternatives? Edit: it's a little faster now idk why

it is not slow. it waits a second for the next character, because it doesn't know which is last. you could use ttySerial.setTimeout(100); (in setup)

write will treat an int as a number and assume you want it converted to ascii.  Try casting that to char:
Keyboard.write((char)ttySerial.read());

The print class treats char variables as if they are already ascii codes.

Are you saying I should try Keyboard.print(...)? Or .write as you have?

I'm saying that either way you have to feed it a char if it is an ascii code.  And yeah, I'd probably use print there.

Well I tried (char)... at one point but the behavior still wasn't write but I didn't do it using .print not sure if that would make the difference - I'll have to try it out next week but I'll let you know

Delta_G, read the comments please


text:
Millis () funtion fails to perform for extended period of time
I'm using millis () function to control the timer of my LED. It is a very basic code that I used from the example libraries. The code worked well for 6 hours (On for 6 h, Off for the following 6 h and continues), however, when I set it up for 12 hours, the light failed to turn off when I checked on it. The designed time should have fit into the 2^32 bits for unsigned long which I have defined beforehand.
Can someone please help on this issue? Thank you!
/*
  Blink without Delay

  Turns on and off a light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  7;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
unsigned long interval = 12*60*60*1000UL;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

please look at your post ... does the program listing look the way you intended it to look? ... please format your code ... use the {} button

use unsigned long interval = 1000UL*12*60*60*;

In C++, the multiplication operator is “left-associative”. This means
that the expression
12*60*60*1000UL

is interpreted as
((12*60)*60)*1000UL

The left factor, namely (12*60)*60, is computed using the int data
type, but the result overflows that format, resulting in the problem you
see.
The simple solution is to make one of the factors of the first product
be an unsigned long. For example
1000UL*60*60*12

Then, 1000UL*60 is computed with the unsigned long data type. Since
the result is itself an unsigned long, the next multiplication is also
done as unsigned long, and likewise for the last one.
If you find this technique somewhat obscure, you can also add the UL
suffix to every single factor. This would avoid implicit conversions by
the compiler, making all the types explicit.

The problem is panned out! Thank you sir! Programming is not my field at all and so I am clearly with no base. Your comment is very helpful and much appreciated.

Did you try to change your variables so that the calculations would be in seconds instead of milliseconds ? IOW add "/1000" after millis() and reduce your constants accordingly.
millis() is overflowing periodically, but it only happens every 49 days or so, and that even shouldn't play a role in the way you use it (the difference will also kind of overflow in the other direction).

Do not add /1000 after millis(), otherwise you will have a problem when millis() rolls over.


text:
Can I use 1-byte datatypes to store digital input?
I am reading the docs on DigitalRead() and wondering why it stores seemingly boolean HIGH and LOW inputs in int data type variable.
I have two issues with that:

int is 2-byte, while bool and uint8_t are 1-byte so it seems like a waste of memory for no benefit whatsoever.
It gets me confused when reading the code about whether the input came from digital or analog since int can have a wide range.

Is there any particular reason for storing digital inputs as int?
EDIT: bool and uint8_t are out of the question as per the answer below. int8_t still looks suitable for the purpose though.

Note that the value returned by a function is passed in internal CPU registers, so no waste of RAM here. If I ever had to store the returned value in memory, I would indeed use an uint8_t.

You receive the data as int, but you store it as byte.
For example, when you call the serial library function to receive a data byte, the library will return either the data or a -1 if a problem has occurred.
The binary value of -1 is a byte 11111111 or int 1111111111111111.
The binary value of 255 is a byte 11111111 or int 0000000011111111.
I think that you can see the problem if you use byte data and the data is 255.
So, if you receive an int -1, then you do not process the data.  Otherwise you cast the int to uint8_t.
You could receive byte data, but then the value of 255 would be undefined.

I suspected there was something hidden going on. What about int8_t? It can store -1, 0, and 1 and still takes up 1 byte

int8_t stores values of -128 to 127 .... uint8_t stores values of 0 to 255 ... the two data types both store 8 bits ... they are just there so that the compiler will throw a warning if the limits are exceeded

So I just replaced all ints storing digital inputs in my program with 1-byte int8_ts. It seems to work fine so far.

Neither digitalRead() nor analogRead() ever return -1.
There is no reason why digitalRead() is a int function instead of uint8_t, and it indeed needlessly wastes space. The compiler will probably optimize it away though, if you store the result as uint8_t or int8_t

I did not check the internals a while, but in early days there was a
 #define HIGH 1

meaning that HIGH is a const int.
Perhaps someone did not want to disable some TRI-STATE digital logic in the beginning, and since then nobody wanted to change the basics.
But of course bool is a more appropriate data type for HIGH/LOW and of course you can always treat them this way, for example like
if (! digitalRead(pin) ) { // pin is LOW
   ...
}

jsotola's answer why Serial.read() returns  an int is a different issue. And correct of course.

The smallest unit in most languages is a byte (8 bits), whether signed or unsigned.
So returning a byte, even if it only returns three different values, is the smallest and most efficient unit available, that I'm aware of.
If you want to store later, you can assign each bit of a byte as a high or low, thus giving you 8 storage spots.

One could always store the value of digitalRead() as a bit in a variable, compacting the data from say 8 pins down into 1 byte
// read an input and store it, say the reads of D2 thru D9 are stored in byte bits9to2
// 9,8,7,6,5,4,3,2
// first clear the state for 2
bits9to2 = bits9to2 && 0b11111110; // two && for bit manipulation? Or just 1?
// then map in the new value
if (digitalRead(D2) == HIGH){
bits9to2 = bits9to2 || 0b00000001;// two || for bit manipulation? Or just 1?
}
else{
// leave it as 0
}

Then to use it later on:
if ((bits9to2 && 0b00000001) != 0){
// bit is set (HIGH), do whatever
}
else {
// bit is clear (LOW), do whatever, or maybe do nothing
}

Can use an unsigned int and store 16 bits compacted that way, or unsigned long for 32 bits.


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:
How to transfer serial data or plot wirelessly on an arduino?
I have an arduino uno and an accelerometer connected reading vibrations. I want to be able to send the serial data or serial plot wirelessly from the arduino to any program(recommendations will be considered) on the pc without using the USB port on the pc. Is it possible?
I have an arduino ethernet shield, bluetooth modules HC-05 and HC-10 all at hand if they will be helpful.
please help, any help would be greatly appreciated.

serial plot is just serial data .... google is your friend ... find a tutorial about the Arduino and HC-05

so i gave the arduino an ip address through the ethernet shield and it is reading the data when i type in the ip address in my computer, now I just need a way how to plot this data and I think I need a database for that kind of work. Any suggestions on how to do this.

you want to collect data and then draw a chart it in a spreadsheet offline? with HC-05 you could draw realtime in the IDE Serial Plotter

yes i want to collect data and then draw it in a spreadsheet offline, realtime plotting would also be a great add on.

paired HC-05 creates a COM port which you can select in Arduino IDE and use it with Serial Monittor/Plotter

actually i cant use the bluetooth modules anymore, do you know anything about wonderware?

so which part should be wireless? the communication with the sensor or the communication with PC or both?


text:
arduino atmega32u4 beetle extract hex code
I made a program using the Arduino Atmega32U4.
As a security issue, I tried to extract the hex code because I wanted to know if this program was duplicated.
avrdude -C"\avrdude.conf" -v -V -patmega32u4 -carduino -PCOM15 -b9600 -D -Uflash:w:C:\test\sketch_jun07b.ino.hex:i
This is what I executed in Command Line.
Avrdude ended with the following error: avrdude: stk500_getsync () attempt 1 of 10: not in sync:
Can you tell me if there is no risk of extracting and duplicating hex code from beetle or chipset unlike arduino board?

what does the error message mean?

it is unclear what you are asking ... what do you mean by unlike arduino board?   ... what kind of risk are you talking about?

I know that I can extract hex code from the Arduino board, is this information wrong? I'm trying it and that's the biggest risk

yes you can read the content of memory .... i suggest that you investigate the error message before you go further .... you still have not said what risk you are talking about

Launched Arduino USB type product.
I don't want this product duplicated, so I've run a hex code extraction beforehand.
Connecting to programmer: .. Now I face to face this error... TT

What programmer? Connected via ISP I suppose? You would probably want -c stk500v1in that case. Also, -U flash:w:xyz:i tries to write a hex file to your device, with xyz being the path. You'd want that to be -U flash:r:xyz:i

Just set a lock bits properly and it won't be so easy to read out the flash.


text:
Two Servo motors don't work as required (Arduino Mega 2560)
Can anyone help me with the following codes? I have attached sensors to detect either plastic or metal materials. If the sensor detected a metal, the first servo will rotate at least 90 degrees. If not, it will not rotate. If its a plastic material, the other servo will do the same. Kindly consider the following codes.
// Include Libraries
#include "Arduino.h"
#include "Button.h"
// Pin Definitions
#define REFLECTIVEIR_PIN_COLL  A1
#define REFLECTIVEIR_PIN_COLL_M  A3
// object initialization
Button ReflectiveIR(REFLECTIVEIR_PIN_COLL);
Button ReflectiveIR_M(REFLECTIVEIR_PIN_COLL_M);
// define vars for testing menu
const int timeout = 10000;       //define timeout of 10 sec
char menuOption = 0;
long time0;

#include <Servo.h>
#define redpin 2
#define bluepin 3
#define greenpin 4
#define redpin_M 5
#define bluepin_M 6
#define greenpin_M 7
int metalsensor = A0;
int metalsensor_M = A2;
int plasticsensor = A4;
//int anothersensor = A2;

Servo myservo;  // create servo object to control a servo
Servo myservo_M;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 165;    // variable to store the servo position
int pos_M = 158;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo_M.attach(10);  // attaches the servo on pin 9 to the servo object
  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  //metal sensor
  pinMode(redpin_M, OUTPUT);
  pinMode(bluepin_M, OUTPUT);
  pinMode(greenpin_M, OUTPUT);

  pinMode(metalsensor, INPUT_PULLUP);
  pinMode(metalsensor_M, INPUT_PULLUP);
  pinMode(plasticsensor, INPUT_PULLUP);
  //  pinMode(anothersensor, INPUT_PULLUP);
  Serial.begin(9600);
  analogWrite(redpin, 255);
  analogWrite(bluepin, 255);
  analogWrite(greenpin, 255);
  analogWrite(redpin_M, 255);
  analogWrite(bluepin_M, 255);
  analogWrite(greenpin_M, 255);
  //ReflectiveIR.init();
  //ReflectiveIR_M.init();
}

void loop() {

  int sensor_read_m = digitalRead(metalsensor);
  int sensor_read_mm = digitalRead(metalsensor_M);
  int sensor_read = digitalRead(plasticsensor);
  Serial.println("metal sensor");
  Serial.println(sensor_read_m);
  Serial.println(sensor_read_mm);
  Serial.println("plastic sensor");
  Serial.println(sensor_read);

  bool ReflectiveIR_Val = ReflectiveIR.read();
  bool ReflectiveIR_Val_M = ReflectiveIR_M.read();
  //Plastic bin
  if ((sensor_read == 0) && (sensor_read_m != 1)) {
    for (pos = 160; pos >= 90; pos -= 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 15ms for the servo to reach the position
    }
    analogWrite(redpin, 255);
    analogWrite(bluepin, 0);
    analogWrite(greenpin, 255);
    delay(2500);
    for (pos = 90; pos <= 160; pos += 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 15ms for the servo to reach the position

    }
    analogWrite(redpin, 0);
    analogWrite(bluepin, 0);
    analogWrite(greenpin, 0);

  }

  else if (ReflectiveIR_Val == 1) { //checking the volume of the trash
    analogWrite(redpin, 0);
    analogWrite(bluepin, 255);
    analogWrite(greenpin, 255);

  }

  else {
    // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    // waits 15ms for the servo to reach the position

    analogWrite(redpin, 255);
    analogWrite(bluepin, 255);
    analogWrite(greenpin, 255);

  }

  //metal sensor

  if (sensor_read_mm == 1) {
    for (pos_M = 160; pos_M >= 90; pos_M -= 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo_M.write(pos_M);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 15ms for the servo to reach the position
    }
    analogWrite(redpin_M, 255);
    analogWrite(bluepin_M, 0);
    analogWrite(greenpin_M, 255);
    delay(2500);
    for (pos_M = 90; pos_M <= 160; pos_M += 1) { // goes from 180 degrees to 0 degrees
      myservo_M.write(pos_M);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 15ms for the servo to reach the position

    }
    analogWrite(redpin_M, 0);
    analogWrite(bluepin_M, 0);
    analogWrite(greenpin_M, 0);

  }

  else if (ReflectiveIR_Val_M == 1) {
    analogWrite(redpin_M, 0);
    analogWrite(bluepin_M, 255);
    analogWrite(greenpin_M, 255);

  }

  else {
    // goes from 180 degrees to 0 degrees
    myservo_M.write(pos_M);              // tell servo to go to position in variable 'pos'
    // waits 15ms for the servo to reach the position

    analogWrite(redpin_M, 255);
    analogWrite(bluepin_M, 255);
    analogWrite(greenpin_M, 255);

  }

}

Thank you for the help.

The servo don't respond to any type of material (plastic or metal). Can you help me solve this? Thank you in advance.

You're absolutely right. I can't figure out how it would work using the sensors that will make the servo response. Can you help me find the correct codes to make it work? Thank you.

your code right now is read sensor ... if metal then flash LEDs and move servo   .... do instead at beginning of loop() read sensor ... if metal then set flag  (metal=true) .... further down in loop() if metal then move servo .... if metal then flash leds   ..... that way everything is separated and you can easily print debugging info about the state of flags

Thanks. I would try to change the codes according to what you suggest. I'll get back later for updates.

start with the detect code .... forget about servos and leds .... well maybe use the led to indicate detection of material and another led to indicate type of material

I really can't figure out which of the codes I will change or modify. It would be greatly appreciated If you don't mind changing it for me. I am new to this. Some codes were taken from online sources. I understand what you mean but I find it hard for me to figure out which specifically I will change. Thanks for the help.

start by commenting out all code in loop() except the first 8 lines .... see what values get printed for each of the materials that you want to detect .... slow down the loop() by including delay 200; before end of loop()

The detection creates loops continuously even nothing is detected. The servo for metal sensor rotates back and forth. I really don't know how to change the codes to make it right. Could you please fix it for me? I am new to Arduino coding.

you are the only one who can figure out if the sensors are working and what data values the sensors produce ... it is not possible to write the code to do something without knowing what the inputs are

Thanks for the help. I really appreciate it. But, anyway, I will try to find it out how to make it work the way it is suppose to.

like i said before, get the detection code working first ..... if you cannot differentiate between metal and plastic, then it is pointless to write code for the servos .... good luck with your project


text:
How to send NEO6M gps data to firebase?
I'm using nodemcu and neo6m gps module. I can't send data to firebase. As a library using tinygps++. Can anyone please help me how can i pass data to firebase.
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>
#include "TinyGPS++.h"
#include "SoftwareSerial.h"

// Set these to run example.
#define FIREBASE_HOST "vessel-monitoring-a21f4.firebaseio.com"
#define FIREBASE_AUTH "EYUZc64JyLMR5cbJc99nZzjah8uwEDxSp3m93Lvr"
#define WIFI_SSID "H17"
#define WIFI_PASSWORD "pass@router"

//GPS
SoftwareSerial serial_connection(4, 0); //tx,rx
TinyGPSPlus gps;// GPS object to process the NMEA data

float latt, lngg;

void setup() {
  Serial.begin(9600);
  serial_connection.begin(9600);
  // connect to wifi.
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
}

void loop() {
    while (serial_connection.available()) {
      gps.encode(serial_connection.read());
    }
    if (gps.location.isUpdated()) {
      latt = gps.location.lat();
      lngg = gps.location.lng();
      Serial.println(latt, 6);
      Serial.println(lngg, 6);
      delay(1000);
    }
    char location_str[25]={0};
    sprintf(location_str, "%f, %f", latt, lngg);
    String name = Firebase.push("location", location_str);
    if (Firebase.failed()) {
      Serial.print("setting /location failed:");
      Serial.println(Firebase.error());
      return;
    }
    delay(1000);
}

Please show the code you have problems with, and tell us something about what goes wrong.

I update the code in the post. The problem is I got 0 value for lat, lng in firebase. Sometimes it provides the correct value in firebase(the ratio is too low).

With Firebase.push you add a new location to the "location"-collection with every call. Is that, what you intended to do?  If you just want to set a string to the location attribute use Firebase.setString("location", location_str);. It would also be a good idea to move the code that writes into the Firebase into the if (gps.location.isUpdated())  block. IMHO You only have to write into the Firebase if the location has been changed. Btw I would understand the behavior of the code better, if I'd know whether the Serial.println(latt, 6); and Serial.println(lngg, 6); prints out someth.

I don't understand more about your comment. Can you please help me to arrange the code, where i can store lat, lng in firebase database with nodemcu.


text:
How to extract fingerprint template from Arduino Fingerprint Sensor
How to extract fingerprint template from Arduino Fingerprint Sensor and store it to SD card module using adafruit library and then search/import it from SD card module when tapping the fingerprint?
Can anyone give me hope to this project I am starting to feel stressed and depressed.
I'm using Arduino R307 and AS601 fingerprint modules.
here is the code:
    #include <SPI.h>
    #include <SD.h>
    #include <SoftwareSerial.h>
    #include <Adafruit_Fingerprint.h>

    SoftwareSerial mySerial(2, 3);

    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

    uint8_t id;
    String userName;
    uint8_t isProfessor;
    char *myFileName = "acct.txt";
    File myFile;

    void setup()
    {
      Serial.begin(9600);
      while (!Serial);  // For Yun/Leo/Micro/Zero/...
      delay(100);
      Serial.println("\n\nAdafruit Fingerprint sensor enrollment");

      Serial.print("Initializing SD card...");
      if (!SD.begin(4)) {
        Serial.print("initialization failed!");
        while (1);
      }
      Serial.print("initialization done.");

      // set the data rate for the sensor serial port
      finger.begin(57600);

      if (finger.verifyPassword()) {
        Serial.println("Found fingerprint sensor!");
      } else {
        Serial.println("Did not find fingerprint sensor :(");
        while (1) {
          delay(1);
        }
      }
    }

    uint8_t readnumber(void) {
      uint8_t num = 0;

      while (num == 0) {
        while (! Serial.available());
        num = Serial.parseInt();
      }
      return num;
    }

    void loop()                     // run over and over again
    {
      Serial.println("Ready to enroll a fingerprint!");
      Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
      id = readnumber();
      if (id == 0) {// ID #0 not allowed, try again!
        return;
      }
      Serial.print("Enrolling ID #");
      Serial.println(id);

      while (!getFingerprintEnroll() );
    }

    void writeReadSDCard(){

        delay(2000);
        // open the file. note that only one file can be open at a time,
        // so you have to close this one before opening another.
        myFile = SD.open(myFileName, FILE_WRITE);
        // if the file opened okay, write to it:
        if (myFile) { //if myFile is open, you can write
          Serial.print("Writing to "); Serial.println(myFileName);
          //myFile.print(id); myFile.print(","); myFile.print(userName); myFile.print(","); myFile.println("Professor");
          myFile.print(id); myFile.print(","); myFile.println(userName);
          // close the file:
          myFile.close();
          Serial.println("done.");
        } else {
          // if the file didn't open, print an error:
          Serial.print("error opening when writing on "); Serial.println(myFileName);
        }

        delay(2000);

        // re-open the file for reading:
        myFile = SD.open(myFileName);
        if (myFile) {
          Serial.print("Reading SD Card file named "); Serial.println(myFileName);

          // read from the file until there's nothing else in it:
          while (myFile.available()) {
            Serial.write(myFile.read());
          }
          // close the file:
          myFile.close();
          Serial.flush(); // wait for last transmitted data to be sent

        } else {
          // if the file didn't open, print an error:
          Serial.println("error opening for reading");   Serial.print(myFileName);
        }
    }

    uint8_t getFingerprintEnroll() {

      int p = -1;
      Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
          case FINGERPRINT_OK:
            Serial.println("Image taken");
            break;
          case FINGERPRINT_NOFINGER:
            Serial.println(".");
            break;
          case FINGERPRINT_PACKETRECIEVEERR:
            Serial.println("Communication error");
            break;
          case FINGERPRINT_IMAGEFAIL:
            Serial.println("Imaging error");
            break;
          default:
            Serial.println("Unknown error");
            break;
        }
      }

      // OK success!

      p = finger.image2Tz(1);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      Serial.println("Remove finger");
      delay(2000);
      p = 0;
      while (p != FINGERPRINT_NOFINGER) {
        p = finger.getImage();
      }
      Serial.print("ID "); Serial.println(id);
      p = -1;
      Serial.println("Place same finger again");
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
          case FINGERPRINT_OK:
            Serial.println("Image taken");
            break;
          case FINGERPRINT_NOFINGER:
            Serial.print(".");
            break;
          case FINGERPRINT_PACKETRECIEVEERR:
            Serial.println("Communication error");
            break;
          case FINGERPRINT_IMAGEFAIL:
            Serial.println("Imaging error");
            break;
          default:
            Serial.println("Unknown error");
            break;
        }
      }

      // OK success!

      p = finger.image2Tz(2);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      Serial.print("Creating model for #");  Serial.println(id);

      p = finger.createModel();
      if (p == FINGERPRINT_OK) {
        Serial.println("Prints matched!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_ENROLLMISMATCH) {
        Serial.println("Fingerprints did not match");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }

      Serial.print("ID "); Serial.println(id);
      p = finger.storeModel(id);
      if (p == FINGERPRINT_OK) {
        Serial.println("Stored!");

        delay(10000);

          userName = Serial.readString();// read the incoming data as string
          Serial.println(userName);

          writeReadSDCard();

      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_BADLOCATION) {
        Serial.println("Could not store in that location");
        return p;
      } else if (p == FINGERPRINT_FLASHERR) {
        Serial.println("Error writing to flash");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }
    }

Here is the result:

I hope someone can answer my question.

Directly related to this question

I don't think, that the library allows you to extract the template or model of a fingerprint. I even haven't seen such a function in the manual of the Adafruit Sensor. Only functions for getting the read image. So I guess you technically cannot get the template

what should I do?

What I wrote in my answer to your other question. Yes, that is no easy solution, but when you cannot find a library, that already implements the needed feature, you need to write that yourself. Or you need to rethink your project, so that you don't need this feature.


text:
How many output pins do NodeMCU have?
I am trying to build a Smarthome system with NodeMCU.
NodeMCU would wire up with relays.
How many replays can one NodeMCU control?

It depends how many shift registers or IO expanders you are willing to use.

Juraj I know, but I don't know the get those GPIOs things.
Can you give me a short answer?


text:
Using DHT11 and EMF - Lag issue
The code is working but there is a delay when the LED turns on and off (physically). Is there a more efficient way I could write this code? I assume it is the delay in reading the DHT11 causing it.
~Issue resolved

Don't have a delay?

there is one, physically, when the LED lights up and turns off.

I don't know what you mean by "physically", but there is a delay in your code. Remove it, and if you need parts of your code to run slower, use millis() to determine when they should run.

Please leave the original question intact so others can benefit from your question and its solution.

Your question is a bit unclear (A delay is defined by two points in time or one point and a duration -- you only tell us one point).
Reading your code, I can only assume that you mean that an external event on inPin is delayed in showing up on the LED on pin11. This should come up when that external event is emitted just at the beginning of your delay(1000) (and is therefore randomly delayed between 0 and 1000ms).
You could get rid of the delay in your loop using a bit of timer math around the DHT11 reading code:
#define DHT11_SAMPLE_DELAY = 1000
uint32_t last_dht11_reading_ms = 0;

void loop() {
  uint32_t current_ms = millis();

  if( current_ms - last_dht11_reading_ms > DHT11_SAMPLE_DELAY ) {

    DHT.read11(dht_apin);
    Serial.println("....your output....");

    last_dht11_reading_ms = current_ms;
  }
  // also, remove the delay(1000) in your loop()
}

You get the current time (millis() gives you the uptime since boot in milliseconds) and subtract the time of last reading. If the result is bigger than a threshold (in this case: 1000 ms), you do a new reading of the DHT11 while setting the variable containing the time of last reading to the current time. When the loop() comes around again, the threshold will not be reached, so reading the DHT11 value is skipped until millis() returns a sufficiently big number again.

@RobE If you did copy my error in the DHT.read11() call, then I can see why... if you didn't, I'd be very surprised ^^ (Fixed the errorneous call. It should be the same line as in your original code.)

Updated the code, now the temp sensor never reads. I must have done something wrong. I updated the code above in the OP.

@RobE Nice to see that your issue has been resolved, but could you please leave the question here so others can find the solution? The intended way here on Stackoverflow is to keep everything readable, so others won't have to ask the same question again. Instead of removing the question, please mark an answer as correct.


text:
Missing ArduinoJson/DynamicJsonBuffer.hpp
I have read other posts regarding ArduinoJson that recommend using a library version no later than 5.14.3.  That recommendation is more than a year old - is it still the recommended library version?

I have only ever used ArduinoJSON 6 and never had any problems with it. Unless you need version 5 for compatibility with some old system then I would say use 6.

version 6 breaks backward compatibility so you can't upgrade from 5 to 6 without migrating all sketches to classes of version 6 of the library. (or using some workaround by having the version 5 of the library in a renamed folder)


text:
Send large files to API via HTTP
I am making a stream-based radio clock that needs to send snippets of the stream to an external API for music recognition using an ESP-WROOM-32 DevKit.
The snippets that I record are 15 seconds long, which results in a file ~2MB in size (assuming the stream is 128Kbps, MP3). If I try to buffer this in the ESP32's RAM, it will fill it up in no time.
How can I send that snippet via HTTP without overflowing the ESP's RAM?

Use one of the ESP32s with the 8MB PSRAM?

Can't you stream the snippets? If you can, then you don't need to store them.

i don't like shying away from a challenge, but this is more apt for an SBC than an MCU.


text:
Issue with incrementing PWM over time
First post here. So I have an issue, which I have identified, but I'm not quite sure how to fix it.
I'd really appreciate some input and suggestions.
I realize that my "pwmDelta" is the problem, but I am not sure what to do to fix it.
I am trying to write a program that will increment the value of the pin 3 a set amount of time, in a somewhat linear fashion, starting at my low point, and finishing at my high point.
The issue is that my equation is incorrect and I can't output a partial bit value. Huge oversight on my part. If you read the data from the serial monitor with the code written as I have it, you'll see that it isn't coming even close to reaching my max value.
I need suggestions on how I can have the program figure out the delta in a way that I can send an integer value to the PWM output pin, yet still keep a somewhat linear increase over time. Would this even be possible?
int motor1 = 3;         //pin for PWM output to motor
float t = 0;            //Variable to keep Track of time
int tLim = 30;          //Time Limit for Ramp
float lowLim = 21;      //Low Limit, in Duty Cycle %
float highLim = 65;     //High Limit, in Duty Cycle %
float motorPWM = 53.55; //Starting Value of PWM, in Bits
float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim); //Delta equation, to calculate how much to change PWM value each time it is incremented
float motorDelta;       //Variable to write value to Motor Output

void setup() {
  pinMode(motor1, OUTPUT);
  analogWrite(motor1, 53.55); //run motor at initial value for 20 seconds before beginnning ramp
  delay(20000);
  Serial.begin(9600);
}

void loop() {
  motorDelta = motorPWM + pwmDelta; //incrementing output value based on Delta Equation
  motorPWM = motorDelta; //Setting new incremented value equal to old value, so incrementing can continue

  if (t <= tLim) {  //Check if time is <= time limit
    analogWrite(motor1, (motorDelta)); //write incremented value to output pin
    delay(1000);  //wait 1 second, increment t, to keep track of time
    t++;
  }
  else {
    analogWrite(motor1, motorPWM = 165.75); //set pin to high value for 60 seconds, then set to 0
    delay(60000);
    analogWrite(motor1, motorPWM = 0);
  }
  Serial.print(motorDelta);
  Serial.println();
  Serial.print(t);
  Serial.println();
}

think about this .... what other parameter can you vary?

@jsotola The 255/100 needs to be constant, as that gives me 2.55 bits per 1 Duty Cycle percent. Any of the other parameters in the pwmDelta can be varied, and it's designed to be as such. So when it's finished a user can input the Low/High Limit in Duty Cycle % and time, and the output will increase in a linear fashion over that time period. If you mean other parameters outside of that equation, I guess I am not following.

float pwmDelta=((255/100)*(highLim-lowLim))/(tLim);

That line should be:
float pwmDelta=((255.0/100)*(highLim-lowLim))/(tLim);

Adding the .0 tells the compiler to do that math using floats and you get 2.55.  Without it the math is done with int and the result is 1 which isn't what you want.
analogWrite(motor1, 53.55);

Just write 54.  analogWrite only accepts integer values.
analogWrite(motor1, motorPWM=165.75);

You should really do that as two lines, an assgnment and then an analogWrite.  This way leads to confusing code.  Also, analogWrite only accepts integer values so your decimals are useless there as well.

analogWrite(motor1, 53.55) outputs 53: float to int conversions do not round, they just truncate the fractional part.

You're right.   But I figured 54 would be closer to what he actually wanted because I rounded.  I was suggesting that he use 54 not that analogRead would treat his float as 54.

You are trying to smoothly ramp up the PWM value from 21% to 65% over a period of 30 seconds at 1 second intervals, which does not work very well because the PWM value has to be a byte.
That means that the value written into the PWM register changes from  21*255/100  to 65*255/100, which is 53.55 to 165.75.
Use values of 53 and 166, which gives a difference of 113.
Your code is written to update the PWM value every 1000 ms, which produces 30 steps, most of which are not integers.
Instead, ramp up the PWM value in 113 steps. Each step will be an integer and each step will be 265486 μs in length.

The previous responses already showed the main issue with the program.
Here I am providing a few suggestions that hopefully could still improve
it:

Instead of using delay(), you could manage the time with
millis(). This will make the ramp smoother, and you will be able to
add code to the loop if needed that will not be blocked by the
delays.
Storing the times in milliseconds and the PWM value in its natural
unit (rather than percent) makes the code simpler.
Remove redundant variables, such as motorDelta, which is the same
as motorPWM.
Consistent indentation and removal of superfluous parentheses help
the readability.

Here is my attempt at implementing those suggestions:
const int motor1 = 3;  // pin for PWM output to motor
const unsigned long tLim = 30000;  // duration of the PWM ramp
const float PWM_unit = 255.0/100;  // convert percent to PWM scale
const float lowLim = PWM_unit * 21;
const float highLim = PWM_unit * 65;
const float PWM_rate = (highLim-lowLim) / tLim;

unsigned long start_time;  // start of the ramp
int previousPWM = 0;

void setup() {
    pinMode(motor1, OUTPUT);
    analogWrite(motor1, round(lowLim));
    delay(20000);
    Serial.begin(9600);
    Serial.println(" t   PWM");
    Serial.println("--------");
    start_time = millis();
}

void loop() {
    unsigned long t = millis() - start_time;

    if (t >= tLim) {  // we are done
        analogWrite(motor1, round(highLim));
        delay(60000);  // keep at highLim for 60 s
        analogWrite(motor1, 0);  // then stop
        exit(0);
    }

    int motorPWM = round(lowLim + t * PWM_rate);
    if (motorPWM != previousPWM) {
        analogWrite(motor1, motorPWM);
        Serial.print(t / 1000.0);
        Serial.print("  ");
        Serial.println(motorPWM);
        previousPWM = motorPWM;
    }
}

This helps tremendously. Thank you so much. I'll check it out later. It will be a part of a much larger program designed to replace a motor controller, with a much more functional one, so the delay would certainly cause issues with it. For the time being, I was just trying to see if I could make it work, and it wasn't working. This code was never intended to be long term, but I will definitely take your suggestions into consideration when it comes time to implement the code into the rest of the controller.

What's happening is that you've written a fraction in a way that the compiler treats it as integer math. C/C++ truncate fractions, so 255/100 is just 2 (and if any of the rest of those are integers, they cause truncation too). What you want to do is make some number in that calculation a decimal--it doesn't matter which one--or cast an input to a float with (float) somevariable.
As long as that's all on one line, all of the calculations involved (excepting order of operations, so cast to float one of the variables being divided if you have them in separate parenthesized terms) will be in floating point. Do note that if you set the value of an integer with this, it will only truncate after doing the math accurately, too, so it's more correct.
float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim);
Should be:
float pwmDelta = 2.55*(highLim-lowLim)/(float)tLim;
(This also makes it all one term.)


text:
Error 'exec: "python": executable file not found in $PATH Error compiling for board AI Thinker ESP32-CAM.' in Arduino IDE 1.8.12
I am trying to upload a sketch to the ESP32-CAM board using Arduino IDE 1.8.12 and I get an error message:
exec: "python": executable file not found in $PATH
Error compiling for board AI Thinker ESP32-CAM.

My OS is Ubuntu 18.04.4.LTS.
When I type python in the console, it does open python:
$ python
Python 2.7.17 (default, Nov  7 2019, 10:07:09)
[GCC 7.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
KeyboardInterrupt
>>>

Also python is in one of the directories referenced by PATH:
$ which python
/usr/bin/python
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

I added an additional URL referring to the ESP32 boards on the Espressif website:
Arduino IDE > File > Preferences > Settings > Additional Boards Manager URLs: > https://dl.espressif.com/dl/package_esp32_index.json

Then I added the libraries for all ESP32 boards:
Arduino IDE > Tools > Board > Boards Manager > esp32 version 1.0.4

(I tried with version 1.0.3 and it didn't change anything...)
I selected my board in the interface:
Arduino IDE > Tools > Board > AI Tinker ESP32-CAM

I granted all permissions to the USB port:
sudo chmod a+rwx /dev/ttyUSB0
ls -la /dev/ttyUSB0
crwxrwxrwx 1 root dialout 188, 0 Mar  4 21:25 /dev/ttyUSB0

My sketch is really simple:
void setup() {
}

void loop() {
}

I get the same error for any example sketch and for any ESP32 board.
Any idea how this could be fixed ?

All right so I was able to fix the problem. The Arduino IDE I was using had been installed from the Ubuntu Software Center. I uninstalled it.
Then I reinstalled the Arduino IDE by downloading it from the www.arduino.cc website and doing a manual install in /opt. Now it works awesome.

Good, that you solved the problem. You can mark your answer as correct, so that other can see, that this problem is solved.

This was an issue with the old Arduino IDE snap on Ubuntu. You can easily fix this by installing the new arduino snap:
snap install arduino

Then add your user to the dailout group:
sudo usermod -a -G dialout $USER

After this, reboot your device and open Arduino IDE.
Installing additional libraries
The Arduino IDE snap runs inside of a sandbox for security and stability reasons. This means it cannot access the Python libraries on your device. The snap bundles Python 3 and the serial library. If you need any other Python dependencies, you can install them inside of the sandbox using the arduino.pip command.
arduino.pip install <package-name>

Note: do not use sudo for this command


text:
Getting wdt reset + reboots every 5 seconds on simple button/relay code that has worked previously, now it does not and I changed nothing
I have some arduino code I adapted from a simple 2 button 2 relay code I found online. I just multiplied everything so I could have 5 buttons/5relays. I am using a NodeMCU (ESP-12E) for this.
I have not changed anything, and now trying to upload it to other boards, and the same existing board I used before. Same results every time.
I have verified arduino is updated, the board manager link is up to date, and verified the code. Drivers re-installed. I have tried using different boards such as nodemcu 0.9, generic esp8266 module etc.
Code is verified, no error messages upon upload.
But every single time I get this error in the serial monitor over and over:

 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

And here is the code I am using:
(But please keep in mind this WORKS and has worked before)
//Buttons

int button1 = 4;
int button2 = 13;
int button3 = 12;
int button4 = 15;
int button5 = 10;

//Relays
int rl1 = 5;
int rl2 = 0;
int rl3 = 14;
int rl4 = 16;
int r15 = 9;

//States for Relay and Button (1)

int state1 = HIGH;      // the current state of the output pin
int reading1;           // the current reading from the input pin
int previous1 = LOW;    // the previous reading from the input pin

//States for Relay and Button (2)

int state2 = HIGH;      // the current state of the output pin
int reading2;           // the current reading from the input pin
int previous2 = LOW;    // the previous reading from the input pin

//States for Relay and Button (3)

int state3 = HIGH;      // the current state of the output pin
int reading3;           // the current reading from the input pin
int previous3 = LOW;    // the previous reading from the input pin

//States for Relay and Button (4)

int state4 = HIGH;      // the current state of the output pin
int reading4;           // the current reading from the input pin
int previous4 = LOW;    // the previous reading from the input pin

//States for Relay and Button (5)

int state5 = HIGH;      // the current state of the output pin
int reading5;           // the current reading from the input pin
int previous5 = LOW;    // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time1 = 0;          // the last time the output pin was toggled
long time2 = 0;
long time3 = 0;
long time4 = 0;
long time5 = 0;

long debounce1 = 60;   // the debounce time, increase if the output flickers
long debounce2 = 60;
long debounce3 = 60;
long debounce4 = 60;
long debounce5 = 60;

void setup()
{
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);

  pinMode(rl1, OUTPUT);
  pinMode(rl2, OUTPUT);
  pinMode(rl3, OUTPUT);
  pinMode(rl4, OUTPUT);
  pinMode(r15, OUTPUT);

}

void loop() {

  reading1 = digitalRead(button1);
  reading2 = digitalRead(button2);
  reading3 = digitalRead(button3);
  reading4 = digitalRead(button4);
  reading5 = digitalRead(button5);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  //Condition Relay 1
  if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
    if (state1 == HIGH)
      state1 = LOW;
    else
      state1 = HIGH;

    time1 = millis();
  }

  //Condition Relay 2
    if (reading2 == HIGH && previous2 == LOW && millis() - time2 > debounce2) {
    if (state2 == HIGH)
      state2 = LOW;
    else
      state2 = HIGH;

    time2 = millis();
  }

  //Condition Relay 3
    if (reading3 == HIGH && previous3 == LOW && millis() - time3 > debounce3) {
    if (state3 == HIGH)
      state3 = LOW;
    else
      state3 = HIGH;

    time3 = millis();
  }

  //Condition Relay 4
    if (reading4 == HIGH && previous4 == LOW && millis() - time4 > debounce4) {
    if (state4 == HIGH)
      state4 = LOW;
    else
      state4 = HIGH;

    time4 = millis();
  }

  //Condition Relay 5
    if (reading5 == HIGH && previous5 == LOW && millis() - time5 > debounce5) {
    if (state5 == HIGH)
      state5 = LOW;
    else
      state5 = HIGH;

    time5 = millis();
  }

  digitalWrite(rl1, state1);
  digitalWrite(rl2, state2);
  digitalWrite(rl3, state3);
  digitalWrite(rl4, state4);
  digitalWrite(r15, state5);

  previous1 = reading1;
  previous2 = reading2;
  previous3 = reading3;
  previous4 = reading4;
  previous5 = reading5;
}

If I google this error I get a myriad of results that so far have not helped me. Any help or insight on how I can better understand this error, where to start, and what I need to do to get this "simple" sketch working would be awesome.  I'm at my wits end and all I want is a simple lighting panel to work.

that looks like a status message, not an error message

But with this, it reboots over and over and shows the message each time.

that does not mean that it is an error message .... it may be boot status messages ... looks like the chip is in a wrong state ... could be something wrong with your breadboard, if you are using one ... or the watchdog timer is set incorrectly

I think it is a brown out

Did it ever work with 5 relays?

@orithena yes it did. i changed gpio9 to gpio2 and now it stopped rebooting every 10 seconds.

io 9 is used by the QIO to flash memory

For anyone that has a similar issue, I figured it out. GPIO 9 could not be used for a relay/output for whatever reason. Wish I knew why.  Switched it to GPIO2 (D4) and the reboots stopped.

Pins 6-11 on most NodeMCUs are used for connecting the on-board SPI Flash memory and are not recommended for use as general I/O pins.

@starcat I understand that but I just find it strange pin 9 worked in the past, nothing changed, then now it magically doesn't.

@Coltography Found the culprit. GPIO9 and GPIO10 are not usable on boards that use Quad-IO Flash SPI access (which needs 4 data lines instead of 2 on Dual-IO Flash). It seems that some NodeMCU boards do use DIO, some other use QIO -- and on those QIO boards, messing with the Flash SPI pins seem to trigger the watchdog, which then reboots the chip. Here's the schematics with commentary on GPIO9: https://www.esp8266.com/wiki/lib/exe/fetch.php?media=schematic_esp-12e.png -- and here's the issue in the Arduino ESP8266 core: https://github.com/esp8266/Arduino/issues/1446

First thing to realize for you is that the externally set status of three of the GPIO pins determine the boot mode for the ESP8266 used on your NodeMCU. So you must take care to check that your external wiring will not interfere with the boot mode:

GPIO15/D8 must be LOW on boot (i.e. no external pull-up resistors may be connected between D8 and 3.3V)
GPIO2/D4 must be HIGH on boot (i.e. no external pull-down resistors may be connected between D4 and GND)
GPIO0/D3 must be free of pull-up/down resistors so that the USB-to-serial chip can switch between RUN and FLASH mode.

Also, holding GPIO16/D0 LOW for an extended amount of time while running may have unintended side effects like triggering the watchdog, especially if the board manufacturer decided to add the deep sleep wakeup resistor between D0 and RST (you most certainly have a NodeMCU clone, so this might actually be possible).
So it might very well be that you need to reverse the button logic on GPIO15/D8 (i.e. connect the button between D8 and 3.3V). It also might be that the pin numbering on your NodeMCU is confusing; better use the D0-D10 constants.
Depending on the type of your relays, your relays may act as a pull-up/down resistor, too, further adding to the confusion.
I'd try this sketch without anything connected (no buttons, no relays) and when it works, I'd add buttons and relays one by one until you find the culprit. Sometimes it might be sufficient to swap a relay and a button, sometimes you need to reverse the logic on a button.
I would say that using any ESP8266 with that many input/output lines requires very careful consideration on where to connect what. The GPIO pins on an Arduino Nano are not involved in boot mode nor watchdog, so at least there you'd not get any interference.

Hello, thank you for the detailed response.  I do not have anything attached to the nodemcu so that unfortunately rules out any of the gpio issues.
What I don't get is how this exact code is on another nodemcu with no issues, but I've uploaded it to 3+ other boards and gotten this constant crash/boot cycle now.

According to Esp8266 documentation this is a software reset.
After a fast peek, I didn't find delay() or yield() in your code.
The esp8266 needs to attend some time to WiFi related background tasks, and it is does when your arduino code delays or yields the processor.

i was going to suggest adding a sleep(1). great minds think alike...

AFAIK a yield() is implicit in every repetition of loop()

Why would this work on another nodemcu without that, though? And where would I put the delay() part of the code?