text:
Arduino Mega 2560 + ESP8266 Problem with GET Request
I have an ESP8266 module connected to my Arduino Mega 2560. My goal is to send a GET request as below to the network:
api.pushingbox.com/pushingbox?devid=vEB39F555B1B8295?tempData=cabbages

If that is successful, I will get the string "cabbages" along with the timestamp inside my Google Sheets. Note that I intend to change the string "cabbages" with many other data once this is working, but for now, just cabbages. Pasting the link above inside a web browser and pressing Enter seems work fine, but doing it automatically from inside Arduino with ESP8266 attached is somehow not as I expected.
After connecting to my home wifi I tried making a GET request to Google.com:
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);

  delay(3000);
  Serial2.write("AT\r\n");
  delay(3000);
  Serial2.write("AT+CWMODE=1\r\n");
  delay(3000);
  Serial2.write("AT+CIPMUX=0\r\n");
  delay(3000);

  Serial2.write("AT+CIPSTART=\"TCP\",\"www.google.com\",80\r\n");
  delay(500);
  Serial2.write("AT+CIPSEND=80\r\n");
  delay(500);
  Serial2.write("GET / HTTP/1.0\r\n");
  delay(500);
  Serial2.write("User-Agent: curl/7.37.0\r\n");
  delay(500);
  Serial2.write("Host: www.google.com\r\n");
  delay(500);
  Serial2.write("Accept: */*\r\n\r\n\r\n");
}

void loop()
{
  if (Serial2.available()) {
    Serial.write(Serial2.read());
  }
  if (Serial.available()) {
    Serial2.write(Serial.read());
  }
}

And I get the response as follows, which is actually the Google home page:
AT
OK
AT+CWMODE=1
OK
AT+CIPMUX=0link is builded
Recv 80 bytes

SEND OK

+IPD,1410:HTTP/1.0 200 OK
Date: Fri, 23 Sep 2016 08:49:38 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=87=TS-mbT3JjN_vZQurH0M4e1tbNsgmSPF4ALY_ohGFUD6uz76RmbxY41AA_XtC75Wqxfcqu5v1lbLxy-tMa_yrn5-BHrxN7Hn6CeYVnEfG1bBsVd78Y6eHtJ0hOUQPIwaDM0_2wGPO52e7HQ; expires=Sat, 25-Mar-2017 08:49:38 GMT; path=/; domain=.google.com; HttpOnly
Accept-Ranges: none
Vary: Accept-Encoding

<!doctype html><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><link href="/images/branding/product/ico/googleg_lodp.ico" rel="shortcut icon">

<nobr>Search Images Maps Play YouTube News Gmail Drive More »</nobr>

<nobr>Web History | Settings | Sign in</nobr>

<form action="/search" name="f">

 	<input name="ie" value="ISO-8859-1" type="hidden"><input value="en" name="hl" type="hidden"><input name="source" type="hidden" value="hp"><input name="biw" type="hidden"><input name="bih" type="hidden">
<input style="color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top" autocomplete="off" class="lst" value="" title="Google Search" maxlength="2048" name="q" size="57">

<input class="lsb" value="Google Search" name="btnG" type="submit"><input class="lsb" value="I'm Feeling Lucky" name="btnI" onclick="if(this.form.q.value)this.checked=1; else top.location='/doodles/'" type="submit">	Advanced searchLanguage tools

<input id="gbv" name="gbv" type="hidden" value="1"></form>

Advertising ProgramsBusiness Solutions+GoogleAbout GoogleGoogle.com.my

© 2016 - Privacy - Terms

CLOSED

However, when I try it with the actual URL I intend to use:
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);

  delay(3000);
  Serial2.write("AT\r\n");
  delay(3000);
  Serial2.write("AT+CWMODE=1\r\n");
  delay(3000);
  Serial2.write("AT+CIPMUX=0\r\n");
  delay(3000);

  Serial2.write("AT+CIPSTART=\"TCP\",\"api.pushingbox.com\",80\r\n");
  delay(500);
  Serial2.write("AT+CIPSEND=135\r\n");
  delay(500);
  Serial2.write("GET /pushingbox?devid=vEB39F555B1B8295&tempData=cabbages HTTP/1.0\r\n");
  delay(500);
  Serial2.write("User-Agent: curl/7.37.0\r\n");
  delay(500);
  Serial2.write("Host: api.pushingbox.com\r\n");
  delay(500);
  Serial2.write("Accept: */*\r\n\r\n\r\n");
}

void loop()
{
  if (Serial2.available()) {
    Serial.write(Serial2.read());
  }
  if (Serial.available()) {
    Serial2.write(Serial.read());
  }
}

I get the following response:
AT
OK
AT+CWMODE=1
OK
AT+CIPMUX=0
OK
AT+CIPSTART=Accept: */*ERROR
ERROR
ERROR

+IPD,212:HTTP/1.0 408 Request Time-out
Cache-Control: no-cache
Connection: close
Content-Type: text/html

408 Request Time-out

Your browser didn't send a complete request in time.

CLOSED

The code is exactly the same except for the different URLs used, so what is causing the problem here? Why can't I send "api.pushingbox.com/pushingbox?devid=vEB39F555B1B8295?tempData=cabbages" to the internet? Please help! :-/

All those string literals need wrapping in F(...) or you will be overflowing your precious RAM.

But "cabbages" is something I wish to change later. Isn't F(...) only for constant strings?

Yes, and 99.99% of that (all except the word "cabbages" and the content length value) is constant strings.

Hey @Majenko thanks for the tip. But I can't seem to compile right with the F(....) wrapping. :-/

Did you get this issues sorted? I have the same problem, yet I can "GET" to Thingspeak with the same code without any issues? When I copy the URL directly into my web browser it works, however, the timeout error occurs only when I make use of my Arduino the "Serial.print" the GET command. would like your feedback, thanks! EO

I did notice you also changed
AT+CIPSEND=80\r\n
to
AT+CIPSEND=135\r\n
probably you send your request wrong or something?!?
(sorry I post this as answer but I didn't unlock comments yet)

First you must check if the problem is on your side or not.
You call http://api.pushingbox.com and you send parameter which are "pushingbox?devid=vEB39F555B1B8295&tempData=cabbages"
When I glue them together
http://api.pushingbox.com/pushingbox?devid=vEB39F555B1B8295&tempData=cabbages
and copy past this on my browser, I get an error with "Daily limit exceeded" with a status of 429 meaning "too many request".
So maybe there is a problem with the server?

Try changing:
Serial2.write("AT+CWMODE=1\r\n");

to:
Serial2.write("AT+CWMODE=2\r\n");

or:
Serial2.write("AT+CWMODE=3\r\n");


text:
How to serially communicate arduino uno to PIC18f4550?
I am new in PIC programming
my question is, how can i communicate arduino UNO with  PIC18f4550. i am using THIS programmer board for PIC controller and it has a builtin RS232 serial interface.
Can any body tell me how to communicate between them. I want to communicate in such a way that only Rx & Tx pins and the power pins of arduino will be used.

yeah you can quite easily do the Serial communication between Arduino and PIC Microcontroller. You need to connect the below pins:

Arduino TX will be connected to PIC RX.
Arduino RX will be connected to PIC TX.
GND of Arduino must be connected to GND of PIC.

Next thing you need to remember is to have same baud rate for both Arduino and PIC. Now you should check these two posts:

Arduino Serial Communication.
PIC Serial Communication

First one is explaining the Serial Communication of Arduino while the second one is Serial Communication of PIC Microcontroller. You should also read What is Serial Port? to get more idea about Serial communication.
I hope they will help you out. If you still got into some issues then let me know.

source: Stack Exchange

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

sort: votes


text:
how to use capacitive touch keypad without using CapacitiveSensor.h Library
i want to use multiple capacitive touch keypads with arduino uno but number of IO ports are not enough. So I decided to use MSP23S17 port extender. Now i have to find some methods to sense the touch keypad without using its library. Can anyone tell me if there is any way to do the task.

Tricky at best. CapSense relies on pretty tight time measurement to determine small changes in capacitance. You would be better off using a proper CapSense interface chip. There's plenty to choose from - most of them I2C based.

I am new in this field. Can you please refer me any CapSense interface chip. I am using the following touch keypad by waveshare
Waveshare Touch Keypad

Here's one: Microchip mtch6102, though it might be a little more complex than you're looking for.  All the others I found with a quick search were surface mount or single button controllers.  You might be able to multiplex a single button controller like the Atmel AT42QT1011, but I don't know what the settling or reset times are.  It may take to long to change pads, reset the chip, then wait for settling/calibration time (if any).

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


text:
L298N vs Motor Shield R3
I'm new to Arduino and need some clarification on motor drivers.
I was wondering if I can use a L298N instead of the Motor Shield R3, I hope not to be comapring apples to oranges, the doc of the Motor Shield R3 say "The Arduino Motor Shield is based on the L298"  and more or less I see similar projects (Robot cars) using both but as mention I don't if I can use one or the other as "replacement".
(L298N)

(Motor Shield R3):

There are many pages, both here and on electronics.stackexchange.com which explain that all boards based on the very old L298 and L293 are best avoided in favor of newer FET drivers, especially if you are using battery power.  If you already have one you can give it a try, but it would be a waste of money to buy one.

Yes.  The shield is easier to user, but the breakout board you've shown uses the same chip.  I'd suspect that the breakout board, which has a much bigger heat sink, can handle larger motors, though.  You'll need to put wires from PWM and digital pins to the breakout board you're showing, but it's not super challenging to use those.  I've used extremely similar boards in the past, as well as shields, and both work great.  How big are your motors?  If they're WAY too big (the breakout board can only handle 2 amps IIRC) then you'll need something else anyway.

Actually, all L298 based boards should be avoided, especially in something battery powered, as they are obsolete and very lossy.  Choose something based on an FET bridge IC instead, or for larger motors a bridge made of discrete FETs.

OP's question related to whether the two boards are interchangeable.  For many applications the readily available motor shields, or possible the shield that OP already happens to own, are sufficient.  I still have a lot of L298 boards lying around from old projects, I'm not going to throw them out and buy new things if I'm happy with their performance.

The problem is that the losses mean you need an extra cell in your battery pack just to heat up the driver chip.  That might be okay if you have a 12v pack and a motor that really wants a bit less, but it's a disaster whenever someone tries to do something with a lower voltage pack, and wasteful in any event.  So no, "work great" is not really a helpful statement.  Essentially the only reason these horrible parts remain in circulation is inertia and popular lack of understanding of how bad they are.

But they're not bad, they're just not optimal.  They actually do work fine.  If OP is running this from an adaptor, for example, and doesn't care about efficiency, and already has some of these things lying around there is absolutely no reason not to use them.  When OP wants to optimize for power use, then I do agree that better options are available.  But that's not what OP was asking


text:
SD card fail of initializing
I have an Arduino Mega and a catalex card reader which yesterday worked, but today I tried another time and the sd card where not detected, I am using the example code from Arduino website for the card info. I have tried conecting the reader to the SPI ports in the middle of the board and it was not solved. Anyone has another idea of what can be failing?

#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 10;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {

}

When you tried you tried the same SD card you tried it yesterday ?

Add these Two Lines for better initialization of SD card:
void setup{
    pinMode(10, OUTPUT); // change this to 53 on a mega(don't follow this!!)
    digitalWrite(10, HIGH); // Add this line
}

Check this link, may be useful to your current problem.

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


text:
Compilation error using arduino-mk on arch Linux (undefined reference to __dso_handle)

I'm compiling a simple sketch that reads values from an analog input
and activates a buzzer on a digital input.
working on an Arduino uno.
the sketch compiles and runs fine on windows and arch linux using the Arduino
IDE.

I recently tried to start working with Arduino-mk, I tried to compile the said sketch and got the following compiler error (analogVal is the variable holding the analogRead):
/usr/bin/avr-gcc -mmcu=atmega328p -Wl,--gc-sections -Os -o /home/niv/Gits/bin/uno/maglove/maglove.elf
~/Gits/bin/uno/maglove/maglove.ino.o ~/Gits/bin/uno/maglove/libcore.a  -lc -lm
/home/niv/Gits/bin/uno/maglove/maglove.ino.o: In function `_GLOBAL__sub_I_nothing':
maglove.ino:(.text.startup._GLOBAL__sub_I_nothing+0xc): undefined reference to `__dso_handle'
maglove.ino:(.text.startup._GLOBAL__sub_I_nothing+0xe): undefined reference to `__dso_handle'
maglove.ino:(.text.startup._GLOBAL__sub_I_nothing+0x18): undefined reference to `__cxa_atexit'
/usr/bin/avr-ld: /home/niv/Gits/bin/uno/maglove/maglove.elf: hidden symbol `__dso_handle' isn't defined
/usr/bin/avr-ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
/home/niv/Gits/Arduino-Makefile/Arduino.mk:1416: recipe for target '/home/niv/Gits/bin/uno/maglove/maglove.elf' failed
make: *** [/home/niv/Gits/bin/uno/maglove/maglove.elf] Error 1
make: Target 'all' not remade because of errors.

I am not very experienced with Arduino yet, and google has failed me in finding this error or any keyword from it in the context of Arduino uno.
thanks.

Please add the compile line. And google "__dso_handle".

@Mikael I added the compile line. anything before that is just library compilations that go smoothly

I can't say I fully understand what is going on, but it seems that if you add:
void * __dso_handle;

You may be able to eliminate one of the problems. You might try the same trick with __cxa_atexit as well.
I found the idea by searching on:

arduino __dso_handle

This is the webpage that I found that suggested the void * hack.

weirdly... That worked!
however it seems like an ugly workaround, I would prefer to understand whats causing this error and fix it on my Linux machine since the code needs to be good to compile on windows too, and something tells me adding these declarations might break it when compiling on windows.


text:
ESP8266 soft resets when using a GPIO Expander
In my project I'm trying to use a PCF8574 to drive some peripherals, since the ESP8266 doesn't offer all the GPIO pins I need, however I seem to be having problems at the most basic level of driving the pins of an e-paper display.
The e-paper display is connected to MOSI, MISO and SCL to the "native" pins GPIO12, 13 and 14, and I wanted to rely on the PCF to drive the other four pins (CS, DC, RST, BUSY).
I modified the original library so that it could accept an arbitrary Pin abstraction that looks like the following:
class Pin {
public:
  Pin(void){};
  ~Pin(void){};

  virtual uint8_t read() = 0;
  virtual void write(uint8_t value) = 0;
};

and at first implemented it as ArduinoPin, which all it does is setting up the pin mode and calling digitalRead or digitalWrite when needed.
While connecting the EPD with the ArduinoPin implementation, using D0, D1, D2, D4 as pins, the e-paper display works correctly, so I proceeded to make another implementation of Pin with the GPIO Expander.
Following the GPIO Expander and relative Pin implementations
gpio-expander.h
class GpioExpander {
public:
  GpioExpander(uint16_t address);
  GpioExpander();
  uint8_t read(uint8_t pin);
  void write(uint8_t pin, uint8_t value);

private:
  uint8_t buffer[1] = {0xFF};
  uint16_t address;
};

class GpioExpanderPin : public Pin {
public:
  GpioExpanderPin(GpioExpander *expander, uint8_t pinNumber);
  ~GpioExpanderPin(void);
  virtual uint8_t read();
  virtual void write(uint8_t value);

private:
  uint8_t myPin;
  GpioExpander *expander;
};

gpio-expander.cpp
GpioExpander::GpioExpander(uint16_t address) {
  this->address = address;
  buffer[0] = 0xFF;
  Wire.beginTransmission(address);
  Wire.write(buffer[0]);
  Wire.endTransmission();
}

GpioExpander::GpioExpander() : GpioExpander(0x20) {}

uint8_t GpioExpander::read(uint8_t pin) {
  write(pin, 1);
  Wire.requestFrom(address, 1);
  buffer[0] = Wire.read();
  return (buffer[0] >> pin) & 1;
}

void GpioExpander::write(uint8_t pin, uint8_t value) {
  if (value == 1)
    buffer[0] |= (1 << pin);
  else
    buffer[0] &= ~(1 << pin);
  Wire.beginTransmission(address);
  Wire.write(buffer[0]);
  Wire.endTransmission();
}

gpio-expander-pin.cpp
GpioExpanderPin::GpioExpanderPin(GpioExpander *expander, uint8_t pinNumber) {
  this->expander = expander;
  myPin = pinNumber;
}

GpioExpanderPin::~GpioExpanderPin(void) {}

uint8_t GpioExpanderPin::read() { return this->expander->read(myPin); }

void GpioExpanderPin::write(uint8_t value) {
  this->expander->write(myPin, value);
}

These implementations work fine, I tested everything with a multimeter and I can arbitrarily write 1s and 0s on all 8 pins of the PCF, but when I try to drive the four pins of the e-paper, the ESP8266 resets and I have no clue on why. I tried with the exception decoder and the following stacktrace appears:
Exception Cause: Not found

0x40202984: Twi::read_bit() at ??:?
0x402029db: Twi::write_byte(unsigned char) at ??:?
0x40202b94: Twi::writeTo(unsigned char, unsigned char*, unsigned int, unsigned char) at ??:?
0x40202bb9: Twi::writeTo(unsigned char, unsigned char*, unsigned int, unsigned char) at ??:?
0x40202cc0: twi_writeTo at ??:?
0x40201720: TwoWire::endTransmission(unsigned char) at ??:?
0x40105cfe: os_printf_plus at ??:?
0x40201748: TwoWire::endTransmission() at ??:?
0x402017f5: GpioExpander::write(unsigned char, unsigned char) at ??:?
0x40201794: GpioExpanderPin::write(unsigned char) at ??:?
0x402011f9: Epd::spiTransfer(unsigned char) at ??:?
0x40201238: Epd::sendData(unsigned char) at ??:?
0x40201385: Epd::clear() at ??:?
0x402010b6: setup at ??:?
0x4020583c: std::_Function_handler<bool (), settimeofday::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Function_handler<bool (), settimeofday::{lambda()#1}> const&, std::_Manager_operation) at time.cpp:?
0x4020583c: std::_Function_handler<bool (), settimeofday::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Function_handler<bool (), settimeofday::{lambda()#1}> const&, std::_Manager_operation) at time.cpp:?
0x4020583c: std::_Function_handler<bool (), settimeofday::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Function_handler<bool (), settimeofday::{lambda()#1}> const&, std::_Manager_operation) at time.cpp:?
0x4020583c: std::_Function_handler<bool (), settimeofday::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Function_handler<bool (), settimeofday::{lambda()#1}> const&, std::_Manager_operation) at time.cpp:?
0x40202158: loop_wrapper() at core_esp8266_main.cpp:?
0x40100e85: cont_wrapper at ??:?

(Not sure why I can't get the source lines to appear, any suggestion in that is most welcome.)
Anyway apparently the problem appears when ending the I2C transmission, at the lowest level possible, at Twi::read_bit, which I include for the sake of all of you trying to help me out
core_esp8266_si2c.cpp
bool Twi::read_bit(void)
{
    SCL_LOW(twi_scl);
    SDA_HIGH(twi_sda);
    busywait(twi_dcount + 2);
    SCL_HIGH(twi_scl);
    WAIT_CLOCK_STRETCH();
    bool bit = SDA_READ(twi_sda);
    busywait(twi_dcount);
    return bit;
}

The most upsetting thing is that this same setup, when programmed in Micropython works just fine (I can't use Micropython though, because I need all the RAM I can get from the ESP to draw pictures, and I'm much interested in the overall performance I can get with C++).
Anyone had this same problem? Any advice on how to fix this behavior?
EDIT
With some experimentation, I managed to replicate the problem in a smaller scale. The following code resets the ESP8266 as well:
void setup() {
  Wire.begin();
  GpioExpander expander;
  GpioExpanderPin pin(&expander, 0);
  while(true) {
    pin.write(0);
    pin.write(1);
  }
}

It looks like fast cycles of on-off crash the system (which is what the EPD library does when sending data, turning on and off the pins relatively fast to switch between modes etc.). Not sure how to address this though, but I believe it might be something related to the Twi libraries at this point.
EDIT 2
Adding a yield() to the write function of the gpio expander class makes the issue go away, but the time to execute a simple display clear grows to unacceptable levels (~3 seconds to perform a full display refresh).
Any suggestion is appreciated at this point.
EDIT 3
I did some more experimenting and benchmarking, and reached the following conclusions:

the time that it takes for the Wire library to send data to the GPIO expander (the write function) is ~50µs
when using the gpio expander, the time to write data to the SPI device (DC write + enable CS + SPI transfer + disable CS) takes a total of ~170µs (which checks out, 3 times calling the gpio expander makes for ~150µs and the rest is SPI transaction)
when using the arduino pins, the time to write data to the SPI device takes ~10µs (an order of magnitude less than the GPIO expander).

To send a total of 150,000 bytes to the e-paper display, then, with the GPIO expander takes roughly 3 seconds, while with the normal pins it would take 10 times less (0.3 seconds).
The reset issue is surely due to the time spent in the send loop: the watchdog thinks the program is stuck in an infinite loop and thus resets the board. This is why the calls to yield remove the reset issues.
I believe I must either find a faster implementation of wire (?) or try to minimize usage of CS / DC pins

Are you sure you are decoding the stack trace with the right binary?

build, upload, run, crash, copy stack dump, decode in one pass so the decoder can use the elf file corresponding to the bin which was uploaded

@SimSon yes, I believe I am. I am building everything with platformio which outputs the final binary in .pio/build/nodemcuv2/firmware.elf, and that is the target I'm supplying to the exception decoder, which, by the way, is the jar one found here: https://github.com/littleyoda/EspStackTraceDecoder

You didn't post your code on how you create the instance of GpioExpander. But judging that your GpioExpander construct is conducting a Wire transaction, this will depend on where you create an instance of GpioExpander, if it is created before the setup() function, the Wire.begin() has not be established yet. It is better to create a GpioExpander::begin() method and move most of the code in the construct to the begin() method.

@hcheung sadly, that changes nothing. As I mentioned, the gpio expander works just fine, I can arbitrarily turn on and off pins. The issue only presents itself when using it with the epaper display.

I edited the question because I found out a way to replicate the issue. It seems fast duty cycles crash the system.

Adding yield() help to "feed the dog"... Maybe you should consider to use a different MCU, ESP8266 do not have a hardware i2c.

In the end the answer to the problem is the update frequency of the pins that drive the e-paper display:
The original waveshare library (as linked in the post) does the following to send data to the EPD:

enable DC (to tell the EPD that it's receiving DATA)
enable CS (to tell the EPD to listen to the incoming SPI data)
send SPI data
disable CS (to tell the EPD that anything received after that is not its competence)

Normally with arduino's digitalWrite this happens in a matter of ~10µs, and even if we repeat this process 15k times (that's how many bytes a 4.2 inch display supports) we spend 0.15 seconds to update half of the display's content (because the EPD has 2 memory banks which must be written).
When using the GPIO expander, instead, the mean time to send data via I2C is something around 50µs, which means that to enable / disable the pins three times we increase tenfold the time that the normal digital write takes (~150µs) which translates to 1.5 seconds to update half of the display and finally roughly 3 seconds for a full update.
During this loop, the watchdog thinks that the program is stalling and resets the chip. This is why using yield the update runs its course correctly.
To fix this issue, I worked on the EPD library and reduced the use of the digital writes, by creating a "session" of sorts: whenever I start writing data in a loop, I enable the CS pin, and disable it only at the end of the loop, so that the 100µs are only expended around the data transfer loop.
This is actually what happened in the Micropython driver for the e-paper display: the SPI connection sent data in chunks, enabling and disabling the chip select pin only at the beginning and end of the "transaction".
I'm planning to publish the updated library at some point, once everything is smoothed out, if this can interest anyone leave a message :)

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


text:
MP3-TF-16P only works while connected to serial monitor
I am building a project with Arduino Nano and the component in the subject, which, as far as I understand, can be assimilated to a DFPlayerMini (not sure if it's the same thing or it's just a cheap knockoff).
Following one of the millions of tutorials on the net I managed to make it work, I can correcly play audio files out of an SD card, but the weird thing is, that it only works while I'm connected to the Arduino with the serial monitor open on my IDE: the moment I close the IDE and power everything via Vin or via any other means - including USB power from the PC - it fails to do anything.
If this can be helpful, the wiring is as follows (taken from the instructables website where I found the first tutorial)
And the code running everything is the following
main.cpp
#include <Arduino.h>
#include <modules/Sound.h>

#define BTN 3
#define TX 10
#define RX 11

Sound sound(TX, RX);

void setup() {
  Serial.begin(9600);
  Serial.println("Init");
  pinMode(BTN, INPUT);

  if (!sound.init()) {
    Serial.println("Nope");
  }

  sound.playInitSound();
}

void loop() {
  // unrelated stuff
}

modules/Sound.h
#include <Arduino.h>
#include <DFRobotDFPlayerMini.h>
#ifndef __SOUND__
#define __SOUND__

#define SOUND_POWER_UP   1
#define SOUND_POWER_DOWN 2

class Sound {
    public:
        Sound(uint8_t txPin, uint8_t rxPin);
        boolean init();
        void playInitSound();
    protected:
        DFRobotDFPlayerMini soundboard;
        uint8_t txPin;
        uint8_t rxPin;
};

#endif

modules/Sound.cpp
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include "modules/Sound.h"

Sound::Sound(uint8_t txPin, uint8_t rxPin) {
    this->txPin = txPin;
    this->rxPin = rxPin;
}

boolean Sound::init() {
    SoftwareSerial mySerial(txPin, rxPin);
    mySerial.begin(9600);
    boolean working = soundboard.begin(mySerial);
    if (working) {
        soundboard.volume(10);
    }
    return working;
}

void Sound::playInitSound() {
    soundboard.play(SOUND_POWER_UP);
}

As I said, everything works as long as I'm connected to the serial monitor from the IDE (if it's any relevant, I'm using PlatformIO on VSCode, on Linux).
I also tried to use the if (!sound.init()) part to make the arduino LED cyclically blink if there is a failure, and indeed it starts blinking.
Any thought? Any way I can add more info to help troubleshooting?
EDIT:
I tried removing all instances of usage of the Serial but it doesn't help
I started thinking that maybe it was a faulty Arduino, so I switched to another controller and this one behaves a bit differently: the sound module gets initialized (I don't see the blinking led that would mean failure) but no sound is played.
The main difference between the two controllers is that the "faulty" one has the new bootloader, the one that is partially working has the old bootloader instead. Not sure if this is meaningful in the least.
EDIT 2:
The arduino with the old bootloader works just fine, beats me why

@jsotola Sadly, it does not help. I removed all Serial stuff and it still does not work if not plugged to the serial monitor. The situation changes a bit when changing the controller though. I'm updating the post to reflect these last findings.

this part is confusing ... the moment I close the IDE and power everything via Vin or via any other means - including USB power from the PC - it fails to do anything .... does the failure occur simply by closing the IDE program? ... is it the powering by Vin that causes the failure?

@jsotola any way I power it, be it via Vin or via USB the problem occurs. I'm beginning to think that it's the board that's defective, because the other one I have seems to be working just fine

I'm having the same problem. Did you find a way to make it work?

@user86864 sadly, no. I am convinced that the board is defective. Any other board works. I suggest getting a new board, maybe a cheap one, and try it out


text:
Arduino Vending Machine problem
Currently I'm working on a vending machine project. The vending machine works using 3 button on LCD Keypad Shield DFRobot where 1 button of it assigned as 0.10 cent,the other two 0.20 cent and 0.50 cent respectively. My problem here is how can my system keep track on the balance/coin inserted so that whenever I pressed button 1 = balance 0.10 then later I pressed button 2 = balance 0.30 (because 0.20 cent added to the system). Or if you have a better idea for my code, that should be great. This is my code so far:

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    int lcd_key     = 0;
    int adc_key_in  = 0;
    #define btnRIGHT  0
    #define btnUP     1
    #define btnDOWN   2
    #define btnLEFT   3
    #define btnSELECT 4
    #define btnNONE   5
    volatile float balance = 0.00;
    float number1 = 0.10;
    float number2 = 0.20;
    float number3 = 0.50;
    int read_LCD_buttons()
    {
    adc_key_in = analogRead(0);      // read the value from the sensor
    if (adc_key_in > 1000) return btnNONE;
    if (adc_key_in < 50)   return btnRIGHT;
    if (adc_key_in < 195)  return btnUP;
    if (adc_key_in < 380)  return btnDOWN;
    if (adc_key_in < 555)  return btnLEFT;
    if (adc_key_in < 790)  return btnSELECT;
    return btnNONE;
    }

    void setup()
    {
    lcd.begin(16, 2);
    lcd.setCursor(0,0);
    lcd.print("TouchNGo Machine");
    }

    void loop()
    {
    lcd.setCursor(0,1);
    lcd.print("Balance=");
    lcd.setCursor(10,1);
    lcd_key = read_LCD_buttons();
    balance = 0.00 ;

    switch(lcd_key)
    {
    case(btnLEFT):
    {
    balance = balance + number1  ;
    lcd.print("RM");
    lcd.println(balance);
    break;
    }
    case(btnRIGHT):
    {
    balance = balance + number2 ;

    lcd.print("RM");
    lcd.println(balance);
    break;
    }
    case(btnUP):
    {
    balance = balance + number3  ;
    lcd.print("RM");
    lcd.println(balance);
    break;
    }
    }
    }

I would love to hear any comment from you guys.Thanks for the help!

What's wrong with your current code?

Remove "balance = 0.0;" from you main loop.  It's always clearing your balance.


text:
Need help with my code for my project using an Arduino Uno and Processing
I am using an Arduino Uno for my project. I use 4 digital inputs and they will be triggered by 4 different relays. I would like to save the data in a *.csv file in the format below.
For example, if any of the inputs goes high, it will save a station ID, date, time it goes ON (starts). But once the input goes low, it will save the time it goes OFF (stops) on the same line.
Kindly help to advise if my code is correct because I get too many errors when I run it.
Example table in .csv file:
Date        Oven Station    Time Start     Time Stop
3/7/2017       Oven_P1_1       11:58       16:00
3/7/2017       Oven_P1_2        7:30       11:00
3/7/2017       Oven_P5_1       14:10       20:00
4/7/2017       Oven_P5_2        01:20      7:30
4/7/2017       Oven_P5_1        2:40       8:45
4/7/2017       Oven_P1_2        08:05      12:00
4/7/2017       Oven_P1_1        09:12      13:10

import processing.serial.*;

int Oven_P1_1 = 8;
int Oven_P1_2 = 9;
int Oven_P5_1 = 10;
int Oven_P5_2 = 11;
float Ovenvals [] = {0,0,0,0};

Serial myPort;
String val;
Table table;

String filename;

void setup() {
  String portName = Serial.list()[5];
  myPort = new Serial(this, portName, 9600);
  table = new Table();
  table.addColumn("id");
  table.addColumn("year");
  table.addColumn("month");
  table.addColumn("day");
  table.addColumn("hour");
  table.addColumn("minute");
  table.addColumn("second");
  table.addColumn("Oven_P1_1");
  table.addColumn("Oven_P1_2");
  table.addColumn("Oven_P5_1");
  table.addColumn("Oven_P5_2");
}

void serialEvent(Serial myPort) {
  val = myPort.readStringUntil('\n');
  if (val != null) {
    val = trim(val);
    println(val);
    float Ovenvals[] =float(split(val, ','));
    TableRow newRow = table.addRow();
    newRow.setInt("id", table.lastRowIndex());
    newRow.setInt("year", year());
    newRow.setInt("month", month());
    newRow.setInt("day", day());
    newRow.setInt("hour", hour());
    newRow.setInt("minute", minute());
    newRow.setInt("second", second());
    newRow.setInt("Oven_P1_1", ovenVals[0]);
    newRow.setInt("Oven_P1_2", ovenVals[1]);
    newRow.setInt("Oven_P5_1", ovenVals[2]);
    newRow.setInt("Oven_P5_2", ovenVals[3]);
    {
      saveTable(table, "data/OvenStatus.csv");
    }
  }
}

void draw() {
  OvenVal[0] = digitalRead(Oven_P1_1);
  OvenVal[1] = digitalRead(Oven_P1_2);
  OvenVal[3] = digitalRead(Oven_P5_1);
  OvenVal[4] = digitalRead(Oven_P5_2);
  Serial.print(OvenVal[0]);
  Serial.print(",");
  Serial.print(OvenVal[1]);
  Serial.print(",");
  Serial.print(OvenVal[2]);
  Serial.print(",");
  Serial.print(OvenVal[3]);
  Serial.print(",");
  delay(100);
}

Better if you ask a particular problem rather than "too many error when we run"

Grinds teeth What you have is not referred to as "codes." You have posted your program code.  "Codes" are the things you enter into a numeric keypad lock to open a door.  "Code" is the text you write that is compiled to be made into the binary file that becomes your firmware.

C is case-sensitive.  You have defined a variable array "Ovenvals[]", but try to use "OvenVals[]" - those are two different arrays.

You asked for (emphasis mine):

[...] But once the input goes low, it will save the time OFF (stop)
  on the same line.

That's hard. What if several other inputs have gone HIGH in the
meanwhile? You will have to somehow rewind part of the file, then add
the stop time, the add again the subsequent lines...
You probably do not want to do all this on an Arduino. Especially
considering that the Arduino has no concept of file, unless you add an
SD card and the appropriate library. And it has no concept of time of
day, unless you add an RTC and the appropriate library. I would suggest
you go the easy path:

have the Arduino tell your computer through the Serial port whenever
one of those inputs changes state
write a program in your computer (with processing or whatever) that
reads this information and formats it the way you want.

For the first part, I suggest the following:
/*
 * Tell us when some pins change state.
 */

const int CHANNELS = 4;
const uint8_t pins[CHANNELS] = {8, 9, 10, 11};

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

void loop()
{
    static int states[CHANNELS];
    for (int i = 0; i < CHANNELS; i++) {
        int state = digitalRead(pins[i]);
        if (state != states[i]) {  // input changed state
            Serial.print("channel ");
            Serial.print(i);
            Serial.print(" going ");
            Serial.println(state ? "HIGH" : "LOW");
            states[i] = state;  // record new state
        }
    }
}

The output will be something like
channel 2 going HIGH
channel 1 going HIGH
channel 2 going LOW
...

For the second part, well, that's not an Arduino-related question
anymore!

Thanks Edgar for the enlightenment. Would you be able to help me how to save those output to .csv file or txt file on my computer?

@Bong: No, but that could be a legitimate question on stackoverflow.


text:
Arduino, RS232 and SIM800L EVB 2.0 (not responding on AT command)
I buy a SIM800L EVB 2.0 modul for Arduino (https://www.aliexpress.com/item/SIM800L-V2-0-5V-Wireless-GSM-GPRS-MODULE-Quad-Band-W-Antenna-Cable-Cap/32465337183.html).
First I tested modul with all pins connect to Arduino. Modul successfully response on AT commands (but not register on network).
Next day is the same. So I connect modul +5V and GND to external power supply with 1000uF capacitor (as in comments on Aliexpress). Modul successfully connected to the network - my GSM number was accessible) (additional GND pin on modul I connect to Arduino GND on digital GND pin).
But modul is not longer respoding on AT command.
So I tested with USB - serial cable (pin 2 and 3 with GND 5) - modul register on network, but not response on AT command (tested via Putty with different baud speed) - no answer.
What else can I try? How to tested if Rx and Tx on modul works or how to know if I accident burned pins on modul or Arduino or USB-serial cable.
Thanks for every reply.

RS232 is where here? in setup with external power supply, did you connect the ground between Arduino and the module?

My mistake -  I thought serial cable for PC (USB). Yes I connect GND modul with Arduino and with power supply.

USB is different then RS232 and both are different from TTL-Serial on Arduino and module. you should not wire USB to TTL-Serial

Ok tnx for explanation. I add additional test with Arduino and SIM800L.
Digital PIN 10 and 11 is fine - I try with other modul and it's working. So how to test Rx and Tx pins on SIM modul. I measured pin with voltmeter - one is 5V, other is 2.5V. Normal?

We've solved the problem (my firends) - one of the transistor on the modul was broken. Now works fine.

I burned out 2 of mine just few minutes ago after connecting to my ESP8266 NodeMCU's UART0, not sure about why, it is really weird. My ESP 8266 have a 3.3V UART0, no way to burn this 5V module out


text:
How to power two stacked motor shields with one 3S Lipo battery (11.1V)?
I have these 2 motor shields:
Adafruit Motor Shield V2 and
Seed Motor Shield V2.
They are stacked on top of an Arduino UNO.
My question is, how can I power 2 of those motor shields with one 3S Lipo battery(Turnigy 3S 2200mAh 20C), given that I have 6 identical 4.6-6V DC gearmotors?
Thanks!

Get a UBEC (switching buck regulator) for 5V with enough current to drive the motors. Turnigy do some good ones.

Could you provide links to the gear you are using?

Buck regulator as Majenko says is best with battery you have. BUT better is probably a 2S LiIon and linear regulator - only if you are willing to change battery.

@RussellMcMahon Why linear? Isn't that wasteful of energy? A buck regulator will increase the current availability from the batteries, but a linear won't. 6 motors could be quite thirsty on current, especially stall current...

@Majenko Note that I suggested linear only with 2S LiIon. 2S range is say 6V - 8.4V with most energy in say 6.4-8V range or maybe 7.8V. AT 8V to 6V linear regulator gives 75% efficiency. At mid range of say (8+6.4)/2 = 7.1V efficiency at 6V out is 6/7.1 = 85%. Buck is better than that across range but if you want usefully high stall currents then a linear reg that handles 1 or 2 or 4 A is a doddle. Buck is not overly hard but harder. Simplicity wise linear is nice. Losses per amp are 2W at 8V and 0.4W at 6.4V. IF gearmotors allow slightly >6V they may allow 2S directly.

@RussellMcMahon Note that I recommended a UBEC specifically - that is a single module with battery input and 5V output. Not a single component or a circuit you have to build. They are designed for model vehicle enthusiasts, and I even recommended one by the same manufacturer as the battery (I use the same make myself as it happens). No messing with components or circuitry, just wire it up and away you go. You can't get simpler than that - even simpler than wiring your own linear with all that messing with capacitors ;)

@sa_leinad Sure: https://www.amazon.com/Seeed-motor-shield-for-Arduino/dp/B00KAE2B3U/ref=sr_1_1?ie=UTF8&qid=1475012972&sr=8-1&keywords=seeed+motor+shield https://www.amazon.com/gp/product/B00PUTH3B0/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1 and https://www.amazon.com/gp/product/B0072AEY5I/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1

@Majenko Thank you so much! So if I want to power those two motor shields at the same time, I would need two UBECs?

It depends on the current capacity of the UBEC and the current requirements of the motors. If one UBEC can provide enough current then you can power both shields off one UBEC - just connect the output of the UBEC to both shields.

@Majenko  there are 6 identical motors (each takes max 250mA and min 190mA). First motor shield will control 2 motors (or 500mA) and second one will control 4 motors (or 1A). Would this 3A  UBEC do the job? Thank you again!

Yep, that would do it fine - and still leave you plenty of capacity to also power the Arduino as well if you like.

@Majenko Sweet, I ordered it. I will post the results. Thanks!

You can avoid using a linear voltage regulator. Try using this voltage regulator.
You will get 5 Volts 2 Amp output which should be easy to connect to motor shield's input power ports.

Thanks. How is this different from UBEC suggested by @Majenko ?

No, you really don't want to run a motor on a regulator.  Choose an appropriate power source, use a regulator for the electronics and use PWM to deliver an appropriate amount of power to the motors.


text:
How to use millis()
I'm trying to have a keypad do two one of three things when a key is pressed:

If the 1 is pressed I want LED 1 to blink twice then stay on
If either the 2 or the 3 is pressed I want LED 2 to blink forever
If the # key is pressed I want it to cancel whatever's going on with the other LEDs

How can I use millis() to blink forever? Or just blink twice then stay on? When in my blinking should I be checking for another keypress? What's frustrating me is that I know how to do all this with delay(), and I've written 70% of the code for it with delay, but if I use delay I don't think it'll be able to check for another key input, will it?
Thanks for any help.

How can I use millis() to blink forever?

The algorithm is essentially as follows:
if (it_is_time_to_toggle_the_led()) {
    toggle_the_led();
}

The details are thoroughly covered in the Blink Without Delay
Arduino tutorial. It is essential to understand this technique: as soon
as you have more than one thing to do in your program (here: blink an
LED and monitor button presses), delay() is toxic because it blocks
all the program. You should really ban delay() from your vocabulary,
except for the simpler single-task programs.

Or just blink twice then stay on?

For this and your other questions, the canonical answer is “implement a
finite state machine”. I recommend the Finite State Machine
tutorial[] by Majenko.
In this particular instance, I would probably implement two FSMs, one
for each LED. The first one would have three states: (OFF, BLINKING,
ON), and a counter for the number of blinks. The transition rules:

If button 1 is pressed and the state is not BLINKING go to the
BLINKING state
If it is BLINKING and it's time for it to toggle, do it
If it is BLINKING and it is switching on for the third time, go to
the ON state
If '#' has been pressed, go to the OFF state.

Or maybe you could split the state BLINKING into BLINKING_ON and
BLINKING_OFF.
The second LED would be essentially the same, except for lacking the ON
state and rule number 3.
I am not writing the code, but you may want to take a look at this code
for automatic door[]. It is an answer to a seemingly unrelated
question, but it gives a good example on how to combine millis()-based
timing with a finite state machine. Your program could be written mostly
along the same lines.

Wow, I had never heard of FSMs before, really cool! Thanks for your help.

So I've tried many different ways of doing it and the system seems to have trouble advancing through the loop. Here's my code so far. I know I'm not supposed to use delay() but it works okay for right now. The problem is that the red LED will turn on (when 4 or 5 is pressed), and stay on. There's no blinking or anything, which leads me to believe it runs through the code then waits for another keypress before running back through the loop? Does that make sense? Any more help you can offer would be greatly appreciated.

@finlay: Your code won't compile.


text:
Can I power two 5V with Arduino powered with 9V power adapter?
I have a setup where I have a 5V IR receiver and 5V relay board and Arduino Uno.
I am currently powering the Arduino from the PC USB and both the IR receiver and the relay board from the Arduino. And it works fine.
Now I want to know how it would work when I power it with a 9 volts wall adapter. Will the voltage be enough for both the IR receiver and the relay board? And will Arduino work fine?

What do the datasheets say?

The voltage will be fine - as long as you plug it into the DC barrel jack, and don't try to wire directly to the 5V pins. The barrel jack has a voltage regulator on it that will convert 7-12V down to the required 5V.
But there's a second reading that you need to look at, not just voltage. The 9V adapter will also have a current rating expressed in milliamps (mA) or amps (A, which is 1,000 mA). The Arduino needs around 25 mA to do its thing, and your adapters add to the total current - maybe 20 mA each again. So if your adapter only provides 50 mA, it won't be able to provide enough current and the system won't work.
The USB port provides 5V, but it also provides up to 500 mA, which is more than enough for the job. If your wall adapter is 100 mA or above, that should be enough. And unlike voltage, a larger number for current is better - that's its maximum capacity of supply, rather than something that will burn out the equiment!

This is the correct answer. As long as you connect the Arduinos properly to the adapter, the voltage is no problem. Amps is what you need, most net adapters for phone charging for example can supply a current of 1A, tablet chargers often go between 2~3A. But as John said: don't fear something with high amperage, it's not like voltage. If anything you'd want the highest amperage you can get, but you can easily settle for 1A.

I wouldn't go with an adapter that can't deliver less then 500 mA, since it was verified to be working on USB with max 500mA. The relays can draw "quite something" to go on. But without having the data, I would take the worst case scenario/verified (to be working) scenario.

But you can indeed try, wouldn't do any harm (but could be unstable).

If you're connecting the 9V wall adapter to the Power socket of the arduino, then sure its going to work. It can supply both for the IR and relay boards.


text:
How can I save my float 'ave' on the EEPROM continuously?
How can I save my output continuously to EEPROM? Or is this even possible? Please help me out.
void setup() {
  Serial.begin(9600);
}

void loop() {
  static unsigned long count = 0;
  static float sum = 0;
  float ave = 0;
  int volt = analogRead(A1);
  float voltage = map(volt, 0, 1023, 0, 2500) / 100.0;
  Serial.print("Voltage: ");
  Serial.println(voltage, 2);
  sum = sum + voltage;
  count++;
  ave = sum / count;
  Serial.print("Average: ");
  Serial.println(ave, 2);
  Serial.println("-----");
  delay(3000);
}

Add an FRAM to your system. They can support 10 trillion writes.  34 billion years worth of writes. Plus they can be accessed at SRAM speeds, while the onboard EEPROM takes 3.3mS to write to it, and can be corrrupted if power is lost during the write.  With FRAM, you can toggle between 2 addresses, if one gets lost you can back up to the good one and only be a few seconds behind. (you can do that with EEPROM too)

The answer is: Read the Arduino Reference and find EEPROM.put
But your actual problem is that
1) if you write to eeprom every 3 seconds, the Arduino eventually
    won't survive you
2) you eventually rather want to write the sum and the count, in
    your case ?
You should also think about how to initialize from EEPROM after Restart.
Perhaps it's sufficient to save restart values only once after 1 minute / 1 hour / daily if it still changes?
BTW the "Update only if it changed" is already built into the put() method.

What if i will just store my latest data? Every data it will received will be replaced by new one every 3sec. As long as I can save or store my last data, that will be fine.

You might like to consider whether there's a chance to detect the power-down before the Arduino actually stops working. If detected your values are saved, some milliseconds suffice. This could be done with some hardware but depends on your environment.

@Rica Jacutina: That was my basic idea as well. If you always store the latest data every 3 sec, you will store them  28800 times a day. atmega EEPROM has a lifetime of about 100000 writes, so your system survives 4 days. Not very smart for an "average since ever". You can write them to different locations and use all EEPROM memory and thus extend lifetime to about a year, but the busybee's idea is much better.

I'll try your suggestions. Thanks a lot!

It's possible, but it's certainly not advised.
EEPROM has a limited number of writes before it's dead. By writing continuously to the EEPROM you will kill it in no time at all.

How limited is it? Maybe I can adjust the seconds on when I will save data per day?

100,000 IIRC but I'd have to check the datasheet. Better to use something like a 47L16 EERAM.


text:
Powering Arduino and transistors with one power supply > 12V
So say you want to use transistors with your Arduino Nano to power components, which require greater than 12V. If your power supply is more than 12V, is there a way to safely use the same power supply to power the Arduino?

power components, which require greater than 12V More specific info leads to better responses.

The voltage regulator (on the Vin pin) is supposed to be provided with 12V at max, since it is not cooled (it is a linear regulator, that dissipates the excess voltage as heat). If you have significantly more, you should at best buy a little switching regulator, to directly get a regulated 5V to feed to the 5V pin of the Arduino (that's what I suggest). Be sure to use a regulator, that can provide the needed current (which also depends on what else you provide over the Arduino).
If you really don't want to use an extra regulator and you don't have much more than 12V (maybe like 15V), you might get away by cooling the voltage regulator on the Arduino. The voltage regulator on a genuine Arduino will go into emergency shutdown, if it overheats, but it will not be damaged easily. Here you could try a bit. But be careful to not stress it too much. The clones from china often have different/cheaper regulators, that will mostly be fried if you overheat them. But they are very cheap.

If powered with 12V, do those output pins still output 5V?

The output pins of the Arduino still use 5V, since the Arduino still works with 5V. The 12V only get regulated down, when you provide them to the Vin pin or the barrel jack. A dedicated voltage regulator takes the 12V and outputs 5V for the Arduino to run on. The only question is, if the voltage regulator can stand the power to dissipate, which depends on the provided input voltage and the drawn current.

Even the 5V Pin provides 5V only :) You should not connect load to it, if Vin is 12V or even higher.

The recommended input voltage for the Arduino Nano is 7-12 V, the max. 20 V.
So you could use upto 20 V, but this is indeed not advisable.
What you can do, is to use a so-called step down/boost down converter which converts the voltage back to a voltage that your Arduino Nano can (easily) handle. The voltage drop will be changed into heat, but I guess considering you are using a higher voltage power supply, you are not using battery power.
Note: this is only true for some (cheap?) converters, see the comment of DataFiddler below.

Recommendable step down converters do not turn the excess voltage into heat, but use a fast switching regulation mechanism with a better efficiency.

@DataFiddler I didn't know that, thought it was not advised to have a too much difference between input/output voltage.

That's correct for linear regulators like the one onboard Arduino.

If I understand your question you have external devices say lamp, motor, etc. There are several ways of doing it. My preferred way is to use a N-Channel MOSFET where the drain is the output, the source is ground (both the logic and power grounds need to be connected together) and the gate Is connected to the port pin that also has a 10K pull down resistor. You can use the 12V to power the Arduino via Vin as you suggested. Be sure the MOSFET is avalanche rated and will turn on at about 3V or less.
You can do the same thing with an NPN Transistor where the port pin connects to the base with a 300 Ohm resistor (you need to calculate this based on the load), emitter to the connected grounds and the collector is your  output.


text:
Arduino Reset via Software (every day)
Dear Stack Exchanger's,
I want to reset my Arduino and system in every 24h for preventing frozen software and also other connectivity stuffs.
I wrote a program which connects a digital pin to reset pin of Arduino and I want to reset with that way.
For example my code :
unsigned long myTime; // Millis() function time value
int timeExpected = 5000; // I want to reset it in every 5 secs for testing.
const int RESET_PIN = 2; // Reset pin's connection

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN,OUTPUT);
}
void loop() {
  digitalWrite(LED_BUILTIN,HIGH);
    myTime = millis();
    Serial.println(myTime); // prints time since program started
     delay(1000);

   if(myTime % timeExpected == 0) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
     Serial.println("RESET");
    //digitalWrite(RESET_PIN, LOW);(I just test with LED_BUILTIN Low function)
    }

  }

I have tried the watchdog timer but I cannot do it for 24 hours.
If you have another solution for reset in 24h please tell me and send me the related article/book/link etc. I will check and implement into my code.
UPDATE:
I have done this but it does not reset at very 5s .
Code :
#include <avr/wdt.h>
unsigned long myTime;
int timeExpected = 5000;

void setup() {
  Serial.begin(9600);
Serial.println("Setup started :");
// make a delay before enable WDT
// this delay help to complete all initial tasks
delay(2000);
wdt_enable(WDTO_2S);
}

void loop() {
    myTime = millis();
    delay(1000);
    Serial.println(myTime); // prints time since program started
   if(myTime == timeExpected) {
     Serial.println("RESET");
    wdt_reset();
    }

You can't really use unstable software to reset itself - if it freezes, how can it execute the reset code? You'll need to either: 1) debug the software (you should do this anyway); 2) use the built-in watchdog timer to reset the arduino if your software doesn't reset the watchdog; or 3) use an external hardware timer to reset the Arduino at intervals. Solution 3) should be unnecessary if you do 1) and 2).

wdt_reset() resets the watchdog's timer to avoid reset of the MCU. read my answer again

You can do an almost immediate full reset with watchdog by activating it 'on place'.
wdt_enable(WDTO_15MS); // resets the MCU after 15 milliseconds
while (true);

You can use millis() for timing the reset as any other timed function.

You can use the watchdog timer, but you have to change the way you measure the elapsed time. Try this code:
#include <avr/wdt.h>

unsigned long myTime; // Millis() function time value
unsigned long elapsedTime;
unsigned long timeExpected = 5000; // I want to reset it in every 5 secs for testing.
const int RESET_PIN = 2; // Reset pin's connection

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  myTime = millis();
  Serial.println("INIT");
  wdt_enable(WDTO_2S); //Enable wdt every two seconds

}
void loop() {

  //************RESET HANDLER********************//
  elapsedTime = millis() - myTime;
  if (elapsedTime > timeExpected) {
    Serial.print("RESET");
    while (1); //Intentionally halt the program, so the watchdog performs the reset
  }
  //**********************************************
  //****************REST OF THE PROGRAM***********
  wdt_reset(); //Ensure one call to this function at least one time in two seconds or less
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println(elapsedTime); // prints time since program started
  delay(1000);
}

Please note that if you have multiple delays in your program, you have to ensure the call to wdt_reset() in order to prevent unwanted resets.
Personally I try not to use delays and would recommend avoid delays as much as possible. You may check out this tutorial if you want to see how to avoid delays. If you achieve avoiding delays you can call wdt_reset() just one time at the begining of the loop.


text:
RCSwitch for Alarm System
Folks,
I use the RCSwitch sketch to notify my WiFi alarm controller when a motion is detected.
Using the Receiver Code, I have got the following information related to the motion detection signal from the PIR (detector):
Decimal: 8876073 (24Bit)
Binary: 100001110111000000101001
Tri-State: not applicable
PulseLength: 311 microseconds
Protocol: 1
Raw data: 9700,1096,264,400,952,420,964,380,968,372,1012,1040,316,1028,324,1016,380,332,1008,1012,340,1040,344,1000,348,356,1024,324,1016,332,1012,372,1016,336,1012,372,1008,1016,336,328,1016,1008,380,324,1016,368,1012,1008,344,

My Transmitter Sketch is as follows:
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
 Serial.begin(9600);
 // Transmitter is connected to Arduino Pin #10
 mySwitch.enableTransmit(10);
 // Optional set pulse length.
 mySwitch.setPulseLength(312);
 // set protocol (default is 1, will work for most outlets)
 // mySwitch.setProtocol(2);
 // Optional set number of transmission repetitions.
 mySwitch.setRepeatTransmit(5);
 pinMode(13,OUTPUT);
}
void loop() {
 mySwitch.send("100001110111000000101001");//Detection Signal
 //mySwitch.send("100001110111000000101001");//Detection Signal
 //mySwitch.send("101110100000000011000010");//Panic Signal
 //mySwitch.send("101110100000000011000010");//Panic Signal
 Serial.print("Sent 100001110111000000101001 ");
 digitalWrite(13,HIGH);
 delay(500);
 digitalWrite(13,LOW);
 delay(10000);
}

While it appears the message is being sent, unfortunately my Alarm Control doesn't detect it.
Can anyone suggest a fix please?
Ranjith

why do you expect the alarm control to accept communication from the arduino? ... it seems that it would be a security failure if the code was accepted

I need to replace the unreliable wireless alarm system with a new wired system which I have built using good components. However, I also need to use the old wireless security controller to take the advantage of the wireless notification function of it. Given that none of the detectors communicates to the security controller, the security of the system will not be compromised.


text:
Arduino IDE Java error
I'm running IDE version 1.8.16 under Windows 10.
Frequently I get the error message. The situation is solved only when exiting the IDE. Afterwards the compilation  may be finished with or without sketch errors.
Is there anything to do?
Exception in thread "AWT-EventQueue-0" Exception in thread
"Thread-18" java.lang.IndexOutOfBoundsException: len=-12
    at sun.font.FontDesignMetrics.charsWidth(FontDesignMetrics.java:501)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidthUpTo(TokenImpl.java:601)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidth(TokenImpl.java:570)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1180)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1159)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.getLineWidth(SyntaxView.java:307)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.calculateLongestLine(SyntaxView.java:110)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.refreshFontMetrics(RSyntaxTextArea.java:2106)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.setFont(RSyntaxTextArea.java:2545)
    at processing.app.EditorTab.applyPreferences(EditorTab.java:333)
    at processing.app.Editor.lambda$selectTab$52(Editor.java:1457)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
java.lang.IndexOutOfBoundsException: len=-12
    at sun.font.FontDesignMetrics.charsWidth(FontDesignMetrics.java:501)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidthUpTo(TokenImpl.java:601)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidth(TokenImpl.java:570)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1180)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1159)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.getLineWidth(SyntaxView.java:307)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.calculateLongestLine(SyntaxView.java:110)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.updateMetrics(SyntaxView.java:903)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.yForLine(SyntaxView.java:988)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.yForLineContaining(SyntaxView.java:1013)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI.yForLineContaining(RSyntaxTextAreaUI.java:263)
    at org.fife.ui.rtextarea.RTextAreaBase.yForLineContaining(RTextAreaBase.java:1218)
    at org.fife.ui.rtextarea.LineHighlightManager.repaintLine(LineHighlightManager.java:174)
    at org.fife.ui.rtextarea.LineHighlightManager.addLineHighlight(LineHighlightManager.java:69)
    at org.fife.ui.rtextarea.RTextArea.addLineHighlight(RTextArea.java:296)
    at processing.app.Editor.addLineHighlight(Editor.java:1670)
    at processing.app.Editor.statusError(Editor.java:2552)
    at processing.app.Editor$BuildHandler.run(Editor.java:1646)
    at java.lang.Thread.run(Thread.java:748)

do you have some unusual characters in the sketch?

I see this a lot and I am using Linux. It appears when there is an error in my code, sometimes as simple as a parenthesis  missing sometimes it just crashes. I close it and restart and everything is fine. This only messes with the current instance of the IDE, other windows and IDEs operating in the same and different work spaces and they are OK. The only consistent thing is it crashes during upload and I get lots of java errors. It will usually close, so I do not have to kill it. Sorry this does not solve the problem but lets you know it is not a windows only problem.


text:
Bitwise Operator in Arduino Code Question
What is the below Arduino code doing?
I am not familiar with the '+' with regard to bitwise operations. Just getting familiar with this stuff.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);

This isn't really Arduino code. Arduino uses C++, so questions like this can be answered by consulting C++ tutorials. There is no special "Arduino" language.

+ is the addition operator. It is used to add numbers. For example,
2+3 yields 5.
For analyzing your expression, let's call “a”, “b”, “c” and “d” the bits
of one, two, three and four respectively, like this:
one    = aaaaaaaa
two    = bbbbbbbb
three  = cccccccc
four   = dddddddd

These numbers may have more than 8 bits, but in that case the extra bits
will be discarded by the & operations. Now, let's compute the terms of
the sum, and then the whole sum:
(one   << 24) & 0xFFFFFFFF = aaaaaaaa000000000000000000000000
(two   << 16) & 0x00FFFFFF = 00000000bbbbbbbb0000000000000000
(three <<  8) & 0x0000FFFF = 0000000000000000cccccccc00000000
(four  <<  0) & 0x000000FF = 000000000000000000000000dddddddd
─────────────────────────────────────────────────────────────
sum                        = aaaaaaaabbbbbbbbccccccccdddddddd

As you see, only one bit in each column of this addition can be
non-zero, and that column's sum can only be 0 or 1. This means that
there will be no carries, and the columns will add independently of one
another. The sum is then made of the bits of one, two, three and
four concatenated.
The exact same result could be computed by using the bitwise OR operator
(|) instead of +. In fact, I would prefer using |: to my eyes it
makes the programmer's intent clearer.

Amazing explanation. Thank you so much!

You are better off using | for bitwise operations. Whilst + will work under certain circumstances, | is better. For example:
a = 1 + 1 + 1 + 1;  // a will be 4
a = 1 | 1 | 1 | 1;  // a will be 1

For code where you are just trying to set a single bit, using | is much preferable, as if the bit is already set and you use + then you will clear the bit and set the next one along.

That makes sense. Thank you!


text:
Unable to control motor with ESP32 using logic level shifter
I am using an ESP32 a TB6600 micro stepper, and a Nema 23 stepper motor, I am trying to control the motor with the esp32 but the TB6600 requires a 5v signal, I tried to fix this by using a logic level converter (specifically this) but when I attempt to control the motor I get a very slight hum out of the motor and no movement.
The motor controller and motor both work as I tested it with an Arduino Uno.
void setup() {
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  digitalWrite(16, HIGH);
}

void loop() {

  digitalWrite(15,LOW);
  digitalWrite(15,HIGH);
  digitalWrite(17, HIGH);
   delay(200);
}

Picture of Circuit

Circuit Diagram

The inputs ENA, DIR and PUL appear to be leds of optocouplers based on this: https://www.dfrobot.com/product-1547.html . I guess that you don't need that logic level shifter which is anyway intended only for very low currents. It is strange, however, that 5v is specified. The wiring in the link I have supplied implies that LOW is on and HIGH is off. Ensure that any example code you are using matches your wiring.

How much current the TB6600 needs on its inputs? Bidirectional level shifters can't provide much current on the high side as they are basically shorting LOW through the mosfets (HIGH is pulled up by few kiloohms resistors to HV)

When you plug in your circuit, do you notice your motor getting hot? Also, why are you setting your pin 17 to high in your loop?

It doesn't look like the motor controller shares a ground with your ESP32.  Try connecting the grounds together and see if it helps.

I figured out the problem, the logic level switcher I was using is meant for I2C  sensors, and thus was only capable of converting open-drain signals and cannot perform push/pull level translation meaning it was not able to provide a data signal to the micro stepper. I replaced the shifter with a shifter capable of push/pull translation specifically This

I haven't used this kind of system, so I'm just guessing. But in the Manual it says:

When“EN”is in the valid state, the motor is in a free states (Off-line
mode). In this mode, you can adjust the motor shaft position manually. When“EN”is
in the invalid state, the motor will be in an automatic control mode.
(Source).

It is not entirely clear what they mean by "manually". But you set pin 17 to HIGH and the result would fit the description. Maybe set 17 to LOW?
On another note: there is no delay/time between digitalWrite(15,LOW); and digitalWrite(15,HIGH);. This will create a very short pulse, which might be too short for the level shifting electronics to translate. Some delay() or equivalent non-blocking code between the two writes could help.

In this context, "manual" means physically manipulating the shaft rather than doing it through the motor controller.   When steppers are disconnected, they can free spin.  When they are powered with a constant signal or shorted, they will hold position and resist external forces that would otherwise cause them to free spin.


text:
The code is showing same angles for all three axis in the mpu gyro. can anyone solve it so that it works
#include<avr/io.h>
float x, y, z, baf = 0, j, i = 0, k, angle, a, b, c, d;
unsigned long current_time = 0;
unsigned long previous_time = 0;
unsigned long time_interval = 0;
float gyro_offset_x = 0.0;
float gyro_offset_y = 0.0;
float gyro_offset_z = 0.0;

void i2cinit(void)
{
  TWSR = 0x00;
  TWBR = 0x14;
  TWCR = (1 << TWEN);
}

void i2cstart(void)
{
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
}

void i2cwrite( unsigned char data)
{
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
}

unsigned int i2c_receive(unsigned char isLast) {
  if (isLast == 0)
  {
    TWCR |= (1 << TWINT) | (1 << TWEA) | (1 << TWEN);
  }
  else
  {
    TWCR = (1 << TWINT) | (1 << TWEN);
  }
  while (!(TWCR & (1 << TWINT)));
  return TWDR;
}

void i2cstop(void)
{
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

}

void mpu6050_init(void) {
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(0x6B); // PWR_MGMT_1 register
  i2cwrite(0);
  i2cstop();
}
void mpu6050f()
{
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(0x1B);
  i2cwrite(0x00);// changed here
  i2cstop();
}
float mpu6050rbyte(int gyro) {
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(gyro);
  i2cstart();
  i2cwrite(0xD0 | 0x01);
  float i = i2c_receive(1);
  i2cstop();
  return i;
}
float mpu6050_whole_data(int a, int b) {
  int msb = mpu6050rbyte(a);
  int lsb = mpu6050rbyte(b);
  float x_gyro = (msb << 8) | lsb;

  return x_gyro;
}

void calibrateGyroOffset() {
  const int numSamples = 100;
  for (k = 0; k < numSamples; k++) {
    gyro_offset_x += mpu6050_whole_data(0x43, 0x44);
    gyro_offset_y += mpu6050_whole_data(0x45, 0x46);
    gyro_offset_z += mpu6050_whole_data(0x47, 0x48);
  }

  gyro_offset_x /= numSamples;
  gyro_offset_y /= numSamples;
  gyro_offset_z /= numSamples;
}

float mpu6050angle(float woho, float gyro) {
  float angular_velocity = (woho - gyro) / 131.0;
  previous_time = current_time;
  current_time = millis();
  time_interval = (current_time - previous_time);
  float filter = (0.98 * angular_velocity) + (0.04 * angular_velocity);
  float angle = baf + (filter * time_interval) / 1000.0;
  baf = angle;
  return angle;
}

void setup()
{
  Serial.begin(9600);
  i2cinit();
  mpu6050_init();
  mpu6050f();
  calibrateGyroOffset();
}
void loop()
{
  x = mpu6050_whole_data(0x43, 0x44);
  y = mpu6050_whole_data(0x45, 0x46);
  z = mpu6050_whole_data(0x47, 0x48);
  //  a = mpu6050angle(y, gyro_offset_msb);
  //  b = mpu6050angle(z, gyro_offset_lsb);
  j = mpu6050angle(x, gyro_offset_x);
  c = mpu6050angle(y, gyro_offset_y);
  d = mpu6050angle(z, gyro_offset_z);
  //  mpu6050r(0x43, &x, &y, &z);
  // mpu6050_init();
  //  Serial.print("Offset x");
  //    Serial.print(gyro_offset_x) ;
  //    Serial.print("      ");
  //  Serial.print("Offset y");
  //  Serial.print(y) ;
  //  Serial.print("      ");
  //  //  Serial.print("Offset z");
  //  Serial.print(z) ;
  //  Serial.print("      ");
  Serial.print("Angle x: ");
  Serial.print(j);
  Serial.print("      ");
  Serial.print("Angle y: ");
  Serial.print(c);
  Serial.print("      ");
  Serial.print("Angle z: ");
  Serial.println(d);
}

Should at least post what you expect to see and what you did see.  Even unexpected outputs might give people reviewing this question a hit as to what is happening.

can anyone solve it? is not a question about the gyro

There may be a number of problems with this code.  I will try to edit this answer as you provide feed back.  The goal is a workable answer.  To be clear, some here may, but it is up to you to fix your code.

Dead Reckoning is difficult.  Any errors accumulate over time.  A gyroscope is usually used as part of a sensor fusion with an Accelerometer or Magnetometer. This allows the gyroscope absolute reading to be corrected or reset to mitigate accumulated error. If sensor fusion is not available, then the gyroscope calibration will be very important in mitigating as much drift as possible.

Constrain the problem to make it simple.  Initially, constrain the gyroscope movements such that only the X axis is rotated.  For example, only rotate the gyroscope on a stable table top. This way, only the X data need be considered / shared as this problem is discussed.

Consider finding the gyroscope offset as the first step.  The calibration function does not appear to have a time delay as does the normal sampling code. If the calibration function samples the gyroscope as fast as possible, the offsets may be too small or even zero and little use later when applying them to the gyroscope samples.

The stack exchange web sites are not good for discussions.  If anything, this question / answer my still be closed, as it deals w/several aspects of gyroscope usage, before we finish. To mitigate the chances, stick w/edits-to-the-question & comments that include results are well worded.


text:
Arduino M0 pro(ATSAMD21G18A-U) to NEO-M8N-0-10 gps interface issue
i trying to interface ATSAMD21G18A-U to NEO-M8N-0-10 gps by using UART.
my problem is here, i  need to use pin 25(rx) and 26(tx) of arduino to interface. i have tried below. but getting
error:C:\Users\lenovo\AppData\Local\Temp\.arduinoIDE-unsaved2023420-9788-1he85tu.af3\sketch_may20a\sketch_may20a.ino:1:10: fatal error: SoftwareSerial.h: No such file or directory
 #include <SoftwareSerial.h>
          ^~~~~~~~~~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: SoftwareSerial.h: No such file or directory

Code:
#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(25, 26); // RX, TX pins for GPS module

void setup() {
  Serial.begin(9600); // Serial monitor for debugging
  gpsSerial.begin(9600); // GPS module communication
}

void loop() {
  if (gpsSerial.available()) {
    char c = gpsSerial.read();
    Serial.print(c); // Print GPS data to Serial monitor
  }
}

I tried to download library but not able find. I am newbie to arduino.

use Serial1 on RX/TX pins


text:
Upload Same Sketch to Multiple Different Microcontollers via USB?
I'm attempting to figure out how to mass-upload a single Arduino INO sketch file to several different microcontrollers on a Windows 10 system.

It was understanding that, every time that the Arduino IDE compiles & uploads an INO sketch, it essentially calls the avrdude.exe executable in the installed Arduino directory. Therefore, I assumed it would be possible to create some sort of a Windows batch script that manually executes that file, and uploads the sketch to a given COM port connected to my Windows 10 system. In fact, an answer to a simillar Arduino Forums post some time ago has provided a potential solution in the following batch script:
@echo off
SET FILE_TO_UPLOAD=%1

SET ARDUINO_DIR="C:\Program Files (x86)\arduino"

@echo off
for /f "tokens=*" %%a in (ports2.txt) do (
echo Com Port for Arduino device is detected as %comport%.
echo --------------------------------------- & echo Uploading to: %%a & "C:\Program Files (x86)\arduino\hardware\tools\avr\bin\avrdude.exe" -C "C:\Program Files (x86)\arduino\hardware\tools\avr\etc\avrdude.conf" -p atmega328p -c arduino -P %%a -b 115200 -D -V -U flash:w:%FILE_TO_UPLOAD%:i
)
pause

However, it appears that the latest verions of the Arduino IDE (v2.3.3 in my case) does not store its data in "C:\Program Files (x86)\arduino" anymore. I saw in other simillar examples that the avrdude.exe path is referenced as "Applications\Arduino\", yet that path does not exist on my Arduino IDE version either. The installation path for my Arduino IDE instance appears to be "C:\Users\*user*\AppData\Local\Programs\Arduino IDE\", and in that directory there is no trace of avrdude.exe.
I'm therefore assuming that the latest versions of the Arduino IDE have a different method of compiling & uploading sketches without avrdude.exe, so I'm assuming that the batch sketch uploading method using avrdude.exe referenced in the previous post answer does not work anymore with the latest versions of the Arduino IDE.
Moreover, this specific example appears to always specify specifically what type of boards to upload to (atmega328p in the specific example above), and what I'm looking for is a method of uploading to several different types of microcontrollers.

A different StackExchange answer provided a method of uploading a sketch to several Arduinos connected in series. However, what I'm looking for is a method of mass-uploading to several microcontrollers in parallel, all connected to separate COM ports.

Another Arduino Forums post showcases a method of mass-uploading via a custom-made circuit that uses another Arduino NANO to "forward" the code to several Arduino NANOs. However, this method relies on an intermediary microcontroller for "forwarding" the code to the remainder of the connected microcontrollers through a custom circuit, yet what I'm looking for is just uploading to a bunch of microcontrollers connected in parallel via several USB connections to COM ports on my Windows system.

Is it possible to mass-upload a single Arduino INO sketch to several different microcontrollers via some sort of batch script on a Windows 10 system? What kind of a Windows batch script, if any, would achieve such a goal?
Thanks for reading my post, any guidance is appreciated.

You can configure the IDE to be verbose during the upload. If you do so, it should show you the specific command it uses for uploading. I bet it still uses avrdude, although its installation location may have changed. Once you know the command, you may try to adapt your batch script.

Simplest to just copy a known working version of the avrdude program (with its config) in the same folder as the batch script, just to keep it simple?

If your Arduino IDE version is 64-bit it is installed in C:\Program Files instead of C:\Program Files (x86)


text:
TMRpcm not compatible incompatible with current board
My goal is to play sounds with my Arduino Nano Every. I tried the example sketch that comes with the library but I get the error:
**WARNING: library TMRpcm-master claims to run on avr architecture(s) and may be incompatible with your current board which runs on megaavr architecture(s).**

Is there such a big difference between the Nano and Nano every?

All the peripherals (timers, comms, programming etc. etc) have changed so code which directly accesses hardware registers (say to configure a timer) may fail. Some libraries already have some compatibility. Others may never be updated. If you have to get the MCU data sheet out to solve low level device access/control issues, you'll find yourself in a new world. You could try opening an incompatibility issue for this particular library here: https://github.com/TMRh20/TMRpcm/issues

I opened a issue on GitHub and the result is: tmrpcm only runs on avr architecture so it is incompatible with megaavr architecture(s).


text:
reading device or board specific properties from the Arduino MKR WiFi 1010 device
How to read programmatically the device specific properties from the Arduino MKR WiFi 1010 chip or board?
For example, following properties of the device:

any identification number, that can uniquely identify the physical device, integer or GUID or string or any other, how to read that from the code?
SerialNumber of the MRK WiFi 1010 device
ModelNumber of the MRK WiFi 1010 device

I have tried to check the documentation and examples, however I couldn't find anything at all.

MAC address is unique. https://www.arduino.cc/reference/en/libraries/wifinina/wifi.macaddress/

MAC address could be of use to you, but remember that it can be spoofed. Aside from that Serial and Model numbers are not accessible from software layer.
Here is a simple implementation for fetching the MAC address
    #include <WiFiNINA.h>

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

      if (WiFi.status() == WL_NO_MODULE) {
        Serial.println("Communication with WiFi module failed!");
        while (true);
      }

      byte mac[6];
      WiFi.macAddress(mac);
      Serial.print("MAC: ");
      for (int i = 5; i >= 0; i--) {
        if (mac[i] < 16) {
          Serial.print("0");
        }
        Serial.print(mac[i], HEX);
        if (i > 0) {
          Serial.print(":");
        }
      }
      Serial.println();
    }

    void loop() {}

Another solution that I can think of is writing your own unique identifier such as UUID to EEPROM memory for each board.
If you're generating a UUID in the context of a server or a device with more resources, there are libraries and tools that can create these for you based on various factors to ensure uniqueness (like timestamp, MAC address, etc.). However, with a microcontroller like the one on the Arduino MKR WiFi 1010, you have a more constrained environment, and the process can be more manual.
You can use an online UUID generator or can generate it using Python:
    import uuid
    print(uuid.uuid4())

After generating your UUID's, you can write them on EEPROM but make sure to not over-write EEPROM since it has very limited call boundaries.
Writing to EEPROM
#include <EEPROM.h>

const char* MY_UUID = "550e8400-e29b-41d4-a716-446655440000";
const int EEPROM_UUID_ADDRESS = 0;  // starting address in EEPROM

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

  // Write UUID to EEPROM
  for (int i = 0; i < strlen(MY_UUID); i++) {
    EEPROM.write(EEPROM_UUID_ADDRESS + i, MY_UUID[i]);
  }
  Serial.println("UUID written to EEPROM");
}

void loop() {}

"starting address in EEPROM" is the address of the first box (or byte) where the program begins storing our UUID. By specifying const int EEPROM_UUID_ADDRESS = 0;, we are saying we'll start storing the UUID from the very first byte (box) of the EEPROM. If you were storing other data in EEPROM, you would need to ensure that the addresses don't overlap. For example, if you had other data stored in the first 10 bytes, you might set EEPROM_UUID_ADDRESS to 10 to start storing the UUID from the 11th byte.
Reading from the EEPROM:
#include <EEPROM.h>

const int UUID_LENGTH = 36;  // Length of the UUID string
char readUUID[UUID_LENGTH + 1];  // +1 for the null terminator
const int EEPROM_UUID_ADDRESS = 0;  // starting address in EEPROM

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

  // Read UUID from EEPROM
  for (int i = 0; i < UUID_LENGTH; i++) {
    readUUID[i] = EEPROM.read(EEPROM_UUID_ADDRESS + i);
  }
  readUUID[UUID_LENGTH] = '\0';  // Null terminate the string

  Serial.print("UUID read from EEPROM: ");
  Serial.println(readUUID);
}

void loop() {}

+1 for the null terminator:
In the C and C++ programming languages, strings are represented as an array of characters. The end of the string is marked by a special character known as the "null terminator" or "null character", which is represented by the value '\0' (a byte with all bits set to 0).
When we read or write strings to/from memory (like EEPROM), we often need to account for this null terminator to ensure the string is properly terminated and can be safely used with string functions.
In the code, the UUID is 36 characters long. When we declare an array to hold this UUID with the line:
char readUUID[UUID_LENGTH + 1];

We're allocating space for the 36 characters of the UUID plus an additional character for the null terminator, hence UUID_LENGTH + 1.
Later, after reading the UUID from EEPROM, we ensure this array is a properly terminated string by adding the null terminator:
readUUID[UUID_LENGTH] = '\0';

This ensures that when we use readUUID in functions that expect a string, they'll recognize where the string ends. Without the null terminator, these functions wouldn't know where the string finishes, leading to unpredictable behavior or errors.
I hope that this is helpful.

thanks. There are few more ways to get the board information, it is USB device serial number, which is stored in the FTDI chip. However, the Arduino can't read from the FTDI chip, and second way is like this: if defined (__AVR_ATmega2560__)

yes, I am aware that FTDI chip contains the USB device serial number but I have came to realise that sometimes chip producers assign the same VID and PID numbers to different boards they produce. if you want to read values from the FTDI chip you can use Python by the way. using serial and ftdi you can get the first available FTDI device serial number and send it to Arduino via COM3 Serial. if you wish i can demonstrate how to do it. using "if defined (AVR_ATmega2560) " would not distinguish between two ATmega boards would it?

correct, using if defined (__AVR_ATmega2560__), won't allow to distinguish between two ATmega boards.

would you like to try the -very hard way of- reading the FTDI on your OS and then sending it to ArduinoIDE? looks like a nice challenge to work on.

I think, that there is no much difference between storing the UUID and serial number from the FTDI chip into the EEPROM. It has to be stored in the same way

there is no FTDI on MKR WiFi 1010. the MCU has native USB. and it has an accesible serial number

Ah, thanks for letting us know Juraj, you seem correct. I assumed it uses FTDI as shekhovtsov claimed so. MKR WIFI 1010 uses SAMD21 which has a datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf
and it seems like the addresses for serial number are: 0x0080A00C, 0x0080A040, 0x0080A044, 0x0080A048 ----- word 0 to 3. one could just read them like: id[0] = *(volatile uint32_t *)0x0080A00C; and so on...

The IDE shows the serial number so I looked into the SAMD core and found the function which reads the serial number from registers. It is in the CDC.cpp file
uint8_t Serial_::getShortName(char* name) {
    // from section 9.3.3 of the datasheet
    #define SERIAL_NUMBER_WORD_0    *(volatile uint32_t*)(0x0080A00C)
    #define SERIAL_NUMBER_WORD_1    *(volatile uint32_t*)(0x0080A040)
    #define SERIAL_NUMBER_WORD_2    *(volatile uint32_t*)(0x0080A044)
    #define SERIAL_NUMBER_WORD_3    *(volatile uint32_t*)(0x0080A048)

    utox8(SERIAL_NUMBER_WORD_0, &name[0]);
    utox8(SERIAL_NUMBER_WORD_1, &name[8]);
    utox8(SERIAL_NUMBER_WORD_2, &name[16]);
    utox8(SERIAL_NUMBER_WORD_3, &name[24]);
    return 32;
}

from the datasheet of SAMD21:

Each device has a unique 128-bit serial number which is a concatenation of four 32-bit words contained at the
following addresses:

The uniqueness of the serial number is guaranteed only when using all 128 bits


text:
Low power RF decoder possible?
I'm building a panic button project for my grandma which uses a 433MHz RF remote keyfob and a 3.3v Pro Mini connected to an RF receiver, a buzzer and an led. The purpose is that whenever she needs assistance like in the middle of the night, she could simply press the keyfob button and the Arduino will act as an alarm and would go off, alerting me and others. So far I have set everything up and the project works exactly as intended.
How can I further reduce the power consumption on the receiver end of this project so that I can run it using batteries for a long time, like 6 months or so?
The battery I have in mind is either a single 3.2v 5000mAh LiFePo4 battery or 3x AA 2600mAh NiMH Low self discharge cells in series.
My current setup for the receiver has an always active 433MHz RF receiver which draws around 5mA while running at 5v and an Arduino Pro Mini which should consume about another 5mA. I'm using the RC switch Library and the project is currently powered by a USB wall adapter. I haven't used any low power or sleep functionality before so I'm not very informed on those methods.

The biggest saving can be made by making your sketch just always transmit and nothing else. Then put the button in the power connection. Press the button, the power turns on, the Arduino transmits. In fact you could even do away with the Arduino altogether.

But my arduino doesn't transmit anything. It just receives the code the keyfob will send.

Ah, I misunderstood. Ignore that then.

I am not familiar with using the RC switch library, but if you're using a pin that is an interrupt it may be possible to go to sleep and wake when that pin changes state. You may miss the first transmission from your button, but I would hope there would be multiple transmissions sent so you would capture the next one.

why does the receiver need to be battery powered? That's quite unusual as these sorts of things go...10ma isn't that bad. I can see some tweaks halfing that, but that still doesn't really help make or break the feasibility. You have to be awake to answer the phone...

@Majenko Yes, the receiver will be plugged into the interrupt pin. Missing the first transmission is not a problem, the person needing help will press the button multiple times. I think your idea will work out.

@Majenko The reciever needs to be battery powered mainly because the power supply in my country is very unreliable. If the project cannot be run on a battery for an extended period of time, then I'm willing to modify it to have a battery backup system instead. Either way a battery will be involved, preference will be for the low power long backup option.