text:
Combining the code of MAX30100 and DS-18B20
sorry to ask this but I am very very new to Arduino.
My project aims to collect the skin temperature by 18B20 and the heart rate & SPO2 level by MAX30100.
I have tested the codes for the respective sensors and they work fine, but when i am trying to merge these two codes together, only 18B20 works and 30100 isn't delivering any information (Heart rate:0.00bpm / SpO2:0%). Is there a way to combine these two codes? Thank you very much!
Code of 18B20
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into digital pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

void setup(void)
{
  sensors.begin();  // Start up the library
  Serial.begin(9600);
}

void loop(void)
{
  // Send the command to get temperatures
  sensors.requestTemperatures();

  //print the temperature in Celsius
  Serial.print("Temperature: ");
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print((char)176);//shows degrees character
  Serial.print("C  |  ");

  delay(500);
}

Code of 30100
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS     1000

PulseOximeter pox;
uint32_t tsLastReport = 0;

void onBeatDetected()
{
    Serial.println("Beat!");
}

void setup()
{
    Serial.begin(115200);
    Serial.print("Initializing pulse oximeter..");

    // Initialize the PulseOximeter instance
    // Failures are generally due to an improper I2C wiring, missing power supply
    // or wrong target chip
    if (!pox.begin()) {
        Serial.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
    }
     pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

    // Register a callback for the beat detection
    pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
    // Make sure to call update as fast as possible
    pox.update();
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        Serial.print("Heart rate:");
        Serial.print(pox.getHeartRate());
        Serial.print("bpm / SpO2:");
        Serial.print(pox.getSpO2());
        Serial.println("%");

        tsLastReport = millis();
    }
}


text:
RP2040 RTC alarm or similar function
I have a rp2040 board using Earl E. Philhower core. I would like to use the rtc functions just like the one mentioned in the sdk. Especially the alarm function which is critical in my project.
Supposedly from what i know you have access to all the functions in the sdk on the arduino IDE but when i tried out the example in the sdk it would not compile saying that rtc functions are not declared
char datetime_buf[256];
char *datetime_str = &datetime_buf[0];

    datetime_t t = {
            .year  = 2020,
            .month = 06,
            .day   = 05,
            .dotw  = 5, // 0 is Sunday, so 5 is Friday
            .hour  = 15,
            .min   = 45,
            .sec   = 00
    };

void setup() {
    Serial.begin(9600);
    Serial.println("Hello RTC!");

    rtc_init();
    rtc_set_datetime(&t);
}

// the loop function runs over and over again forever
void loop() {
        rtc_get_datetime(&t);

        Serial.println(datetime_str);
        sleep_ms(100);             // wait for a second
}

Earl E. Philhower comes with a Time sketch example but problem is i could not find a documentation if a alarm like function exist
/* Simple demonstration of setting and printing the current time */
/* The initial time will need to come from an RTC, NTP, or user */

/* Released to the public domain by Earle F. Philhower, III <earlephilhower@yahoo.com> */

#include <time.h>
#include <sys/time.h>

void setup() {
  Serial.begin(115200);
  delay(5000);
  struct timeval tv;

  tv.tv_sec = 1611198855; // Jan 21, 2021  3:14:15AM ...RPi Pico Release;
  tv.tv_usec = 0;
  settimeofday(&tv, nullptr);
}

void loop() {
  time_t now;
  char buff[80];

  time(&now);
  strftime(buff, sizeof(buff), "%c", localtime(&now));
  Serial.println(buff);
  delay(1000);
}

Did you #include "hardware/rtc.h" when trying to use the RTC from the SDK?

@Majenko Yes, it could not find the library. fatal error: hardware/rtc.h: No such file or directoryResolveLibrary(hardware/rtc.h)

You can try to use my RP2040_RTC Library, especially this RP2040_RTC_Alarm example.
Both ArduinoCore-mbed and Earle Philhower arduino-pico cores are supported.

This looks nice, it even has example on how to get time via, ethernet which is one of the reason for the alarm, i need to update the time every 6 hours.

by the way , is this a hardware implementation of RTC?

Yes. It's the RP2040 hardware RTC, as mentioned in section 4.1.21. hardware_rtc of Raspberry Pi Pico-C/C++ SDK

Cool, thank you for making the library :)

I have a question about alarms, if the alarm goes off it triggers an interrupt right? and just like how standard interrupts work, it will stop whatever its doing and process that interrupt right?

Yes. Check the ISR code here  RP2040_RTC_Alarm.ino#L54-L58. The ISR just sets a flag and flag is read and processed in loop() at RP2040_RTC_Alarm.ino#L179-L186

Another question, how many alarms can be set at a given time?

source: Stack Exchange

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

sort: votes


text:
Arduino and PCA9685 - Suddenly stopped working
I'm using an Arduino Uno and a PCA9685 board to run 4 servos (of type MG996R).
For that, I set up the following connections:

SCL -> SCL
SDA -> SDA
Ground -> GT
VCC -> 3.3V

As the servos require high current under draw, I've used an external power supply that is also connected to the PCA9685 at the intended place. The power supply is at 6V (DC) - and max 3 ampere.
Everything just worked fine for about 1 month. Then, suddenly the servos did not move anymore.
What I checked:

the power supply still gives the desired 5-6V at the PCA9685 board
I bought a new PCA9685 board
I used another power supply at 5.2V and max 2 ampere (only 1 servo connected)

The strange thing is that even with the new PCA9685  board and power supply, the servos don't move. However, they move if a remove the external power supply and connect the v+ pin of the PCA9685  to the arduino's 5V output pin.
You have any idea whats going on or what might be broken?

sounds like the external power supply is not powering the PCA9685 board

It would help if you posted links to each of the hardware devices and a schematic, not a frizzy thing. Do this after you verified that the pull ups for the I2C are correct and all the grounds are connected.

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


text:
ESP8266 ESP-12E: SD2 (GPIO 9) causing reboot when pulled low
I'm working on a project with reed switches, which are connected between a GPIO pin (in pullup mode) and ground. With some of my NodeMCU ESP-12E boards (HiLetGo brand) that I ordered, whenever the reed switch on GPIO9/SD2 is closed, the board is rebooting. However, some of these same boards do not exhibit this same behavior - the reed switch on this pin works correctly.
The reset reason is Fatal exception:4 flag:1 (WDT)
Is there any reason that some boards would work while others don't? Is this pin generally safe to use as an IO pin? I need at least 8 GPIO pins to work per board, and I'm having a hard time finding enough of them.
Here's my code, for reference
int REED_PIN = 9;
void setup() {
  Serial.begin(9600);
  Serial.println("Setup");

  pinMode(REED_PIN, INPUT_PULLUP);
  Serial.println(ESP.getResetInfo());
}

// the loop function runs over and over again forever
void loop() {
  int proximity = digitalRead(REED_PIN);
  if (proximity == LOW) {
    Serial.println("Magnet detected");
  }
}

GPIO9 is connected to the flash memory chip on the NodeMCU. It should not be used as a general I/O. You can find out more about what NodeMCU pins you can use and for what purposes, on this page

use pin 10 instead and set the flash to DIO to free it up.


text:
Need Help with HTTPClient.h and storing cookies
Im very new to Arduino. Using an ESP32, Im trying to login to a network device to read its log file. To login to the device I need to simulate a web browser with cookies.
The ESP32 is connecting to WiFI correctly, and Im including the HTTPClient.h file
Using http.begin I am able to browse to the device login page, but I dont know how to store the successful login in a cookie.
From doing some research I think that cookies are just HTTP headers, but I'm not really sure how to read/parse/resend the cookie header in another HTTP request.
I can successfully do it in PEARL using CURL (my code is below). Can someone help me port this to ESP32
use strict qw/refs/;
use HTTP::Cookies;
use LWP::UserAgent;
use HTTP::Request::Common qw/POST GET/;

my $Browser = LWP::UserAgent->new(
cookie_jar => HTTP::Cookies->new,
requests_redirectable => ,
timeout => 10,
pragma => "no-cache",
max-age => 0,
agent => "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0"
);

my $Page = $Browser->request(GET $Authenticate);

already posted at https://forum.arduino.cc/t/need-help-with-httpclient-h-and-storing-cookies/924772


text:
RP2040 example sketch for dual core queuing
I would like to use queuing because i think its best for my application. I have very limited experience in dual core programming all i want is to hopefully pass 32 bit numbers to the second core properly. queuing seems to be good because it makes sure that the second core who is receiving the data wont miss anything in the sequence if data comes in very fast and core 2 is not ready to process it.
But Im having trouble finding examples. I did find one but its for a runner queue, which i think is a bit different to what i want
Can anyone show me an example sketch? what i would really like to see is core 1 adding to the queue and core 2 retrieving and removing data from the queue

If all you  want to pass is 32-bit numbers the FIFO is better suited to your needs.

But that said, Queue or FIFO it's the same (you just have to create a queue before you use it). Push stuff on one end, and pop it off the other (both with optional blocking).

@Majenko I did read about FIFO but decided not to because of the note in the sdk, it is suggested that you do not use the FIFO for your own purposes unless none of the above concerns apply; the majority of cases for transferring data between cores can be eqaully well handled by using a queue  Do you have some simple examples of the queue i can look at?

Yeah, I saw that after I posted the comment ;)

@Majenko Do you think you can show me how to use queue sir? :)

After digging around i was able to use the queue_t from the sdk. and here it is
queue_t queue;

typedef struct queueItem {
  uint32_t value;
} item;

const int QUEUE_LENGTH = 128;

void setup() { //CORE 1 setup

  Serial.begin(9600);
  while (!Serial);
  queue_init(&queue, sizeof(item), QUEUE_LENGTH); //initialize the queue

}

void loop() { //CORE 1 TIGHTLOOP

  queueItem temp;
  temp.value = random (1000);
  if (queue_try_add(&queue, &temp)) { //adding items to the queue
    Serial.print("ADDING:\t");
    Serial.println(temp.value);
  }

  else
    Serial.println("FIFO was full\n");
  delay(500);
}

void setup1() { // CORE2
}

void loop1() {  //CORE 2 TIGHTLOOP

  queueItem temp;
  while (queue_try_remove(&queue, &temp)) { //retrieving item from the queue and deleting it from the queue
    Serial.print("ITEM RETRIEVED:\t");
    Serial.println(temp.value);
  }

  delay(500);

}

This requires a thread-safe queue, where one thread writes to the queue, and another thread reads from the queue.
But I find that with a little care, you can just use a circular buffer where the consumer will increase the head, and the producer will increase the tail.
Something like this:
#define MAXSZ 80
static int buff[MAXSZ];
static int head=0;
static int tail=0;

bool full(void)  { return (tail+1)%MAXSZ == head; }
bool empty(void) { return head==tail; }
int  usage(void) { int num = tail-head; return num<0 ? num+MAXSZ : num; }

int produce(int val)
{
   if ( full() ) return -1;
   buff[tail] = val;
   tail = (tail+1)%MAXSZ;
   return 0; // signal success.
}

int consume(void)
{
   if ( empty() ) return -1;
   int val = buff[head];
   head = (head+1)%MAXSZ;
}

This will work as long as your compiler doesn't do crazy re-ordering of the operations, and as long as you only touch the head with the consumer, and only touch the tail with the producer. Also, the assignments of head/tail need to be atomic, not split up as: tail++ ; tail = tail%MAXSZ;
Come to think of it: if a small capacity suffices, like the 80 from the example code, I would use int8_t for head/tail, just in case writing an int to memory gets context-switched between writing the LSB and MSB parts. (I don't know RP2040 well enough to know if writing an int is atomic.)

So the buffer will just grow larger and larger as more data is transfered? Wont that eventually eat all the memory the more data is passed?

No, the buffer in the example has 80 slots reserved, and will never use more memory. The used slots vary between 0 and 79, so you can't have the consumption lag too much, as the buffer will be full. Both the head and tail will wrap-around as they reach 80th index. Once you consume a value, its slot is now available for queuing in a new value.

How do i know how many are in queue? because from what i undestand looking at it, data in the buffer never gets deleted, just overwritten when the array wraps around.

You can check for the number of valid elements by iterating through the queue from head to tail, counting the needed iterations until you reach the tail. An element is only valid, when its between head and tail (inclusive head, exclusive tail)

@DrakeJest Just look at the distance between head/tail for the number of used slots. See the usage() function that I added.


text:
M5 Lora module and Nano - does not receive / transmit
I'm working on my first Arduino project using LoraWAN8688 ASR6501 M5 module. I would like one nano to send message, and another nano to receive and read it.
I believe they are not sending or receiving data. I can see Transmission led flashing on one of them, but not Receive led on another.
I think, that my Lora module must be configured before it will be used to send and receive data from Arduino.
How can I send AT+ commands to the LORA module to configure it? Do I need any additional cables or connectors, or can I use Arduino to set it up?
Can I use Serial.println("AT+ADDRESS=1"); to set address via andruino?

RECEIVER CODE:
String incomingString;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("AT+ADDRESS=3");
}

void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()){
incomingString = Serial.readString();
if (incomingString.indexOf("TeamA") >0){
delay(500);
}
}
}

TRANSMITTER CODE:
unsigned long lastTransmission;
const int interval = 1000;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("AT+ADDRESS=2");
}

void loop()
{
if (millis() > lastTransmission + interval) {
Serial.println("AT+SEND=1,6,TeamA");
delay(2000);
lastTransmission = millis();
}
}

the 9 V battey consists of four AAAA cells ... it is questionable that it has the capacity to power your project


text:
Arduino native USB port and Simulink
I am trying to communicate through the native USB port of the Arduino Due with a PC.
The native port itself works, I have tested this. The problem is, that every time I upload my Simulink model via the programming port onto the Arduino, Windows loses the connection to the native (Bossa) port.
It does not recocnize the port anymore after programming the Arduino with Simulink (Arduino Support Package). The only way to get Windows to recognise the port again is holding reset+erase on the Arduino, which obviously deletes my application.
Do you know any solution? Is this possible to get the native port working for communication after using Simulink to deploy my application?

ditch simulink for arduino programming and use arduino ide and code?  simulink should be able to produce C code you can then patch into the ide in the form of headers.

the native USB is handled by the program running in the MCU. if you upload a program which doesn't do it or doesn't work at all, then there will be no working USB on native port

Are you initializing a serial connection in the Simulink code? If not there won't be one and you loose connection when the actual code starts. The main code needs to do that.please show us what you have got in Simulink. Though it might be that we cannot help you since we are no experts in Simulink

Got it working myself by simply writing the communication part in C for the Due, not using the Simulink blocks.


text:
Arduino data-types
(Im new to the arduino side of stackexchange). Im working on a worksheet for to begin with arduino. I have prior experiences working with arduinos, but problem is new for my field of expertise. Any help will be well appreciated (need help pls uwu)
Problem statement:

I tried different methods to obtain those values, but all are to vain.
Methods that I tried so far:

using limits.h, floats.h and inbuild variables of those library -- Problem: Im getting wrong minimum and maximum values for float and double:
Code:

#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <math.h>

char fltmax[250];
char fltmin[250];
char dblmax[250];
char dblmin[250];

void sint() {
  Serial.print("Range of signed int: ");
  Serial.print(INT_MIN);
  Serial.print(" to ");
  Serial.print(INT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(int));
  Serial.println(" bytes");
}
void usint() {
  Serial.print("Range of unsigned int: 0 to ");
  Serial.print(UINT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned int));
  Serial.println(" bytes");
}
void schar() {
  Serial.print("Range of signed char: ");
  Serial.print(SCHAR_MIN);
  Serial.print(" to ");
  Serial.print(SCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed char));
  Serial.println(" bytes");
}
void uschar() {
  Serial.print("Range of unsigned char: 0 to ");
  Serial.print(UCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned char));
  Serial.println(" bytes");
}
void slong() {
  Serial.print("Range of signed long: ");
  Serial.print(LONG_MIN);
  Serial.print(" to ");
  Serial.print(LONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed long));
  Serial.println(" bytes");
}
void uslong() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(ULONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned long));
  Serial.println(" bytes");
}
void sshort() {
  Serial.print("Range of signed short: ");
  Serial.print(SHRT_MIN);
  Serial.print(" to ");
  Serial.print(SHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed short));
  Serial.println(" bytes");
}
void usshort() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(USHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned short));
  Serial.println(" bytes");
}
void flt() {
  Serial.print("Range of float: ");
  dtostrf(FLT_MIN, -1, 50, fltmin);
  Serial.print(fltmin);
  Serial.print(" to ");
  sprintf(fltmax,"%e", FLT_MAX);
  puts(fltmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(float));
  Serial.println(" bytes");
}
void dbl() {
  Serial.print("Range of double: ");
  dtostrf(DBL_MIN, -1, 50, dblmin);
  Serial.print(dblmin);
  Serial.print(" to ");
  dtostrf(DBL_MAX, -1, 0, dblmax);
  Serial.print(dblmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(double));
  Serial.println(" bytes");
}

void setup() {
  Serial.begin(115200);
  sint();
  usint();
  schar();
  uschar();
  slong();
  uslong();
  sshort();
  usshort();
  flt();
  dbl();
}

void loop() {
}

Other than using dtostrf(), I found better alternatives at exchange here too such as: Print unsigned long long in ESP8266 and https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm

I tried combining both where the test code that I used before actual implementation:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <limits.h>

void setup () {
  char str[30];
  Serial.begin(115200);
  snprintf(str, 30, "Value of float max = %e", FLT_MAX);
  /*puts(str);*/
  Serial.print(str);
  return(0);
}
void loop(){

}

But puts(str) is not getting printed in the serial monitor.  Then It clicked, that I have to use Serial.(code) for it to get printed in serial monitor, but it ended up in Serial.puts(str) code not found. Then I tried just Serial.print(str), but it just outputs Value of float max = ? (Initially, before I wrote this problem here, it output Va only, which i have no idea how it changed, but its still wrong). What do I do now? also, Why cant I use puts to print in serial monitor?
The board im using for this is Arduino UNO (ATmega328P)

There are two issues here.
One is that the Arduino core uses Serial to handle serial I/O, rather
than the traditional libc interface (printf(), puts() and co.). The
avr-libc does provide the traditional stdio functions, but these will
not work unless you tell them where stdout is, which is a bit complex.
The take away is to just use the methods of Serial for accessing the
serial port.
Then there is the question: why did it print “Value of float max = ?”.
The reason is that the avr-libc does not provide by default support for
formatting floating point numbers with sprintf(). That support is
quite expensive in flash space, and it is omitted unless you link with a
specific version of the avr-libc. The simple workarounds are:

Use Serial.print() to both format and print floating point numbers,
which is inconvenient for very small or very large numbers.
Use dtostre() or dtostrf() to format them.

In your case, dtostre() is a better fit:
void setup() {
    char val[40];
    Serial.begin(9600);
    Serial.print("Range of float: ");
    dtostre(FLT_MIN, val, 5, 0);
    Serial.print(val);
    Serial.print(" to ");
    dtostre(FLT_MAX, val, 5, 0);
    Serial.print(val);
    Serial.println();
}

void loop(){}

prints:
Range of float: 1.17549e-38 to 3.40282e+38

Ahh I see, I'll read up the documentation of dtostre(), my guess its similar to dtostrf(), but the output is rather %e instead of %f, but I'll read just in case. Also, I just found out that DBL_MIN and FLT_MIN does not provide the absolute minimum of the data type but rather the positive minimum value :) I'll just add a dash symbol manually and use DBL/FLT_MAX for the minimum value. Though its not ethical/code of stackexchange to say thank you in the comments, I'll still thank you, i've been stuck on this question for the past week :'(


text:
I2C / TWI: set up atmega328p as slave
I try to run an atmega328p as a i2c slave. even with the bare minimum the slave acts as its not wired at all: NACK is transmitted after request (see logic analyzer).
The master should read a constant value in this example. iam using the wire.h lib. pullup resistors on SDA, SCL 4.7kOhm.
master.ino: esp8266 (working, sends requests)
#include <Wire.h>
#define DEFAULT_SLAVE_ADDRESS 0x0A
void setup()
{
  Wire.begin(); // join i2c bus as master
  Serial.begin(9600);
  Serial.println("\n Hello");
  delay(2000);
}
void loop()
{
  //Wire.beginTransmission(DEFAULT_SLAVE_ADDRESS);
  //Wire.write(0);
  //Wire.endTransmission();
  //delay(10);
  Wire.requestFrom(DEFAULT_SLAVE_ADDRESS, 1);
  Serial.println(Wire.read());
  delay(1000);
}

slave.ino: atmega328p
#include <Wire.h>
#define F_CPU 8000000UL
volatile uint8_t nr;
void setup()
{
  Wire.begin(0x0A);                // join i2c bus with address #4
  //Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent);
}
void loop()
{
}
//void receiveEvent(int howMany)
//{
//  while(0 < Wire.available()) // loop through all but the last
//  {
//  int x = Wire.read();    // receive byte as an integer
//  }
//}
void requestEvent()
{
  nr = 99;
  Wire.write(nr);
}

Serial output from master: (got no val)
-1
-1
...

Logic analizer output:

Wiring on atmega:
VALUE-PIN

VCC 7
GND 8
SCL 28
SDA 27

anyone got an idea whats missing?
Edit: removed receiveEvent(), added CPU speed and it worked

You seem to have a problem only with the read operation at the moment. I would remove the onReceive part to troubleshoot the problem and test if the example code works (https://www.arduino.cc/en/Tutorial/LibraryExamples/MasterReader).

esp8266 is usually 3.3V while atmega328p is 5V - do your hardware setup take it in account? And have the voltage on SDA,SCL the right values for HIGH and LOW on BOTH master and slave?

Can you make your 328P's loop() do something, like blink an led so that you know the 328P is operational and at the correct frequency?

@SimSon thanks for your reply. when i removed the receiveEvent it worked. i figured out the the problem is the Wire.available() function on the atmega.

@gilhad the ATmega can be operated at 3.3V, I guess that's the case here. The ATmega also NACKs the read header, which means the address has been transmitted successfully. That doesn't make it look like a hardware issue.


text:
sizeof tm struct (datetime) different on ESP32 vs linux64x
I am logging binary data to my SD. I log a datetime object of type 'tm', which is 36 bytes on ESP32.
When I create a datetime of type 'tm' on linux it is 56 bytes.
ESP32 write tm to SD:
[tm datetime = 36 bytes]
time_t t = std::time(nullptr);
tm datetime = *std::localtime(&t);
uint16_t t = file.write((const uint8_t *)&datetime, sizeof(datetime)); // ==36 bytes.

PC
[tm datetime = 56 bytes] (compiled using g++ on linux 64)
tm datetime;
std::ifstream fileStream(filename, std::ios::binary);
fileStream.read((char *)&datetime, sizeof(datetime));

tm is defined in time.h:
struct tm
{
  int   tm_sec;
  int   tm_min;
  int   tm_hour;
  int   tm_mday;
  int   tm_mon;
  int   tm_year;
  int   tm_wday;
  int   tm_yday;
  int   tm_isdst;
#ifdef __TM_GMTOFF
  long  __TM_GMTOFF;
#endif
#ifdef __TM_ZONE
  const char *__TM_ZONE;
#endif
};

My tm struct doesn't have the 'tm_gmtoff' or 'tm_zone', even if it had it wont add up to 56 bytes.
How can my tm be 56 bytes on my PC?
If someone has a better way to log a datetime object, without this issue, let me know.

sizeof(int) on arduino (AVR) is 2, on most other platforms its 4.

Why log in binary? Log as text, in the format of date +'%FT%T%:z'. If you really need binary, log time_t rather than strcut tm.

@PMF I'm using ESP32, didn't specify, my bad!

@EdgarBonet logging to text is too slow, I log at 100hz using sd.h lib. why is logging time_t better in binary?

Then don't write the entire struct but by elements, making your own data structure.

The layout of strcut tm is implementation dependent. In contrast, time_t is usually a simple integer, with very little variations across implementations: either 32 or 64 bits, and maybe a different epoch (which is fixed by simply adding a constant).

On top of that you have the problems of alignment and data access sizes. The entries in a struct will be aligned to addresses that will be dictated by what the underlying architecture is able to access (if it can only read/write whole words every byte will be aligned on a word boundary bloating your struct). You should never use system level structs in data storage or transmission (unless they're designed specifically for that). Instead define your own and pack them to remove any alignment and padding issues.

You can not trust system-level structs for data storage or transfer between different systems. The main reasons are:

Different data type sizes (16 / 32 / 64 bit ints, floats vs doubles, etc)
Struct element alignment differences owing to underlying architecture optimizations and limitations

Unless you are working with a system struct that is specifically designed for cross-system communication you must define your own and pay special attention to the layout.

Always use explicitly sized variable types (uint8_t, int32_t, etc for example) to ensure both ends always agree on data storage sizes
Always "pack" your struct (__attribute__((packed))) to collapse any specially aligned variables into just the room needed to store those variables

Point 2 requires special attention if you're doing much more than filling the struct and saving / transmitting it. It's advisable to never do more than create the struct instance, fill it, save it, then throw it away. If you start doing advanced operations with pointers to the struct you risk corrupting the packing code if the alignment changes. Also packed structs are often slightly slower to access owing to more complex code usually needed to be used to read / write the individual fields within them (especially if there are no byte-wise operations in the underlying architecture).

Thank you! multiple people commented solutions, but you gave the reason why. Also thanks for your blogpost, very helpful!


text:
My port is grayed out?
Hello I have a question on why my port is grayed out when I go to upload?
I’ve watched so many YouTube videos on what’s the problem and have been trying to do everything but just nothing seems to work! Also, in device manager under ports (COM & LPT) the ports have an error sign over it. If someone can help me through this that would be fantastic!
The error when uploading:
problem uploading to board.
Sketch uses 2838 bites (8%) of program storage space. Maximum is 32256 bytes . Global variables use 9bites (0%) Of dynamic memory, leaving 2039 bites for local variables. Maximum is 2048 bytes.avrdude: ser_open(): can’t open the voice “\.\COM”: The system cannot find the file specified.

In the device manager you can also open the details windows for that device (don't remember how it is called exactly in the context menu when you right click on the device. Please tells us what error message you can find there. Maybe you need to install the correct driver.

Error : Windows cannot determine the settings for this device. Consult the documentation that came with the device and use the resource tab to set the configuration.(code 34)

Be sure you have the appropriate driver loaded.

Genuine Arduino or CH340 based chinese clone?


text:
Bootload from a Nano to an ATMega328 without a crystal
I have a program to load from a Aduino Nano as ISP to a ATMega328p chip that will have an internal clock at 16M, but I don't have a crystal handy.
Is there a way I can not have to buy a crystal? What should be the circuit's look like?
Here's how I have it hooked:

Ground to Ground (Pin 8)
5V to VCC (Pin 7)
D10 to Reset (Pin 1)
D11 to MOSI (Pin 17)
D12 to MISO (Pin 18)
D13 to AVCC (Pin 20) (There are no resistors or capacitors, that all was part of a tutorial I cannot find anymore)

So I'm testing now with the basic Blink sketch and here is the resulting terminal comments.
/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
Using board 'atmegax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
Using core 'megax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
Detecting libraries used...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /dev/null
Generating function prototypes...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a
Linking everything together...
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/../arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a -L/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -lm
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.eep
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -R .eeprom /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex
/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-size -A /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf
Sketch uses 924 bytes (2%) of program storage space. Maximum is 32768 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/cu.usbserial-AC012GAB -b19200 -Uflash:w:/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/Users/b77/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-AC012GAB
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x000000 (retrying)

An error occurred while uploading the sketch
Reading | ################################################## | 100% 0.05s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

From what I've seen online, the device signature being 0x000000 could potentially mean that the lack of crystal may make it impossible for me to do the bootloading. The chip is also brand new and I've tested with more than one as I have 3.
My thought is that I probably read the tutorial wrong especially with the AVCC pin?
In any case, how should I connect a Nano to an ATMega328p without a crystal?
Thanks for your help!

The internal oscilator is 8Mhz on the ATMega328P. You could use the 3.3V 8Mhz Arduino Pro Minis bootloader. But make sure you set the fuses correctly, so it's doesn't use the crystal as a clock source. The only downside is that the RC oscillator isn't as accurate as a crystal, so Serial/UART may not work correctly.

Alright. After reading some and some more, I was able to notice that SCK, just one pin down from AVCC, was the missing link.
Yet another reminder to properly read the fabulous manual.
It looks so easy now.


text:
multiple blinking LEDs at different intervals, morse code A included
Good evening,
I am writing Arduino code to flash multiple LEDS at different sequences from different pins. Everything is working well, however I cant determine how to add in a Morse Code A flash sequence.
Ideally the sequence would go 1s, on 1s off, 3s on, 3s off. then repeat continuously, this would be for a MO (A) bouy
Below is the format I have used for all other lights and works well with 8 different sequences.
// A is 1s, B is 2.5s, C is 4s, D is 5s, F is 6s, G is 8s, H is 10s ,

#define aLed 2
#define bLed 3
#define cLed 4
#define dLed 5
#define fLed 6
#define gLed 7
#define hLed 8

void setup() {
  pinMode(aLed, OUTPUT); //pin2 Output
  pinMode(bLed, OUTPUT); //pin3 Output
  pinMode(cLed, OUTPUT); //pin4 Output
  pinMode(dLed, OUTPUT); //pin5 Output
  pinMode(fLed, OUTPUT); //pin6 Output
  pinMode(gLed, OUTPUT); //pin7 Output
  pinMode(hLed, OUTPUT); //pin8 Output

}

void loop() {
  BlinkA(1000);
  BlinkB(2500);
  BlinkC(4000);
  BlinkD(5000);
  BlinkF(6000);
  BlinkG(8000);
  BlinkH(10000);

}
 void BlinkA (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(aLed, !digitalRead(aLed));
 }
}
void BlinkB (int interval){
   static long prevMill = 0;
   if (((long)millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(bLed, !digitalRead(bLed));
  }
 }
  void BlinkC (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(cLed, !digitalRead(cLed));
 }
}
 void BlinkD (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(dLed, !digitalRead(dLed));
 }
}
 void BlinkF (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(fLed, !digitalRead(fLed));
 }
}
 void BlinkG (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(gLed, !digitalRead(gLed));
 }
}
 void BlinkH (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(hLed, !digitalRead(hLed));
 }
}

to format the code listing, put ~~~ on a blank line before the code ... and same on a blank line after the code

what is your question?

Would this answer be helpful? https://arduino.stackexchange.com/a/48588/37523

Re “1s on, 1s off, 3s on, 3s off”: That would be keying at 1.2 words per minute! Nobody, not even a complete beginner, goes that slow. If you want someone to be able to read the “A” before they get bored, you should not go below ≈ 5 WPM (240 ms on, 240 ms off, 720 ms on, 720 ms off).

@EdgarBonet Unless he wants to simulate the blinking of a lighthouse. They might go this slow and occassionally use morse code patterns.

https://github.com/MajenkoLibraries/Blinker

https://github.com/MajenkoLibraries/MorseStatus

multiple blinking LEDs at different intervals, (not all periodic)...

I changed your question hopefully with out changing its meaning.
Based on this question, I would suggest using a finite state machine.  Assuming you are using differently named "BlankI()" functions for each LED, consider adding state machine features to 1 of these functions to control the "not periodic" LED.  Consider a state machine with 4 state one for each action:

LED On for 1 second.
LED Off for 1 second.
LED On for 3 seconds.
LED Off for 3 seconds.

Use a counter (either global or static to preserve its value between calls to that function) to track the states.  Use a switch/case coding pattern to set the "prevMill" to the appropriate time delay for the current state.


text:
Arduino ESP32 Import Error No module named serial
I googled and couldn't find a solution to my nice problem:
I have Ubuntu and I want to program a ESP32 ...............
I tried a lot of pip commands ... but it didnt work.
You have any idea how to install the correct packages?
Maybe you can tell me what to do. I am really lost.
I tried it last year and also failed.. Now I want to try it another time :)
   /.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py", line 38, in <module>
        import serial
    ImportError: No module named serial

Open terminal and enter this command python -m pip install pyserial it will download pyserial for you and you will not receive the above error. The above error is because you don't have pyserial installed on the system.
The related documentation for pyserial could be found here

python -m pip install pyserial
/usr/bin/python: No module named pip

@jento you will first need to install pip I considered you have pip installed to install pip use the following command sudo apt install python3-pip for python3 or you can use sudo apt install python-pip for python 2

How about doing this but in a virtualenv, so not installing packages system wise?

I had the same issue compiling the CameraWebServer example. I'm using Ubuntu 20.04. The problem occurs during the linking stage when the script invokes python. On my system this runs the system python which is python 2.7.18. I don't think the serial module (supplied by pyserial) is available on Ubuntu 20.04 for python 2.x.
My solution was first to abandon the Arduino IDE and use the arduino-cli to compile the example. I created a virtual python 3 environment, activated it, installed pyserial under the virtual environment and run arduino-cli to make the runtime. The python scripts appear to be compatible with python 3.

the arduino esp32 python scripts work with python 2 and you can install pyserial into python 2.

I'm not sure it's available for 2.7.18. In any case, I did not want to install libs into the system python just to make a runtime when I can use a virtual env.

Problem resolved, Thank you.  I had installed pyserial.  The error surprisingly was related to the incorrect processor speed (!) in the Arduino IDE.  I have no idea why that would influence the serial/pyserial function.

Reference: https://www.how2shout.com/linux/how-to-install-python-2-7-on-ubuntu-20-04-lts/
I think Arduino IDE expects Python2 to be installed. My Version is Arduino-1.8.13
You also need Python2 modules so you need to install pip2
:~/curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
:~/sudo python2 get-pip.py
:~/pip2 install pytools
:~/pip2 install pyserial


text:
i have problem in generating pwm in steps
Given below is my loop and it counts 1 to 250 using the push button i just added this part as this one is the main part. I want to make it in steps like one press (push button) SETS IT TO 10 OR 20 ETC. Many thanks in advance for your kindness.
if ((digitalRead(2)==HIGH) && (digitalRead(7)==LOW))
 {
   if (j<255)
   {j++;
   lcd.setCursor(5,1);
   lcd.print("                ");
   lcd.setCursor(5,1);
   lcd.print(j);
   while((digitalRead(2)==HIGH) && (digitalRead(7)==LOW));}
 }
else if ((digitalRead(2)==LOW) && (digitalRead(7)==HIGH))
 {
   if (j>0)
   {j--;
   lcd.setCursor(5,1);
   lcd.print("                ");
   lcd.setCursor(5,1);
   lcd.print(j);
   while((digitalRead(2)==LOW) && (digitalRead(7)==HIGH));}
}

analogWrite(9,j);
//lcd.noDisplay();
lcd.display();
delay(100);

}

the title says i have a problem ... there is nothing said about a problem in your post ... what happens when you run the program?

Where is j defined? What do you see on the LCD?

If you want to change j in bigger steps, just replace j++ and j-- by for example j+=10 and j-=10. Though I suspect that thats not all of the problem

I actually added the part in which i was having trouble so the j was defined at the start of the code while i have posted the main part of the code (not the full code). I think comment from Chrisl has solved the problem i was facing, i'll try it later and update it here if its solved. Thanks a lot for your precious time.

Finally thanks Chrisl to understand my question and helping me out. It worked.


text:
Issue with input from weighing scale controlling a stepper motor based valve
Hello and thanks for any help in advanced.
What changes do I need to make to my code to get rid of the issue of the valve opening up again at end of cycle in "Auto" function.
Hardware:

Arduino Mega
Bi-polar Stepper Motor connected to Valve.
Weighing scale with TTL output.

Here is my code:
//Buttons
#include <mechButton.h> //Button Library
#define BTNa_PIN  10    //Button Pins
#define BTNb_PIN  6
mechButton aButton(BTNa_PIN);  // Set button to pin BTN_PIN.
mechButton bButton(BTNb_PIN);

//Stepper
#include <AccelStepper.h> //Stepper Library
#define dirPin 4          //Stepper Pins
#define stepPin 2
#define motorInterfaceType 1 //Interface set to driver
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);// Create a new instance

//Analog inputs for setting Max and Min Distance
const int analogPin = A0;
const int analogPin2 =A1;

//Data types for Scale Reading for Optima OP900a
char inString[32];
float Input;
float Setpoint;
float fSetpoint;

//Setup
void setup() {

  Serial.begin(9600);           // Fire up our serial monitor for arduino and computer
  Serial3.begin(9600);          //Fire up Serial for Scale for input

  aButton.setCallback(Manual);    // Set up our callback. (Also calls hookup() for idling.)
  bButton.setCallback(Auto);
  stepper.setMaxSpeed(3500);      // Set the maximum speed and acceleration for stepper motor:
  stepper.setAcceleration(5000);

  Setpoint = 4.44;               // Auto parameters
  fSetpoint = (Setpoint*0.9);

}
// Main Loop
void loop() {
   bool abuttonState;
   bool bButtonState;

   idle();                      // Let all the idlers have time to do their thing.
   abuttonState = aButton.trueFalse();    // Have a look at what the current button state is.
   bButtonState = bButton.trueFalse();
}
//Sub Functions
void Manual(void) {
    int maxOpen = analogRead(analogPin);
    maxOpen = map(maxOpen, 0, 1023, 0,100);

   Serial.print("Manual ");
   if (aButton.trueFalse()) {
      stepper.moveTo(0);
      stepper.runToPosition();
   } else {
      stepper.moveTo(maxOpen*40);
      stepper.runToPosition();

   }
}

void Auto(void) {
    int maxOpen = analogRead(analogPin);
    int minOpen = analogRead(analogPin2);
    maxOpen = map(maxOpen, 0, 1023, 0,100);
    minOpen = map(minOpen, 0, 1023, 0,100);

   while (Input < Setpoint){
     readScale();
     if (Input >= fSetpoint && Input < Setpoint){
     stepper.runToNewPosition((minOpen*10)+400);  //Blocking function research work around...
     Serial.print("Min");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else if (Input < fSetpoint) {
     stepper.runToNewPosition(maxOpen*40);         //Blocking function research work around...
     Serial.print("Max");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else{
     stepper.runToNewPosition(0);                 //Blocking function research work around...
     Serial.print("Close");Serial.print(",");     //debugging
     Serial.println(Input);                       //debugging
     }
     }
}

void readScale(void){
    byte inChar = Serial3.readBytesUntil('\n', inString, 18); //Scale reading for input
    float scaleInput = atof(&inString[7]);
    Input = scaleInput;
  }

I keep getting this strange behavior at the end of the "Auto" function where I am getting false 0.00 from the scale that causes the valve to open and close fully at the end.
Max,0.01
Max,0.01
Max,0.01
Max,0.00
Max,0.00
Max,0.00
Max,0.00
Max,0.35
Max,0.42
Max,0.51
Max,0.60
Max,0.66
Max,0.69
Max,0.75
Max,0.83
Max,0.88
Max,0.93
Max,1.00
Max,1.05
Max,1.11
Max,1.16
Max,1.21
Max,1.26
Max,1.32
Max,1.38
Max,1.43
Max,1.48
Max,1.53
Max,1.59
Max,1.64
Max,1.68
Max,1.74
Max,1.80
Max,1.84
Max,1.89
Max,1.94
Max,1.99
Max,2.04
Max,2.09
Max,2.14
Max,2.18
Max,2.23
Max,2.27
Max,2.32
Max,2.37
Max,2.41
Max,2.45
Max,2.50
Max,2.55
Max,2.59
Max,2.62
Max,2.68
Max,2.72
Max,2.76
Max,2.81
Max,2.85
Max,2.88
Max,2.93
Max,2.97
Max,3.00
Max,3.04
Max,3.08
Max,3.13
Max,3.17
Max,3.20
Max,3.23
Max,3.27
Max,3.31
Max,3.35
Max,3.39
Max,3.42
Max,3.46
Max,3.50
Max,3.52
Max,3.55
Max,3.60
Max,3.63
Max,3.66
Max,3.69
Max,3.73
Max,3.77
Max,3.80
Max,3.83
Max,3.87
Max,3.91
Max,3.94
Max,3.95
Max,3.98
Min,4.03
Min,4.06
Min,4.09
Min,4.13
Max,0.00
Max,0.00
Min,4.35
MZ��r��j
Min,4.36
Close,4.46

Any suggestions are welcome.
Thanks

There are a few issues here:

Serial3.readBytesUntil() does not add a null character at the end of
the string. You have to do it yourself if you want a properly
terminated string.

You are attempting to read a float starting at the eight byte of the
string, even if you got less than eight bytes.

atof() does not report errors. If it fails to parse a float, it just
returns zero.

Just to see what may be going wrong, I suggest this version of
readScale() with verbose debug output:
void readScale(void) {
    byte inChar = Serial3.readBytesUntil('\n', inString, 18);
    inString[inChar] = '\0';  // terminate the string
    const char *start = &inString[7];  // where the number is expected
    char *end;  // where strtod() found it ends
    float scaleInput = strtod(start, &end);
    Serial.print("Scale -> \"");
    Serial.print(inString);
    Serial.print("\", parsed \"");
    *end = '\0';  // terminate the string after the number
    Serial.print(start);
    Serial.print("\" as ");
    Serial.println(scaleInput);
    Input = scaleInput;
}

That helped a lot!  The first time I hit the auto button it works perfectly.  But the more times I hit it the error keeps coming back.  Do you think this has something to do with buffer overflow?
stepper.runToNewPosition is blocking therefore it could be interrupting the serial3.readBytesUntil

Maybe. Or it could be the debug messages slowing down the code. Does the scale pause between messages? Does it help to set a higher baud rate on Serial?

the serial stalls for a good ~1s while moving to maxOpen.   I cranked the baud to 115200  no change.  I think using the accelstepper library always get me into trouble and in the end never use it.  Time to rewrite everything in millis().

Scale -> "US,NT,+  US,NT,+  ", parsed "" as 0.00
Scale -> " 4.34lb", parsed "" as 0.00
This is the serial error with your better parsing.

Do you think adding an if(Serial.available() > 0) would help?

If you don't want the Accelstepper library to block, then why don't you write your code non-blocking? The Accelstepper library is totally capable of that. Look the the examples which call the run() function regularily. That function is meant for non-blocking action

I know it is but the whole reason I was using the accelstepper library was for the ramping because the valve has significant static friction and ramping allows it to over come the issue and run at max speed without stalling.


text:
Serial communication between Python & Arduino:
I need to transfer information between pyton script and arduino.
Data is always built like this "wheelbase:1000"
wheelbase can be another word and 1000 can be another value, : is always the separator
Here is my python code:
import serial.tools.list_ports
import serial
import time

ports = list(serial.tools.list_ports.comports())

for p in ports:
    print(p)

mcustring = str(ports[0]).split(" ")[0]
print(mcustring)

mcu = serial.Serial(mcustring, 9600)
mcu.timeout = 0.1

def write_read(x):
    mcu.write(x.encode())
    time.sleep(0.05)
    data = mcu.readline()
    return data

num = "wheelbase:1000\n"

for i in range(10):
     print(i)
     num = "wheelbase:1000"
     value = write_read(num)
     print(value) # printing the value
     time.sleep(1)        # wait 0.5 seconds
     num = "wheelbase:500"
     value = write_read(num)
     print(value) # printing the value
     time.sleep(1)

value = write_read(num)
print(num) # printing the value
time.sleep(1)

mcu.close()

and here is my arduino code:
String SerialRead1;
String SerialRead2;
double Wheelbase = 0;
double Level0 = 0;
double Gradient = 0;

void setup() {
  // put your setup code here, to run once:
Serial . begin ( 9600 ) ;        // turn on Serial Port
pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {

  while (Serial.available() > 0) {
  SerialRead1 = Serial.readStringUntil(':') ;
  SerialRead1.trim();
  SerialRead2 = Serial.readStringUntil('\n') ;
  SerialRead2.trim();

  Serial.print ( "string1: " ) ;
  Serial.println(SerialRead1);
  Serial.print ( "string2: " ) ;
  Serial.println(SerialRead2);

  }

  if (SerialRead1 == "wheelbase"){
   Wheelbase = SerialRead2.toDouble();
  }

  if (SerialRead1 == "level"){
   Level0 = SerialRead2.toDouble();
  }

  if (SerialRead1 == "gradient"){
   Gradient = SerialRead2.toDouble();
  }

if (Wheelbase == 1000) {
    digitalWrite(LED_BUILTIN, HIGH);
}
else
{
    digitalWrite(LED_BUILTIN, LOW);
}

}

Here is my serial outpout:
COM6 - USB-SERIAL CH340 (COM6)
COM6
0
b''
b''
1
b''
b'string1: wheelbase\r\n'
2
b'string2: 1000\r\n'
b'string1: wheelbase\r\n'
3
b'string2: 500\r\n'
b'string1: wheelbase\r\n'
4
b'string2: 1000\r\n'
b'string1: wheelbase\r\n'
5
b'string2: 500\r\n'
b'string1: wheelbase\r\n'
6
b'string2: 1000\r\n'
b'string1: wheelbase\r\n'
7
b'string2: 500\r\n'
b'string1: wheelbase\r\n'
8
b'string2: 1000\r\n'
b'string1: wheelbase\r\n'
9
b'string2: 500\r\n'
b'string1: wheelbase\r\n'

I don't understand why , for i=0 qnd i = 1 the dqtq is not correctly transfered/received.
The LED blink correctly for i = 2 to 9


text:
ESP32 TCP disconnect takes very long to be recognized
I'm using the following class to create a stream from a WiFi (server) connection. The client (a PC application) connects to the ESP32 and then issues commands over this connection. This works fine. When the client disconnects gracefully, the connection is reset and the ESP32 is ready for another connection. Only one client can connect at a time, but that's ok for now.
The problem arises when the client disconnects unexpectedly (e.g. if I just kill the process on the PC). The connection remains open for a very long time (10 minutes or so) until the ESP32 detects that the connection died. Within that time, no new connection can be established. In that state, I can still see it printing "Still connected" messages to the serial console, with reducing pace (the number of messages per second drops significantly until it finally gives up).
Is there a way to reduce the timeout on a dead connection? The (working) connection itself might be idle for long times as well, so just because no messages are received doesn't mean we can drop the connection from the ESP32 end.
The Connect() function below is called from loop() and in normal mode, it just prints "New client connected" and "client disconnected" messages.

class WifiCachingStream : public Stream
{
private:
    WiFiServer _server;
    WiFiClient _activeClient;
    bool _hasActiveClient;
public:
    WifiCachingStream(int port) :
    _server(port), _activeClient()
    {
        _hasActiveClient = false;
    }

    void Init()
    {
        _server.begin();
    }

    bool Connect();

    int read() override;

    size_t write(byte b) override;

    void maintain();

    int available() override
    {
        return _activeClient.available();
    }

    int peek() override
    {
        return _activeClient.peek();
    }

    void flush() override
    {
        // Do nothing. The implementation of WifiClient clears the _INPUT_ queue instead of the output queue!
        // _activeClient.flush();
    }

    bool isConnected() const
    {
        return _hasActiveClient;
    }
};

int idx = 0; // for testing only
bool WifiCachingStream::Connect()
{
    if (_activeClient.available() || _activeClient.connected())
    {
        if ((idx ++) % 10000 == 0)
        {
            // For testing: This is printed to the console, even after the communication has been killed on the PC
            Serial.println("Still connected");
            // This (attempts to) send a message over the link, which I would expect to cause the implementation to detect that the connection was dropped.
            Firmata.sendString(F("Still connected"));
        }
        return true;
    }

    _activeClient.stop();
    _activeClient = _server.accept();

    if (_activeClient)
    {
        Serial.println("New client connected");
        WiFi.setSleep(false);
        _hasActiveClient = true;
        return true;
    }

    if (_hasActiveClient)
    {
        _hasActiveClient = false;
        Serial.println("Client disconnected - entering WiFi low-power mode");
        // Low-power mode significantly increases round-trip time, but when nobody
        // is connected, that's ok.
        WiFi.setSleep(true);
    }

    return false;
}

// Other functions irrelevant

It's more or less a fact of life that having TCP detect a lost connection (ungraceful disconnect) takes a long time when nothing is being sent over it.
There may be some quaint and curious keepalive and time-out settings in the protocol itself, but implementing a heartbeat (call it an application-level keep-alive) that is sent by the client, and closing the connection from the ESP32-end when no heartbeat/keep-alive message has been received for a certain period, is probably your best bet and it will also give you precise control over the time-out time.

I'll consider this, but I don't really have control over the protocol. Adding a heartbeat message has been discussed, but not approved yet. I need to check that thread.


text:
How do I connect 20 outputs and 20 inputs to an Arduino board?
I am a mechanical engineer starting my journey with Arduino, so please excuse me if I put some very generalized message.

I need to sequentially operate 20 output relays, and then verify if the correct relay has been triggered. If the correct relay was triggered, the next relay will be triggered after a delay of 1-2 seconds.
I plan to do this with an Arduino Uno so that I can generate error messages if any output has not been triggered.

However, the Uno doesn't have sufficient inputs and outputs to do this. So what are my options?
I want to ask you the below:-

If there are I/O expansion boards available for the Uno? If yes, sharing the details will be helpful;
A friend recommended to use a multiplexer. Can I use a multiplexer to convert a 4 pin output from the Arduino to 16 pin output, and probably use the saved pins to monitor the inputs? If yes, how?
Is there something available like a reverse multiplexer wherein the chip can convert the 16 output signals to 4 pin inputs to the Arduino?

Please let me know the best solution wrt the below parameters - reliability of operation, cost, compactness.
Thanks for your time and support.

use a multiplexer to convert a 4 pin output from arduino to 16 pin output ... no, use a de-multiplexer for that, but that would energize only one relay at a time

please describe in detail how the relays are supposed to behave

your question is not arduino specific ... it is off topic here ... better fit at https://electronics.stackexchange.com/questions

At any moment of time, only 1 relay will be switched on. I plan to use the Normally open connection of relay to switch on a motor. The "normally closed" connection will taken as a input to verify that only one relay has switched on. I hope this is what you meant to ask. The reason why i asked here is to ask if there are any I/O expansion boards for Arduino uno

Is there something available like a reverse multiplexer ... that is incorrect ... you are describing a multiplexer here ... https://hackaday.com/wp-content/uploads/2016/08/mux-demux.gif

@jsotola That’s a bit harsh? It’s a beginner question about connecting to arduino. Hard to see it as off topic.

@RowanP how can it be arduino specific? ... the question would be the same if the OP used RPi or beaglebone or any microcontroller ... also, it is not a question that asks how to interface a switch to an arduino

@jsotola That’s true. But OP is not asking about those other microcontrollers. They are asking about the specific Arduino context. There are good answers already provided that stay in that context, they will be valuable to other readers beginning with Arduino.

Look for port expansion boards for the arduino, there are a lot of them many under a dollar. Typically they are in 8 or 16 channel designs. They probably will have PCF8574 or PCF8575 chips. These are low voltage (typically 5V) for the Arduino. You will have to use an interface if it is connected to another voltage. Each of these modules the channels can be individually programmed as an input or output. You can turn on or any of the outputs in any order and pattern you want. These devices operate with the I2C interface so you need only two lines from the Arduino to drive up to 8 of these modules. The pins should be labeled A4 (SDA), A5 (SCL) depending on the model of Arduino you have. Good luck!

There is a useful comparison of PCF8575 versus MCP23017 I2C port expanders on the Arduino forum. https://forum.arduino.cc/t/i2c-port-expanders-pcf8575c-vs-mcp23017/260337

Instead of using expansion boards, you could use an Arduino Mega or an Arduino Due instead. These have more than enough GPIO pins for 20 inputs and 20 outputs. The price isn't much higher compared to the extra expansion board and the extra wiring required.

If going this route keep in mind that the Mega is 5V (like the Uno) but the Due runs on 3.3V. You’ll likely want to match to your selected relays and sensors.


text:
FastLED: "Invalid pin specified" when specifying LED_TYPE from WS2811 to WS2801
I'm trying to run the "DemoReel 100" code from FastLED.
Out of the box, it can be verified.  But when I switch from #define LED_TYPE    WS2811 to #define LED_TYPE    WS2801, I get the error:

error: static assertion failed: Invalid pin specified
static_assert(validpin(), "Invalid pin specified");

the line this error originates from is:
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

I can't think of any reason that the LED_TYPE argument should change whether or not a data-pin is valid.  What's going on?

I figured it out.  There's two lines for FastLED.addLeds, and one needed to be commented out and the other enabled in order have a clock pin work.
//  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);


text:
State machine problem
I am trying to record the pulses from a water flow sensor using a state machine. My goal is to count the pulses until the flow stops (i.e. the rotor inside comes to rest). This will constitute a single reading. if there is no new pulse/interrupt 5 seconds after the rotor is stopped, the total pulse count is printed and pulse count is reset to zero for the subsequent readings.
However, in practice, I get a pulse count even when the sensor rotor is moving. The pulse count gets resets after 5 sec but the pulses between the new reading and until the rotor is stopped are somehow missed.
Could you please help me figure what am I doing wrong?
#include <Arduino.h>
#include <TelnetStream.h>

const byte pulsePin = 22;
byte volatile triggerCounter = 0;

byte newState = 0;

unsigned long newTime = 0;
unsigned long oldTime = 0;

unsigned long pulseCountNew = 0;

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR handleInterrupt()
{
  portENTER_CRITICAL_ISR(&mux);
  triggerCounter++;
  portEXIT_CRITICAL_ISR(&mux);
}

void stateMachine()
{

  switch (newState)
  {

  case 0 /* Reset */:
    newState = 1;

    break;

  case 1 /* Start */:

    if (triggerCounter > 0)
    {
      newState = 2;
    }
    break;

  case 2 /* Pulse count start */:

    pulseCountNew++;
    triggerCounter--;
    newTime = millis();
    newState = 3;

    break;

  case 3 /* Pulse count stop */:

    if (triggerCounter > 0)
    {
      newState = 2;
    }

    if (newTime - oldTime >= 5000)
    {
      oldTime = newTime;
      newState = 4;
    }
    break;

  case 4 /* Cycle complete */:
    newState = 0;
    TelnetStream.println("State 4");

    break;
  }
}

void setup()
{
  pinMode(pulsePin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pulsePin), handleInterrupt, FALLING);
  TelnetStream.begin();
}

void loop()
{

  if (newState == 4)
  {

    TelnetStream.println(pulseCountNew);
    pulseCountNew = 0;
  }

  stateMachine();
}

The pulse count gets resets after 5 sec ... don't reset the counter ... refer to how millis() is used

do you have less than 255 readings in one batch? you use byte

The code will have a mich better readability if you use makros or an enum for the state, so you can have something like case RESET:...

You should have all code that is relevant for the state machine in the switch block. The TelnetStream.println() might be ok in thw loop(), but pulseCountNew=0 should be in case 4.

triggerCounter is declared as byte, so it can't become negative. The statements triggerCounter-- and if(triggerCounter>0) are error prone and probably don't what you expect.

@SimSon I didn't know about enum but you are right. Need to learn it's  usage

@Juraj I suppose you are talking about trigger counter being declared as type byte. Since in the state 2, the trigger will be decremented so I thought the count wouldn't go as high as 255. But thinking about it now I assume that may happen

yes it is possible to always take the value, add it to total and reset. I don't know how fast the value increments in your project. using byte is good because the operations are atomic and don't require to block interrupts. but using larger type allows spending more time in loop without checking the counter and that helps if you do networking.

I do this usually without an extra state variable.
unsigned long readSensor() {
  const unsigned long READING_TIMEOUT_MILLIS = 5000;
  static unsigned long lastReadingMillis;
  static unsigned long lastCounterValue;

  noInterrupts();
  unsigned long counter = triggerCounter;
  interrupts();

  if (counter != lastCounterValue) { // if new reading
    lastReadingMillis = millis(); // reset timout timer
    lastCounterValue = counter;
  } else if (counter > 0 && (millis() - lastReadingMillis) > READING_TIMEOUT_MILLIS) { // if something was counted and is timeout
    noInterrupts();
    triggerCounter = 0;
    interrupts();
    lastCounterValue = 0;
    lastReadingMillis = 0;
    return counter;
  }
  return 0;
}

void loop() {
  unsigned long value = readSensor();
  if (value) {
    Serial.println(value);
  }
}

sorry, the code is not tested.

I thought using a simple state machine would be simpler than using  multiple conditional statements. However, your example is much more compact.


text:
How to use ESP32 ESP32 config flag in platformio?
I build my ESP32 project from platformio and I'd like to change CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT in order to reduce the RAM footprint.
I don't get how to do that: should I modify my platformio.ini?

If you are using arduino-esp in platformio, then you have to build the sdk yourself.

Simply put, you have to update your platformio.ini as assumed in the question as follows (see last line):
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    adafruit/Adafruit NeoPixel@^1.10.0
    plerup/EspSoftwareSerial@^6.13.2
    miwagner/ESP32CAN@^0.0.1
    nilsminor/TMP117-Arduino@^1.0.2
    lbernstone/Tone32@^1.0.0
board_build.partitions = no_ota.csv
build_flags = -DCONFIG_MBEDTLS_DYNAMIC_BUFFER


text:
Disable Keyboard.h status LED
As soon as I include keyboard.h my pro micros LED starts flashing (as far as I know this indicates a serial connection is stablished or so.)
But it's really annoying having a flashing led on my desk all the time.
Is there an option to disable this 'debugging' behaviour from the keyboard.h libary?

Those LEDs are controlled by the USB Core code, and are defined in the board variant.  For the pro micro that's the pins_arduino.h file in the micro variant:
#define TXLED0          PORTD &= ~(1<<5)
#define TXLED1          PORTD |= (1<<5)
#define RXLED0          PORTB &= ~(1<<0)
#define RXLED1          PORTB |= (1<<0)
#define TX_RX_LED_INIT  DDRD |= (1<<5), DDRB |= (1<<0), TXLED0, RXLED0

If you edit that file and remove everything after the macro name, so you have 5 empty macros, it should disable the LEDs completely.
#define TXLED0
#define TXLED1
#define RXLED0
#define RXLED1
#define TX_RX_LED_INIT

Edit:
For the Sparkfun Pro Micro, edit the file at
...\AppData\Local\Arduino15\packages\SparkFun\hardware\avr\1.1.13\variants\promicro

This is because it has an extra package that is not installed by default.

Didn't work for me. I even deleted them completly, but no error nothing. Maybe I am in the wrong directory or do I need to recompile something? Do I need to change it at some different place since the pro micro needs extra libaries to function anyways?
The full path I used : C:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\micro\pins_arduino.h

If you had to install more boards packages (I have not used that board) then the file will be in that package somewhere.

Works now :D.
If anybody is interested: The file you need to edit is at
...\AppData\Local\Arduino15\packages\SparkFun\hardware\avr\1.1.13\variants\promicro
It's a bunch of stuff in the file. You need to look for a second to find the keywords but they are there.

it's really annoying having a flashing led on my desk all the time.

As a software engineer I know we often fall into the trap of thinking that all problems must have a software solution. Try thinking of this as a hardware problem.

Cut out a small piece of a sticky label and stick it over that annoying LED.
Use a soldering iron to remove the offending LED.
Use needle-nosed pliers to crush the offending LED.

The more destructive solutions can be reversed with a soldering iron and maybe a new SMD LED. For Arduinos with female or stacking headers you could instead reinstate the feature by plugging a thru-hole LED and resistor into the appropriate positions in the Arduino's header sockets. E.g. D13 and GND. For other Arduinos by adding LED and resistor in adjacent positions in a breadboard.
There might be a good software solution but it can be worth considering other approaches.


text:
PCA9685 - Hardware problem with diode?
I'm working on a project, where I need to run several high-torque servos. For that I bought come of these PCA9685 boards.
I hooked everything up with my arduino and connected an external 5V - max 3A power supply for driving the servos. After some succesful tests, the board seems to be broken as no servo move anymore.
With my multimeter I looked for the broken component and found the following - in front of the transistor is, in my opinion, a ten diode with label Y4 installed - At the input (right) are still 5 V, but no longer at the output and accordingly not at the V+ pins of the servo connectors.

According to the internet, a ten diode has a maximum of 300mW, which for 5V results in 60mA, which of course is less then my servos require.
Do you agree with me? Could this be the problem?
If so, do you know the "correct" PCA board that is able to power high torque servos?

Yes, I concur with your diagnosis. You can use that board fine, just don't provide the 5V to the servos from it - connect them direct to the power supply.

Newer versions of the board (based on the Adafruit design https://github.com/adafruit/Adafruit-16-Channel-PWM-Servo-Driver-PCB) replace that section with a AOD417 Mosfet. See the "reverse voltage protection" section of the schematic at the same link location. I've not had any trouble running hobby servos  from the revision C board.


text:
How to make Arduino to read 1X4 keypad multiple times?
I want to use 1X4 membrane keypad to enter  3 working parameters for LED string controlled by  Arduino mini. Keypad is attached to D2-D5 pins and LED is attached to pin 12. My objective is to set the following parameters:
frequency (4 values),
duty cycle (4 values),
run time 4 (values).
I need  Arduino to read keypad 3 times so I can enter  3 parameters. "Run time" In the sketch below has not been set. I want to use “while” to force Arduino to read the keys but arduino reads it once.  Only first “while” is working in the code and I can set cycle period. Second “while” does not work because the key has been already pressed and Arduino does not read keypad second time. Are there any means to use more than 1 "while" in the code or to use one while to read keypad 3 times?
Thank you.
   #define Key1 3 // key 1 attached to pin 3
    #define Key2 2 // key 2 attached to pin 2
    #define Key3 5 // key 3 attached to pin 5
    #define Key4 4 // key 4 attached to pin 4
    float period; // cycle time
    float power; // duty cycle
    float ontime; // ontime  time LED is on
    float rest;  // rest time LED is off
    const int ledPin =  12;      // the number of the LED pin

    void setup()
    {
      pinMode(Key1, INPUT_PULLUP);
      pinMode(Key2, INPUT_PULLUP);
      pinMode(Key3, INPUT_PULLUP);
      pinMode(Key4, INPUT_PULLUP);
      pinMode(ledPin, OUTPUT);
    }
    void loop() {
      digitalWrite(ledPin, LOW);
      while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

      int key1a = digitalRead(Key1);
      int key2a = digitalRead(Key2);
      int key3a = digitalRead(Key3);
      int key4a = digitalRead(Key4);

      if (!key1a) {
        period = 1000;
      }
      if (!key2a) {
        period = 2000;
      }
      if (!key3a) {
        period = 3000;
      }
      if (!key4a) {
        period = 4000;
      }

      while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

      int key1b = digitalRead(Key1);
      int key2b = digitalRead(Key2);
      int key3b = digitalRead(Key3);
      int key4b = digitalRead(Key4  );

      if (!key1b) {
        power = 10;
      }
      if (!key2b) {
        power = 20;
      }
      if (!key3b) {
        power = 50;
      }
      if (!key4b) {
        power = 80;
      }

      ontime = period * power / 100;
      rest = period - ontime;

      digitalWrite(ledPin, HIGH);
      delay(ontime);
      digitalWrite(ledPin, LOW);
      delay(rest);
    }

I want to use “while” ... why? ... what if it makes no sense to use "while"?

What makes sense?

it would make more sense to detect a button press at begining of loop() and set a variable to 0, 1, 2, 3 or 4 ... 0 = no button ... use a state variable to keep track of which parameter you are changing

Do something to wait until a key is released before advancing to the next section. It would be wise to structure your program to have only one function that processes key presses, and then call it for each key. (Pass key identification, pin number, into the function.)


text:
Doubt in coding part in blink without delay
Code 1 (here unsigned long currentmillis = millis() is in loop area):
const int LED = 2;
unsigned long previousmillis = 0 ;
const long delaytime = 1500;
int ledstate = HIGH;

void setup() {
 pinMode(LED,OUTPUT);
}

void loop() {
  unsigned long currentmillis = millis();
  if (currentmillis - previousmillis >= delaytime) {
    previousmillis = currentmillis;
    if (ledstate == HIGH) {
      ledstate = LOW;
    } else{
      ledstate = HIGH;
    }
    digitalWrite(LED,ledstate);
  }
}

Code 2 (here unsigned long currentmillis = millis() is above void setup()):
const int LED = 2;
unsigned long previousmillis = 0 ;
unsigned long currentmillis = millis();
const long delaytime = 1500;
int ledstate = HIGH;

void setup() {
 pinMode(LED,OUTPUT);
}

void loop() {
  if (currentmillis - previousmillis >= delaytime) {
    previousmillis = currentmillis;
    if (ledstate == HIGH) {
      ledstate = LOW;
    } else {
      ledstate = HIGH;
    }
    digitalWrite(LED,ledstate);
  }
}

Code 1 is working and Code 2 is not working. What is the significance of the position of unsigned long currentmillis = millis() here and why?

This is a common misunderstanding for Arduino beginners.
In the second code you do
unsigned long currentmillis = millis();

outside of any function, meaning at global scope. These variables are declared at the very start of the program, even before the initial Arduino stuff is configured (like the configuration of Timer0 for getting millis() to work). The variable will have the value zero. And variables are not magically tied to a source. What you are doing there is a one-time assignment. currentmillis will not have future values of millis(). It will stay the same until you change it in your code. In your second code you do not ever change currentmillis, thus is will stay at the same value forever, preventing the code from working correctly.
In the first code the value is assigned at every loop() iteration, so you can be sure that it has a very up-to-date value of millis() when you use it afterwards.
This coding principle works exactly like you would bake a pizza, regularly looking at the clock to check the time while you are doing other things. With your first code you look very regularly at the clock to not miss the time to get the pizza out of the oven. With the second code you only look once at the clock, even before you have put the pizza in the oven, and then never again; so your pizza will burn.

Got it thanks @chrisl


text:
variable or field declared void Error
For a larger sketch, I have separated a chunk of code in a separate .cpp file
#include "msg.h"
#include <Arduino.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv)
{

    String json = payload;

    // Serial.println(json); // enable to debug

    StaticJsonDocument<128> filter;

    JsonObject filter_current = filter.createNestedObject("current");
    filter_current["temp_c"] = true;
    filter_current["wind_mph"] = true;
    filter_current["pressure_mb"] = true;
    filter_current["precip_in"] = true;
    filter_current["humidity"] = true;
    filter_current["feelslike_c"] = true;
    filter_current["uv"] = true;

    StaticJsonDocument<256> doc;

    // Deseriliaze and display error description if there is any
    DeserializationError error = deserializeJson(doc, json, DeserializationOption::Filter(filter));

    if (error)
    {
        Serial.print("deserializeJson() failed: ");
        Serial.println(error.c_str());
        return;
    }

    JsonObject current = doc["current"];
    temp = current["temp_c"];          // 80
    wind = current["wind_mph"];        // 5.6
    pressure = current["pressure_mb"]; // 1005
    humid = current["humidity"];       // 93
    feel = current["feelslike_c"];     // 6.9
    uv = current["uv"];                // 1
}

together with its header file as below:
#ifndef MSG_H
#define MSG_H

void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);

#endif

I have included all the relevant libraries in the .cpp files. However, when I try to compile the code I get multiple errors such as
In file included from src/weatherapi.cpp:1:0:
include/weatherapi.h:4:17: error: variable or field 'getRequest' declared void
 void getRequest(String &payload);
                 ^
include/weatherapi.h:4:17: error: 'String' was not declared in this scope
include/weatherapi.h:4:25: error: 'payload' was not declared in this scope
 void getRequest(String &payload);
                         ^
Archiving .pio\build\lolin32\liba47\libPubSubClient.a
In file included from src/msg.cpp:1:0:
include/msg.h:4:20: error: variable or field 'parseResponse' declared void
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                    ^
include/msg.h:4:20: error: 'String' was not declared in this scope
include/msg.h:4:28: error: 'payload' was not declared in this scope
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                            ^
include/msg.h:4:37: error: expected primary-expression before 'float'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                                     ^
include/msg.h:4:50: error: expected primary-expression before 'float'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                                                  ^
include/msg.h:4:63: error: expected primary-expression before 'int'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                                                               ^
include/msg.h:4:78: error: expected primary-expression before 'int'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                                                                              ^
include/msg.h:4:90: error: expected primary-expression before 'float'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);
                                                                                ^
include/msg.h:4:103: error: expected primary-expression before 'int'
 void parseResponse(String &payload, float &temp, float &wind, int &pressure, int &humid, float &feel, int &uv);

The function parseResponse doesn't return anything so I don't know why it's complaining about being declared as void. Same is true for the function getRequest. Also, is there something wrong in the function prototype as I am passing references?
Edit: Here is the weatherapi.cpp & .h file
#include "weatherapi.h"
#include <HTTPClient.h>
#include <Arduino.h>

const char url[] = "http://api.weatherapi.com/v1/current.json?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

void getRequest(String &payload)
{

     HTTPClient getClient;

    getClient.begin(url);

    int httpCode = getClient.GET();

    //get response and check HTTP status code returned
    if (httpCode > 0)
    {
        payload = getClient.getString();
        Serial.print("HTTP Status: ");
        Serial.println(httpCode);
    }
    else
    {
        Serial.println("Error on HTTP request");
    }

    getClient.end();
}

weatherapi.h file
#ifndef WEATHERAPI_H
#define WEATHERAPI_H

void getRequest(String &payload);
#endif

Your problems start before the code you have shown us. Specifically in (or even before) weatherapi.h. It says it doesn't know what String is - did you include Arduino.h in there?

Yes I have included Arduino.h but still the same error :(. Please see updated post

Order is important.... Arduno.h must be included before it is used...

In C order is important. Everything is parsed sequentially, and header file inclusions are replaced literally with the header contents at compile time.
Things must be defined before they can be used, and that includes anything that is defined in the Arudino.h header file - that file must be included before anything that uses it - and of course that means that it must come before any headers that use things from Arduino.h
To be safer it's good to include Arduino.h in every file that uses anything from it so you don't run into these problems in future.

Included Arduino.h in all .cpp files and it compiles without error.  Though I omitted it only in places where I thought it wasn't needed at all but perhaps it was required somewhere.


text:
`time.sleep` in python script reading serial output causes erratic behavior
I am attempting to control the position of my computer's cursor using a potentiometer hooked up to my arduino nano. The arduino is running the following code:
int potPin = 3;    // select the input pin for the potentiometer
int val = 0;       // variable to store the value coming from the sensor

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

void loop() {
  val = analogRead(potPin);    // read the value from the sensor
  Serial.println(val);
}

When I ran the following python script, it worked properly and the sensor values were printing out in my terminal.
import serial
import pyautogui

ser = serial.Serial("/dev/cu.usbserial-141220", 9600, timeout=0.1)

while True:
    data = ser.readline().decode("UTF-8").strip()
    if data:
        print(data)

However, when I added a small time delay in the while loop, the output would either get stuck on a single value or take multiple seconds to reflect a change to the potentiometer.
import serial
import pyautogui
import time

ser = serial.Serial("/dev/cu.usbserial-141220", 9600, timeout=0.1)

while True:
    data = ser.readline().decode("UTF-8").strip()
    if data:
        print(data)
    time.sleep(0.01)

I'd appreciate any help fixing this issue.

What is a small delay for you? 100ms? You are sending the values as fast as the Arduino can.

@chrisl the issue happens even with a delay in the python while loop of 10ms. I added the code with the loop to my question.

@ManavBokinala, Like chrisl said, you're sending as fast as you can.  What keeps approximately 9.6 characters per iteration from piling up in the host's inbound buffer?

You may find printing ser.in_waiting inside your loop enlightening.

@timemage Thank you so much, this solved my problem! I'm new to all of this, so I did not understand the concept of the inbound buffer. Your comment made things clear for me. I really appreciate it.

Thanks to chrisl and timemage's comments, I figured out the issue: the Arduino was sending the data too fast and the bytes were piling up in the computer's inbound buffer. I solved this by adding a delay to the loop() function of the Arduino code.


text:
Parsing JSON response from Stream
I want to parse JSON response from a GET Request. I do this usually by using a String variable to store the response and later parse this string using ArduinoJSON library like shown below:
#include <Arduino.h>
#include "OTA.h"
#include "Credentials.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char url[] = "http://date.jsontest.com/";

HTTPClient getClient;

void getRequest(String &payload)
{
  getClient.begin(url);

  int httpCode = getClient.GET();

  if (httpCode > 0)
  {
    payload = getClient.getString();
    // Serial.print("HTTP Status: ");
    // Serial.println(httpCode);
  }
  else
  {
    Serial.println("Error on HTTP request");
  }
  getClient.end();
}

void parseResponse(String &payload)
{

  StaticJsonDocument<128> doc;

  DeserializationError error = deserializeJson(doc, payload);

  if (error)
  {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  }

  const char *time = doc["time"]; // "03:53:25 AM"
  // unsigned long *epoch = doc["milliseconds_since_epoch"]; // 1362196405309
  const char *date = doc["date"]; // "03-02-2013"

  Serial.println(date);
}

void setup()
{
  setupOTA("ESP-N2", mySSID, myPASSWORD);

  Serial.begin(115200);
}

void loop()
{
  ArduinoOTA.handle();

  unsigned long newTime = millis();
  static unsigned long oldTime = 0;
  String payload;

  if (newTime - oldTime >= 5000)
  {
    oldTime = newTime;
    getRequest(payload);
    parseResponse(payload);
    Serial.println();
  }
}

I want to avoid using String and ArduinoJSON offician reference page mentions that it's possible to deserialize directly from input Stream e.g. wifiClient, ethernetclient or serial but I couldn't find any example showing it's usage. So I am curious to learn how to use it.
From my basic understanding of a Stream, I suppose I need define a buffer or memory location that will hold the incoming bytes and using the address of this buffer need to read data bit by bit. So  do I need to do something like this:
char buffer[]= httpClient.getStream();

and then pass this buffer as input to deserialize function? or have I gotten it completely wrong?

https://arduinojson.org/v6/how-to/use-arduinojson-with-httpclient/

httpClient.getStream() returns an instance of Stream that you can pass to deserializeJson(), like so:
deserializeJson(doc, httpClient.getStream());

However, by doing so, you bypass the code in HTTPClient that handles chunked transfer encoding, so you must call httpClient.useHTTP10(true) before calling GET to make sure the server won't return a chunked response.
See How to use ArduinoJson with HTTPClient?

Thanks a lot for the explanation. I am happy to learn the Stream usage. It works well but I also get                                                                                [D][HTTPClient.cpp:378] disconnect(): still data in buffer (1), clean up.
[D][HTTPClient.cpp:387] disconnect(): tcp stop.                                                                               Since I am reading all the stream data, which data it might be referring to? Can it cause an issue like memory leakage or fragmentation?

I added ChunkedStreamReader to my StreamLib. it wraps an input Stream and decodes the chunked input:  https://github.com/jandrassy/StreamLib/blob/b9b31e7908479efd0149940df9de610439532506/examples/Advanced/ReadChunkedJSON/ReadChunkedJSON.ino#L36

I followed the approach mentioned in the docs but it seems that my GET requests fail when I use http1.0. My server is running on aws (amplify) and uses http2. What should I do in this case?


text:
Can Arduino go in and out of Sleep or Deep Sleep Automatically?
I am wondering if an Arduino Uno can go in and out of deep sleep automatically with some sort of cue such as a certain time. In my case I have a small light connected to my Arduino Uno as well as a DS1302 clock module which is being powered via a phone charger but overnight the light will be off and I do not want the Arduino idling overnight. So can it be programmed to turn on/off based on the time being read from the clock which would be the same time as the light turning on? I have seen many videos of entering/exiting deep sleep but they all require a manual input such as a button. If not possible are there any other power saving options out there?

Does this answer your question? What are (or how do I use) the power saving options of the Arduino to extend battery life?

The Arduino goes into deep sleep when you tell it to. It wakes up when it gets an interrupt. What that interrupt is is (pretty much) up to you.
If you are using an RTC most will have an alarm function that will trigger an IO pin which can be used as an input (like a button) to the Arduino. Or you can use a timer (the watchdog is common for that) to wake up periodically and check the time, then go back to sleep again.
The datasheet for the MCU on your chosen Arduino will tell you all you need to know about sleep modes and what interrupts can be used to wake from which modes.


text:
Is possible to use ESP-NOW in LR mode (long range) simultaneously with WIFI STA (to connect to internet over wifi)
I am building esp-now gateway with mqtt but need long distance (200 meters).
I try to use LR mode but when I enable de LR mode I lost connection with WiFi.
Is licit to make use of LR and STA at the same time?

Are you able to use ESP-NOW at all together with Wifi? I thought this is mutual exclusive, since the same hardware is used for both

Yes but not in LR mode

you can use both by switching back and forth, but adding a 2nd ESP tied to serial is probably better to avoid message delivery delays.

you can easily use both ESPnow and WiFi - you just configure it as WiFi.mode(WIFI_MODE_APSTA);
no need to switch between AP and STA
And I have not experienced any delays for my gateway - sending MQTT message over WiFi to MQTT broker takes 6ms