text:
Problem understanding how to program DS3231 RTC
I need to send a pulse to an Arduino at every one hour. I don't need day, month, year etc. I just want a pulse from DS3231 at every 1 hour through the square wave pin.
https://github.com/NorthernWidget/DS3231
I have included this library but I can't anyhow understand how to generate an pulse at each hour using this library. Is it possible?
My requirement is simple. I need a pulse at my Arduino interrupt pin at each hour.
#include <DS3231.h>
#include <Wire.h>

void setup()
{
  Wire.begin();
  EICRA |= 0b00000011;
  EIMSK |= 0b00000001;
  sei();
 // No clue on how to setup DS3231 for getting a pulse at each hour
}
ISR(INT0_vect)
{
  // This function will be executed in each hour
}
void loop(){}

Look at the documentation that you've reference and see the turnOnAlarm() function.  I didn't dig into it but that should get you started.

I checked that too. The example was too complicated. But as far as I have understood from the example that I have to check the alarm status through I2C.

In that case let me suggest that you try some simple exercises before diving into a relatively complex device like the DTC3231.  If you just learn about how to set and read the time that would be a good start.

DS3231 address is 104. Instead of using that large complicated header, send simple frame.
For 1 sec pulse the frame will be :
S 208 A 14 A 0 P
N.B. Here address is 7 bit value 104. And a extra bit for R/W operation.
In the Arduino wire library,  you don’t need to include the R/W bit. So,just write 104.
For hourly Alam set the INT bit of control register and send simple frame like this.
Don't make things complicated using the header.

See the documentation at:
DTC3231 Library Documentation
Where there is the section on alarm bits and setting alarms:
        // Alarm functions

        void getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM);
/* Retrieves everything you could want to know about alarm
 * one.
 * A1Dy true makes the alarm go on A1Day = Day of Week,
 * A1Dy false makes the alarm go on A1Day = Date of month.
 *
 * byte AlarmBits sets the behavior of the alarms:
 *  Dy  A1M4    A1M3    A1M2    A1M1    Rate
 *  X   1       1       1       1       Once per second
 *  X   1       1       1       0       Alarm when seconds match
 *  X   1       1       0       0       Alarm when min, sec match
 *  X   1       0       0       0       Alarm when hour, min, sec match
 *  0   0       0       0       0       Alarm when date, h, m, s match
 *  1   0       0       0       0       Alarm when DoW, h, m, s match
 *
 *  Dy  A2M4    A2M3    A2M2    Rate
 *  X   1       1       1       Once per minute (at seconds = 00)
 *  X   1       1       0       Alarm when minutes match
 *  X   1       0       0       Alarm when hours and minutes match
 *  0   0       0       0       Alarm when date, hour, min match
 *  1   0       0       0       Alarm when DoW, hour, min match
 */
        void getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM);
            // Same as getA1Time();, but A2 only goes on seconds == 00.
        void setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM);
            // Set the details for Alarm 1
        void setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM);
            // Set the details for Alarm 2
        void turnOnAlarm(byte Alarm);
            // Enables alarm 1 or 2 and the external interrupt pin.
            // If Alarm != 1, it assumes Alarm == 2.
        void turnOffAlarm(byte Alarm);
            // Disables alarm 1 or 2 (default is 2 if Alarm != 1);
            // and leaves the interrupt pin alone.
        bool checkAlarmEnabled(byte Alarm);
            // Returns T/F to indicate whether the requested alarm is
            // enabled. Defaults to 2 if Alarm != 1.
        bool checkIfAlarm(byte Alarm);
            // Checks whether the indicated alarm (1 or 2, 2 default);
            // has been activated.

UPDATE:
Based on your comment:

I checked that too. The example was too complicated.

You need to spend some time gaining a familiarity with some of the basic Arduino and AVR functions.  To make this work you're going to not only need to understand how to talk to the RTC via I2C but also how to enable and respond to a pin interrupt in the AVR.  You have the ISR function there but you have not done anything to enable any interrupt source.

Trust me, I know how to enable external interrupt (also pin change interrupt of ATMEGA328p). EICRA |= 0b00000011; EIMSK |= 0b00000001;sei(); You are asking for this. Isn't it? I didn't included these as the question is about RTC instead of ISR function.


text:
Sending variable length sequence via serial from PC to Mega
I am trying to send a sequence of commands from a PC to a Mega. The Mega in turn controls 2 signal generators (AD9833's).
The sequences can vary in length but always have the same format:

A start byte of 255
The length of the sequence
Elements of the sequence: Channel 0: MSB, LSB & waveform, Channel 1: MSB, LSB & waveform

The PC side code:
import serial
import struct

usbport    = 'COM3'
ser        = serial.Serial(usbport, 9600, timeout=1)

def sendSequence(seq):

    ''' Send a sequence of frequencies along with waveform '''

    # Start byte & sequence length
    ser.write(struct.pack('>B', 255))
    ser.write(struct.pack('>B', len(seq)))

    for s in seq:

        print(s)
        MSB, LSB = (s[0] & 0xFFFF).to_bytes(2, 'big')     # Split frequency to send
        ser.write(struct.pack('>B', MSB))
        ser.write(struct.pack('>B', LSB))
        ser.write(struct.pack('>B', s[1]))                # Waveform

        combined = ((MSB & 0xFF) << 8) | (LSB & 0xFF)
        print(combined)

sendSequence([[1000, 0], [1000, 0], [2000, 0], [1000, 0], [2000, 0], [2000, 0]])
ser.close()

On the Arduino side:
#include <SPI.h>

// Set up Serial data variables
byte freq_MSB;
byte freq_LSB;
int startbyte;
unsigned long freq_seq_ch_0[16];
int wave_seq_ch_0[16];
unsigned long freq_seq_ch_1[16];
int wave_seq_ch_1[16];
int wave_select = 0;
int seq_length;
long f_2;
long f_1;

const int SINE     = 0x2000;                // Define AD9833's waveform register value.
const int SQUARE   = 0x2028;                // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.
int wave           = SINE;

const float refFreq = 25000000.0;           // On-board crystal reference frequency

const int FSYNCA = 53;                       // Standard SPI pins for the AD9833 waveform generator.
const int FSYNCB = 49;
const int CLK    = 52;

unsigned long pause     = 5000;
unsigned long freq      = 1000;              // Set initial frequency.
int i;

void setup() {

  // Set slave ocntrol pins
  pinMode(FSYNCA, OUTPUT);
  pinMode(FSYNCB, OUTPUT);
  digitalWrite(FSYNCA, HIGH);
  digitalWrite(FSYNCB, HIGH);

  // Set up SPI
  SPI.begin();
  SPI.setDataMode(SPI_MODE2);
  delay(50);

  // Set up AD9833s
  AD9833reset();                                   // Reset AD9833 module after power-up.
  delay(50);
  AD9833setFrequency(freq, SINE, FSYNCA);          // Set the frequency and Sine Wave output
  AD9833setFrequency(freq, SINE, FSYNCB);

  // Open the serial connection, 9600 baud
  Serial.begin(9600);
}

void loop() {

   // Wait for serial input
  if (Serial.available()) {

    startbyte = Serial.read();              // Read the first byte
    if (startbyte == 255) {
      seq_length = Serial.read();

      for (i = 0; i < seq_length; i++) {

        // Channel 0
        freq_MSB = Serial.read();
        freq_LSB = Serial.read();
        f_2 = (long)freq_MSB << 8;
        f_1 = (long)freq_LSB;
        freq_seq_ch_0[i] = f_2 | f_1;
        wave_select = Serial.read();
        switch (wave_select) {
          case 0:
            wave_seq_ch_0[i] = SINE;
            break;
          case 1:
            wave_seq_ch_0[i] = TRIANGLE;
            break;
          case 2:
            wave_seq_ch_0[i] = SQUARE;
            break;
          }

        // Channel 1
        freq_MSB = Serial.read();
        freq_LSB = Serial.read();
        f_2 = (long)freq_MSB << 8;
        f_1 = (long)freq_LSB;
        freq_seq_ch_1[i] = f_2 | f_1;
        wave_select = Serial.read();
        switch (wave_select) {
          case 0:
            wave_seq_ch_1[i] = SINE;
            break;
          case 1:
            wave_seq_ch_1[i] = TRIANGLE;
            break;
          case 2:
            wave_seq_ch_1[i] = SQUARE;
            break;
          }
      }

      // Send sequence to signal generators
      for (i = 0; i < seq_length; i++) {
        AD9833setFrequency(freq_seq_ch_0[i], wave_seq_ch_0[i], FSYNCA);
        AD9833setFrequency(freq_seq_ch_1[i], wave_seq_ch_1[i], FSYNCB);
        delay(3000);
      }

    }

  }
}

// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
  WriteRegister(0x100, FSYNCA);   // Write '1' to AD9833 Control register bit D8.
  delay(10);
  WriteRegister(0x100, FSYNCB);
  delay(10);
}

// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform, int channel) {

  long FreqWord = (frequency * pow(2, 28)) / refFreq;

  int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  int LSB = (int)(FreqWord & 0x3FFF);

  //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000;

  WriteRegister(0x2100, channel);
  WriteRegister(LSB, channel);                  // Write lower 16 bits to AD9833 registers
  WriteRegister(MSB, channel);                  // Write upper 16 bits to AD9833 registers.
  WriteRegister(0xC000, channel);               // Phase register
  WriteRegister(Waveform, channel);             // Exit & Reset to SINE, SQUARE or TRIANGLE

}

void WriteRegister(int dat, int channel) {

  // Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
  //SPI.setDataMode(SPI_MODE2);

  digitalWrite(channel, LOW);           // Set FSYNC low before writing to AD9833 registers
  delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.

  SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
  SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.

  digitalWrite(channel, HIGH);          //Write done. Set FSYNC high
}

My problem is that this does NOTHING. No matter what sequence I send the output of the signal generators never deviates from the set up defaults.
The generators do work & I have managed to control them via serial before but in that case I knew exactly how much information would be in the serial buffer before I read it in but in this case the sequence length isn't known a priori.
Is this a serial issue?

Are you waiting after opening the serial port in Python for the Arduino to reboot and run pass the bootloader before sending data?

@Majenko I have added sleep(1.0) to the Python code after opening up the serial comms but I still get nothing

OK upped that to 10 seconds & hey presto! it worked!

The main issue here is, that you are reading data, that might not be received yet. This:
if (Serial.available()) {

will check if there is any data in the Serial buffer. As the code runs rather fast and communication over Serial at 9600 baud is relatively slow, this very well might be true, when not your complete message was received. So you might have received the start byte, but the rest of the data is still being transmitted. In that case Serial.read() will return -1.
With Serial (UART) the transmission happens with individual bytes, not in big chucks. You need to only read data, that is really received.
As you don't know the sequence length beforehand I would suggest 2 different ways:

You can wait for 2 bytes being in the Serial buffer (start byte and length) and then again wait, until enough further bytes are in the Serial buffer (as you now have the length of the sequence).

You can rebuild your code, so that it just places the data in an extra buffer, until you have received enough data (which you need to check via the received length byte). Then, when you have received the full message, you process it and then clear the buffer, waiting for a new message.

OK so I've added if (Serial.available > 1) then added while (Serial.available < seq_length*3){} but its still doing nothing.

source: Stack Exchange

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

sort: votes


text:
RAM cost of entering functions
A friend has told me I shouldn't rely on functions because, during execution, they occupy a significant amount of RAM.
Is that true or, if it isn't, what's the maximum suggested level of function nesting at runtime?

http://wiki.c2.com/?PrematureOptimization

A friend has told me I shouldn't rely on functions because, during execution, they occupy a significant amount of RAM.

I wouldn't say "significant", but some RAM is used, yes.
Every time a function is called any registers used in the execution of that function are placed onto the stack. Also some parameters to the function may be passed on the stack (depending on the ABI for the architecture you're using). Further, any local variables used inside the function also go on the stack.
These are only temporary allocations and are released again when the function exits.
Depending on your program the "call stack" can be insignificant compared to the local variables.

what's the maximum suggested level of function nesting at runtime?

Low enough that you don't run out of memory. When you have plenty of memory then your call stack is irrelevant. When you only have a couple of hundred bytes, or a hardware stack (like on the low-end PIC microcontrollers) with a limited depth, then keeping your program flatter can be better.
The main reason for flattening a program is usually for execution speed rather than for memory use.

Also, if a function is only called in one location, or is very short, the compiler will try to inline the function, negating the "cost" associated of the function call.

I guess avoiding functions may have been relevant with dumb compilers, a
few decades ago. Compilers today are pretty good at optimizing and,
since recently, the Arduino environment enables “link time
optimization”. This means the optimizer can see the whole program at
once, which enables:

function inlining across compilation units (and the optimizer does
this pretty aggressively)
saving, in the function prologue, only the registers that really need
to be saved.

In most cases, the “optimal” size for a function is whatever size
optimizes the readability of the code. In the rare cases where you would
need to merge a function into its callers for performance purposes, you
can qualify the function as
inline __attribute__((always_inline))

But this only makes sense after you disassembled the program and noticed the
compiler did not make the right optimization choices. A quite infrequent
situation.

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


text:
How to get arduino to always be connected as /dev/ttyUSB0 and with chmod 0777?
I've got Debian 10 as OS and for a Project, I need my arduino to always be connected as /dev/ttyUSB0, not any other ttyUSB-number, and I need it to be connected with the 0777 rights for a script to work.
I've read some things about udev, but nothing I tried yet worked.
I tried creating
/etc/udev/rules.d/51-my_usb_device
with the content
SUBSYSTEM=="tty", MODE="0777", KERNELS=="ttyUSB0"
but it does not work, even after reboot (like nothing changed). I must admit though that I do not really understand udev.
How to do this?

https://majenko.co.uk/blog/making-your-boards-unique-linux

Have you considered not trying to force ttyUSB0 but instead creating a symlink to whatever tty is assigned? Your software then just uses the symlink.
A problem with forcing a particular tty is what if you boot without the Arduino but another device is attached? You then need to convince the other device to skip ttyUSB0.
If you would consider a symlink then something like:
ACTION=="add", KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="arduino"

might get you started. Check the VID and PID using lsusb or similar. To set permissions as well you can use e.g. MODE="0777" as you already have.
There is an example at https://wiki.debian.org/udev that might give more background.


text:
How to light up RGB Leds at the exact same time?
I have 2 sets of RGB Leds, each set is driven by 3 OUTPUT analog pins of the arduino, as illustrated below:

The code is supposed to put on HIGH the 6 analog pins at the same time so that the Leds light up all at the same time, but when I run it, there's a latency between the 2 groups of Leds.
Here's the code:
const int r[2] = {3, 9};
const int g[2] = {5, 10};
const int b[2] = {6, 11};

const int red[3] = {255, 0, 0};
const int green[3] = {0, 255, 0};
const int blue[3] = {0, 0, 255};

int* colors[3] = {red, blue, green};

void setup() {
    for(int i=0;  i<2; i++){
        pinMode(r[i], OUTPUT);
        pinMode(g[i], OUTPUT);
        pinMode(b[i], OUTPUT);
  }
}

void setColor(int r, int g, int b, int color[]){
    int R = 255 - color[0];
    int G = 255 - color[1];
    int B = 255 - color[2];
    analogWrite(r, R);
    analogWrite(g, G);
    analogWrite(b, B);
}

void loop() {
    for(int c=0; c<3; c++){
      setColor(r[0], g[0], b[0], colors[c]);
      setColor(r[1], g[1], b[1], colors[3-c-1]);
      delay(1000);
    }
}

I should point out that the values of the resistors are in my circuit are different than in the diagram.
Is there something wrong in the wiring or in the code that prevents the Leds from wiring all at the same time?
EDIT: I tried the code one more time on the arduino and all Leds lit up at the same time. That happened in the past, but sometimes there's just a latency that I can neither explain nor fix...

How should 3 groups of each 3 ints fit into an array of type int and size 3? you need either a 2 dimensional array or a bigger type (like long, which has 4 bytes instead of the 2 bytes of int)

You can't use red, blue and green as ints in colors[], they are int*s, and you can't call setColor() with 5 arguments. Does this even compile for you?

@it worked event with that... I edited the code to correct the problem and checked that the code compiled on the arduino IDE.

How big is the latency? Maybe you reflect if the delay(1000) is at the right place. analogWrite() will take some time to execute, but it should be only a few milliseconds and I doubt that one would notice. If he latter is the case, you should try direct port manipulation

How much latency are we talking about? Seconds or just fractions of a second? If your code and your hardware are correct, the time between the lighting of the two LEDs should be imperceptible.


text:
Initiating 2nd I2C bus on ESP32 with CCS811 sensor
I want to connect two CCS811 sensors with ESP32 dev board. Since the sensors have fixed address, I am unable to use them simultaneously. I have read that on ESP32 multiple I2C buses can be created. While trying to follow that route I tried to modify the library but I am stuck. I can't simply pass different pins for SDA and SCL when calling ccs.begin() function. It only takes one argument and that is the sensor address (code chunk from library below):
bool Adafruit_CCS811::begin(uint8_t addr) {
  _i2caddr = addr;

  _i2c_init();

  SWReset();
  delay(100);

  // check that the HW id is correct
  if (this->read8(CCS811_HW_ID) != CCS811_HW_ID_CODE)
    return false;

  // try to start the app
  this->write(CCS811_BOOTLOADER_APP_START, NULL, 0);
  delay(100);

and the actual wire.begin() function is called in the _i2c_init() function which is defined in the lib as:
void Adafruit_CCS811::_i2c_init() {
  Wire.begin();
#ifdef ESP8266
  Wire.setClockStretchLimit(500);
#endif
}

With my very basic knowledge of classes and object, I am unable to modify the library to make it work with 2 I2C buses. Could you please help me with this?
Link to Adafruit CCS811 library:(https://github.com/adafruit/Adafruit_CCS811/blob/master/Adafruit_CCS811.cpp)
My Code so far:
#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs1;
Adafruit_CCS811 ccs2;

TwoWire sen1 = TwoWire(0);
TwoWire sen2 = TwoWire(1);

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

  Serial.println(F("CCS811 test"));

  if (!ccs1.begin(25, 26, 100000))
  {
    Serial.println("CCS 1 Failed.");
    //while (1);
  } else {
    Serial.println("CCS 1 OK!");
  }

  // Wait for the sensor to be ready
  //while (!ccs.available());
}

void loop()
{
  if (ccs1.available())
  {
    if (!ccs1.readData())
    {
      Serial.println(" This is CSS");
      Serial.print("CO2: ");
      Serial.print(ccs1.geteCO2());
      Serial.print("ppm, TVOC: ");
      Serial.println(ccs1.getTVOC());
    }
    else
    {
      Serial.println("ERROR!");
      //while (1);
    }
  }
  delay(500);
}

CSS811 chip can have either address 0x5A or 0x5B depend on the logic level of ADDR pin. Read the datasheet.

Yes the chip can but the module I am using can't. There is no ADDR pin.

which module do you use then? the module will include either a pull up or a pull down resistor. Instead of using an extra I2C bus for the second sensor you could buy one which has the address pin broken out (for a clean solution) or desolder the onboard pullup/-down and control it with a gpio or hardwire it to Vcc/Gnd with a solder bridge.

I use this module https://www.banggood.com/CJMCU-811V1-CCS811-NTC-CO2-eCO2-TVOC-Air-Mass-Sensor-p-1250571.html?cur_warehouse=CN&rmmds=search. I know I could buy another sensor but I also want to learn to use the second I2C bus on ESP32. That's why I trying to implement it this way


text:
'scale' was not declared in this scope
I am currently doing a robotic arm project. I used load cell with HX711 amplifier to detect and monitor of the objects. If the objects is less than 3kg, then the servomotor in gripper can rotate and the gripper can hold the objects. But there is an error in my coding.

please, no pictures of text ... post the actual code

#include <HX711.h>
#include <Servo.h>
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 3;
const int LOADCELL_SCK_PIN = 2;
//Define servos
Servo servo1;//servo located at gripper
int joy1X = 0;
//variable to read analog pins
int joyVal;
void setup() {
Serial.begin(9600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
//declare servo connection
servo1.attach(3);//connection of servo at gripper to PWM pin arduino
}

Edit your question and post the code there. You can see, can't you, that in the comment it looks pretty unreadable.

You forgot 'at least' to declare the global variable:
HX711 scale;

See documentation: https://github.com/bogde/HX711/blob/master/src/HX711.h
See GitHub example: https://github.com/bogde/HX711/blob/master/examples/HX711_basic_example/HX711_basic_example.ino

oh yesss got it THANK YOUUUUUU

@Nuradlin Athirah, please also thank him by marking this answer as correct, and also upvoting it if you haven't. Thank you.


text:
Arduino stuck in PT_WAIT_UNTIL
I am using the Protothread Library from Adam Dunkels.
It is supposed to wait 1 second and then continue. But instead it gets stuck there and everything after that line is not executed.
lastTimeBlink = millis();
PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 1000);

Why does it get stuck there?
The entire code is uploaded here: https://pastebin.com/jRsuvn54
(The comments are on german)

It's not really all that helpful to include just a short snippet of code for an issue like this.

I've added the entire code

The Protothread library examples seems to use a timer for this.

By best attempt to provide something of an answer.
You have said:

PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 1000);

That is not literally represented in your code, so I take your question to refer
to:
int dist2 = dist1.toInt();
...
PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > (dist2 * 1710));

or a similar section.
When you execute this PT_WAIT_UNTIL, dist2 contains whatever value you initialized it with in int dist2 = dist1.toInt();   Assuming the condition isn't met, you are exiting runCommand() by way of PT_WAIT_UNTIL's return PT_WAITING;
#define PT_WAIT_UNTIL(pt, condition) \
  do {                               \
    LC_SET((pt)->lc);                \
    if(!(condition)) {               \
      return PT_WAITING;             \
    }                                \
  } while(0)

The LC_SET here in PT_WAIT_UNTIL is being used to generate a label that can be jumped-to later:
#define LC_SET(s)                                \
   do {                                          \
     LC_CONCAT(LC_LABEL, __LINE__):              \
     (s) = &&LC_CONCAT(LC_LABEL, __LINE__);      \
   } while(0)

Later when you later call runCommand to resume the thread, you execute LC_RESUME by way of PT_BEGIN(pt);
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
...
#define LC_RESUME(s)        \
  do {                      \
    if(s != NULL) {         \
      goto *s;              \
    }                       \
  } while(0)

goto *s here is ultimately jumping to the label created by your use of PT_WAIT_UNTIL.
You are now back in PT_WAIT_UNTIL checking the condition with the line if(!(condition)).  That is, you are checking millis() - lastTimeBlink > (dist2 * 1710)  However, what you are probably (more on that below) doing here is reading junk off the stack.  dist2 was initialized on a previous execution of runCommand and its effective lifetime ended when you returned in PT_WAIT_UNTIL on that prior execution.  On this new execution dist2 is uninitialized because you have jumped over its initialization.  If you turn the warning level up in File/Preferences you should see something for this.
A number of things can happen at this point, most of them not good.  I can't say what the compiler's optimizer will do to this code for certain, but not much would surprised me.  It seems likely, just on familiarity with optimizing compilers and what your code looks like, that it is generating code to read dist2.  That may  sound like a given, but it isn't when you're doing something undefined.  It's possible dist2 has the value from a previous run where you're executing this function in a loop.  But it could also have value that makes dist2 * 1710 evaluate to a duration of up to nearly 50 days, causes PT_WAIT_UNTIL to return from runCommand for so long as you're testing.
Generally, if you're going to use these proto-threads you're going to have to be very careful in thinking about what's actually initialized and what just looks like it is.  If you have a PT_whatever between a non-static local variable initialization or assignment and code where it's used, that's something to examine.

The reason I've put 1000 instead of (dist21710) in the question is simply because it doesn't work either way. The calculation of (dist21710) works perfectly fine. There is no problem with that.

But I think I understood what the reason is. Basically the function is only being run once. It isn't run when the condition is met. If the function would be in a loop, then everything would work, as the program is able to jump to the label and check again, if the condition is met. Then it could also continue.
The thread isn't really paused, it's stopped, and there is a label where to jump back to, when run again. As the function is not run again, you can't jump back to the label.

Thank you anyways, as your answer helped me to understand it.

I appreciate that it helped, but if you find the problem is actually something different you could write your own answer to your problem and mark that as accepted.  I think in two days you can do mark your own answers as accepted.  You can vote this up for being useful without declaring it the answer.


text:
smooth DC motor control with millis
So the task is to control 12v DC motor.
With first button, you can add up motor speed by certain speed step.
With second button, you can slow down motors speed by certain speed step.
With third button you cant speed up motor to its max, but problem is there that i must be done smoothly. For example i press third button and in motor starts to spin faster and faster till it reaches max speed. But now when i press this button motor jumps to it max, and i don't know why. There is no smoothness.
I cant use delay, must be done by millis
[code]
int speed = 0;
int motor = 5,
    fasterbutton = 7, slowerrbutton = 4, tillmaxbutton = 2;
unsigned long previousMillis = 0;
const long interval = 100;
const long smoothinterval = 5000;
boolean faster, slower, tillend;
int begginingspeed;
const int step = 3;
const int maxspeed = 255;

void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  pinMode(7, INPUT_PULLUP);
  Serial.begin(9600);
}
void loop() {
  tillend = digitalRead(2);
  slower = digitalRead(4);
  faster = digitalRead(7);

  //button Nr 7 start DC motor and festens up
  if (faster == !HIGH && begginingspeed < maxspeed) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      begginingspeed += step;
      if (faster == !HIGH && speed < 1 ) {
        Serial.print('\n');
        Serial.print("MOTOR ON" );
      }
      analogWrite(motor, begginingspeed);
      Serial.print('\n');
      Serial.print("Speed = " );
      speed = begginingspeed * 100 / maxspeed;
      Serial.print(speed, DEC);
      previousMillis = currentMillis;
    }
  }

  //button Nr 4 slows down  DC motor
  else if (slower == !HIGH && begginingspeed > 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      begginingspeed -= step;
      analogWrite(motor, begginingspeed);
      Serial.print('\n');
      Serial.print("Speed = " );
      speed = begginingspeed * 100 / maxspeed;
      Serial.print(speed, DEC);
      if (slower == !HIGH && speed < 1 ) {
        Serial.print('\n');
        Serial.print("MOTOR OFF" );
      }
      previousMillis = currentMillis;
    }
  }

  //button Nr 2 for smooth fastens up DC motor till max
  if (tillend == !HIGH && begginingspeed > 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis <= interval) {
      for (begginingspeed = begginingspeed; begginingspeed <= 255; begginingspeed += step)
        analogWrite(motor, begginingspeed);
    }
    previousMillis = currentMillis;
  }

}
[/code]

you need more state, 1 more boolean, say, is_accelerating. You set this true when the button is pressed, and set it false when speed is max. It basically replaces faster == !HIGH so you don't have to hold down the button.

@dandavis in my code i don't need to hold button to reach max speed.

the for loop in if (tillend == !HIGH runs instantly. kill the for loop, then hold the tillend button to ramp up smoothly. then make my mod so you don't have to hold the button.

@dandavis you need more state, 1 more boolean, say, is_accelerating. You set this true when the button is pressed, and set it false when speed is max. It basically replaces faster == !HIGH so you don't have to hold down the button. SO could you explain me this part, i din't get it how to declare all of this.

@dandavisint   so i made changes, yes now i don't need to hold button, but speed still jumps up, there are no smoothnes

else if (tillend ==!HIGH && begginingspeed > 0) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 5000) {                                                                              if (tillend==!HIGH){ is_accelerating= true; }                                                           begginingspeed += step; }  if (begginingspeed=maxspeed){ is_accelerating= false; } analogWrite(motor, begginingspeed); previousMillis = currentMillis; } }

I suggest using a different logic in your program. I would first divide up the different parts of the project:

A code part, which reads the 3 buttons and sets/increments/decrements a variable based on the button clicks, and
a code part, which takes a variable as set point and ramps the PWM (analogWrite()) output up or down, until the set point is reached. (So the setpoint is the target speed/PWM value)

This division between "input code" and "output code" is rather common, since it often makes your code better structured and makes it possible to easily add new inputs for one single output.

Let us first look at the second part (ramping the PWM signal up and down). We need a variable, that holds the current PWM value, and one, that holds the current set point (for both we are starting with zero, thus the motor stands still here:
int current_speed = 0;
int speed_setpoint = 0;

We also need a timestamp variable for using millis() to regularly setting the PWM output according to the set point and the corresponding interval (here as a define). Additionally we also define the increment, with which the PWM value should be incremented on each sample:
unsigned long motor_timestamp;
#define MOTOR_SAMPLE_INTERVAL  100
#define MOTOR_SAMPLE_INCREMENT 3

We are doing all this in the global scope. Now in the loop function we first check for millis() and the timestamp (which gives us a regular sample interval for the motor speed) and then check, if the current speed is higher or lower than the setpoint and change the current_speed accordingly. At the end we write the value of current_speed to the output:
if(millis() - motor_timestamp > MOTOR_SAMPLE_INTERVAL){
    if(current_speed < speed_setpoint){
        current_speed += MOTOR_SAMPLE_INCREMENT;
    } else if(current_speed > speed_setpoint){
        current_speed -= MOTOR_SAMPLE_INCREMENT;
    }
    analogWrite(motor, current_speed);
    motor_timestamp += MOTOR_SAMPLE_INTERVAL;
 }

So now we current_speed of the motor will follow the speed_setpoint, but will only increment or decrement with the speed you set with the MOTOR_SAMPLE_INTERVAL and the MOTOR_SAMPLE_INCREMENT. The new target speed is simply set by giving the variable speed_setpoint a new value. The above code will take care of reaching it.

Now lets look at the first part (reading the buttons for changing a variable). At your current code, you need to hold the button down for the value to change. From your text is guess, that you want a click behavior (1 step in speed for 1 button click, meaning button press and release). For that I suggest using the Bounce2 library, which will handle the buttons - especially the debouncing - for you:
#include <Bounce2.h>
Bounce bounce = Bounce();

void setup(){
    bounce.attach( BOUNCE_PIN, INPUT_PULLUP );
    // DEBOUNCE INTERVAL IN MILLISECONDS
    bounce.interval(5); // interval in ms
}

void loop(){
    bounce.update();
    if(bounce.fell()){
        // Handle the button click here
    }
}

Inside the if(bounce.fell()) statement, you would handle the action for the button click, in this case: updating the speed_setpoint variable. Define an increment value for the buttons and do the increment/decrement in the if statements. In global scope:
#define BUTTON_SPEED_INCREMENT 4

In the loop() function:
if(slower_bounce.fell()){
    speed_setpoint -= BUTTON_SPEED_INCREMENT;
}
if(faster_bounce.fell()){
    speed_setpoint += BUTTON_SPEED_INCREMENT;
}
if(tillend_bounce.fell()){
    speed_setpoint = maxspeed;
}

Now you need to put all this together. I will leave that to you. You can then tune the behavior to your liking by changing the defines.

Note the following points:

The motor will accelerate linear. That should be fitting for you.

The code will restart the PWM wave at every MOTOR_SAMPLE_INTERVAL. That is ok for a motor when the interval is significantly higher than the PWM interval. When you choose the interval too low (like single digit milliseconds), you need to put the analogWrite() call into the if statements with the increment of speed_setpoint. That will take 1 more statement, but will solve the problem.

If you choose the MOTOR_SAMPLE_INTERVAL too low, the speed change will get stuttery

If not delay then you'll probably have to use something like an H-Bridge. L298N is a good place to start. You can use PWM to control its speed and its gradual too.
https://www.browncountylibrary.org/wp-content/uploads/2018/03/arduino_dc_motors.pdf
Here's the relevant documentation

i just did CTRL+T, hope it will help. 3 button most smoothly add speed to dc motor, so then i press it, it must go to max speed (255) from current speed.

Yeah thanks, so when programming keep the variable names short and simple and try not to use redundant variables. It'll help debug the process much faster and it'll be a less burden to your compiler too.

thanks for advice, i'm new to coding, so yeah :D thanks in advance

yes button works, but its not smooth, it just "jumps" to max, that's the deal. I know how to make that dc motor goes to max speed, but i don't know, how to make it smoothly increase speed after pushing 3rd button

Did you try increasing the delay, to say 100? from my code above delay(50)

and i cant use delay, sadly

Did you try increasing the delay, to say 100? from my code above delay(50)--Yes, didn't work, just jumped to max

yeah, schematic is correct.It must be done with diode,transistor and push buttons.

@N0m4d why exactly should a H-bridge be necessary to do smooth speed changes?


text:
Switch loops with SPDT switch
I have made a drone/car quadruped robot thing and I need help with the code. I have found two codes to use to control each aspect of it but I need help to connect them. I have made a radio controller with a Xbee 3 Pro that has a spdt (two position switch) and I want to use it to switch the modes. I want the car to be LOW and the drone to be HIGH (If it helps the switch is on pin digital pin 9 of a Arduino Nano). I am a beginner at the coding aspect of the project and I would appreciate all the help I can get.

https://www.youtube.com/watch?v=enT-O4NwCzc

please add your code to the post

There is no need for a SPDT switch. A SPST works just as well.
If you have a SPDT switch with 3 positions (pole 1 closed, open, pole 2 closed) you can use it to activate one pin or the other, or neither.
Let's pretend your switch is an SPST. Ignore one of the poles (pole 2, say.)
Connect a digital pin to pole 1. connect the common (center) pin to ground.
Set your digital pin to INPUT_PULLUP. Now, when the pin is LOW, the switch is closed (mode A). When the pin is HIGH, the switch is open (mode B).

Thank you I just checked back in and this is very helpful. Do I need a resistor like as if it were a pushbutton

If you use INPUT_PULLUP mode then the Arduino connects the pin to +5V through an internal restistor, so you don't need an external resistor. That is true for pushbuttons as well. (However, when you use  INPUT_PULLUP, the pin reads HIGH when the switch is open, and goes LOW when the switch is closed.)


text:
Returning struct from function generates 'does not name a type' compilation error
I have a main.ino file that contains
struct EulerAngles {
  double roll, pitch, yaw;
};

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

and an angles.ino file that contains
EulerAngles anglesCalc(){
   EulerAngles a;
   // calculate a
   return a;
}

When I compile the program, I get a compile error in the main.ino file:
   code/so_examples/main.ino:5:1: error: 'EulerAngles' does not name a type
 void setup() {
 ^~~~~~~~~~~
code/so_examples/main.ino: In function 'void setup()':
code/so_examples/main.ino:7:12: error: 'anglesCalc' was not declared in this scope
   angles = anglesCalc();
            ^~~~~~~~~~
code/so_examples/main.ino:7:12: note: suggested alternative: 'angles'
   angles = anglesCalc();
            ^~~~~~~~~~
            angles
[Build] Error occurred.

How do I fix this? Note that struct is declared before all else, so this answer does not seem to apply.  I am using the Stino plugin for Sublime Text as the IDE.

The original question was a paraphrase of a much larger program, but in that program, I did move the struct up to the top and it did not fix the problem. I have now set up a dummy program that reproduces the problem (has the struct at the top), and have modified the question to show that real code and also the real compiler error message.

what IDE do you use? the main ino file must be named as the sketch folder so_examples.ino to be concatenated by the Arduino builder before the other ino files. the files are concatenated in the order of Arduino IDE tabs. https://arduino.github.io/arduino-cli/latest/sketch-build-process/

Renaming main.ino to so_example.ino does not help. But I am using Sublime Text with the Stino plugin. If I open the renamed file using the Arduino IDE and compile, it works fine. So it looks like a problem with the Stino/Sublime Text IDE.

Arduino IDE doesn't allow to open a ino which is not in a folder with the same name

Good idea.  The trouble with the Ardino IDE on a Mac running Big Sur is that it is unstable, it keeps crashing on me.  As well, it does not seem to have any syntax checking in the editor, plus I do all my development work in Sublime Text.  I will raise an issue on the Stino plugin and just stop trying to use functions which return structs until issue is rectified.  Thanks to all  that helped to resolve this.

There is an open issue with structs with the Sublime Text plugin. I have added an answer with the details.  I plan to delete all my comments on the question/answer, as are out of date and just add noise.

There is an open issue with the Stino Arduino plugin for Sublime Text which means that structs are not handled properly.
Thank you to Jura and Edgar Bonet for helping me to answer this question.

the orignal question didn't mention Stino

I believe that the final form of the question and and accepted answer should be as clear, and if possible, not require reading comments to understand it.  By editing the question to add the Stino clarification, it makes it clear it is not a redundant question.  Deleting unnecessary or out of date comments also enhances the clarify of the Q and A.  However, I notice you have a lot more experience in this community than me (I normally am on SO), so prepared to take your advice on this matter. I have added an acknowledgement of your and Edgar Bonet's assistance in my answer.

I would avoid having multiple .ino files, because of the issues raised
in the other answers. If you want to split your code into multiple
files, the scheme that works reliably is to have:

a single .ino file, named like the containing folder, holding the
“main” program (this is Arduino-specific)
a pair of .h/.cpp files for each “module” implementing a sub-feature
of the program (this is common C++ practice).

Within the .h/.cpp pair, the .h file declares everything the compiler
needs for understanding code that uses the feature: type definitions
(including classes) and function prototypes. The .cpp file holds the
actual implementation.
Applying this scheme to your case would give:
my-sketch.ino (actually, with the name of the containing folder):
#include "angles.h"

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

angles.h:
struct EulerAngles {
  double roll, pitch, yaw;
};

EulerAngles anglesCalc();

angles.cpp:
#include <Arduino.h>
#include "angles.h"

EulerAngles anglesCalc() {
   EulerAngles a;
   // calculate a
   return a;
}

Note that including <Arduino.h> is only useful if the code uses the
Arduino core API. Otherwise you can omit it. The main sketch does not
need to include <Arduino.h> because it is implicitly included in the
.ino file by the Arduino IDE. There is no such implicit inclusion when
the IDE processes .cpp files.

it is much easier to use multiple ino files then maintain a .h files

Try to add struct at the first of function, such as:
struct EulerAngles anglesCalc(){
   EulerAngles a;
   // calculate a
   return a;
}


text:
When are global constuctors executed?
Apologies if this has been discussed before but I couldn't find anything.
I have written a simple LED class. For illustration (it is actually a bit more complex) but it goes something like;
class LED {
    LED(byte pin);
  private:
    int _pin;
};

And the constructor is simply;
LED::LED(byte pin) {
    _pin = pin;
};

and I create a global instance of this class at the top of my code thus;
LED redLED(5);

It is necessary to create this as a global object because (a) I can't create the object in the setup() function because it would go out of scope and (b) I can't create in the loop() function because I don't want to create an infinite number of these objects.
This all seems to work OK but it just leaves me wondering exactly when this constructor gets executed? I suppose that it must be before setup()?
Answered!
Many thanks to all the respondents. So when using the Arduino IDE the build process must silently insert the main() procedure. I was not aware that it did this. I guess that most of the time you can get away with not knowing when the global constructors are called.
It is good practice (I think) to create a "wrapper" class for all/any external (or perhaps internal) hardware devices that are connected to your arduino. And it is thus perhaps tempting (but risky) to do initialisation work in the constructor.
So given what I now know, it is better to create an "init()" method for such classes that can be called from setup(). Even if just to do the the pinmode() call.
Thanks again.

Re “the build process must silently insert the main() procedure”: It is provided by the Arduino core library. Re “it is better to create an ‘init()’ method”: It would seem that begin() is the canonical name for such a method.

The global constructors run right after the initializations performed by
the C runtime startup code, and right before main() gets called.
In a nutshell, the C runtime initialization code:

does some low-level initializations (e.g., setup the memory)
calls the global constructors
calls main(), which in turn

calls init() to do the Arduino-specific initializations
calls setup()
repeatedly calls loop()

The fine details are probably platform-specific. For AVR-based boards,
they are documented in the avr-libc manual.

It is executed before the main() is called (in the main() there is setup() called and then loop() is called in infinite loop).
It has its own sections for the constructors and destructors:
http://beefchunk.com/documentation/sys-programming/binary_formats/elf/elf_from_the_programmers_perspective/node4.html

class LED {
private:
  const byte _pin;
public:
  LED(const byte pin);
};

With an even simpler c'tor:
LED::LED(const byte pin) : _pin(pin) {};

To be a bit on-topic: The initializer list is even executed before the constructor body, and is thus the way to initialize constants.
Question remains whether it's guaranteed that this works:
class LED {
private:
  const byte _pin;
public;
  LED(const byte pin) : _pin(pin) {pinMode(_pin,OUTPUT);}
  set(bool state) {digitalWrite(_pin, state); }
};

( Can pinMode be called that early, or should one invent an init() method? )
My experience says : works well ...

Note that the constructor runs before the Arduino core is initialized. Are you sure it works well on every Arduino board? On AVR, it sure does, because pinMode() happens to not rely on the Arduino core being ready.

I have only tested this on a Nano


text:
using esp8266 to fetch specific data from firebase
I want to fetch specific data from firebase using Node Mcu ESP 8266. I can fetch the num value, but I failed to fetch the id value. The serial monitor kept displaying 0 when I try to fetch the id value. Any method to fetch the newest insert id value( Id value automatically update every time I submit the form at my web application). Thank you.
below is my coding
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

// Set these to run example.
#define FIREBASE_HOST "inserted"
#define FIREBASE_AUTH "inserted"
#define WIFI_SSID "Pro_4258"
#define WIFI_PASSWORD "1234567890"

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

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

  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
}
int a;

void loop() {

  a=Firebase.getInt("id");

  if (Firebase.failed())
  {
    Serial.println(Firebase.error());
    }else
    {
      Serial.println(a);
      }
delay(500);
}


text:
ESP32 light strips showing incorrect colours
I bought some individually addressable LED strips (a large reel). To keep the cost down they are WS2811 and it's one chip per 6 leds. I don't know the cheapness or LED styl makes any difference to the problem but I'm just putting it out there.
They support 24V so to be safe I'm running them at 23V. I have the data line hooked up to pin 13 of the ESP, and a ground connection to the power supply to create a common ground. I am using Alexa to control the colours. This is the code:
#include <WiFi.h>
#include <Espalexa.h>
#include <FastLED.h>
#include <Adafruit_NeoPixel.h>

FASTLED_USING_NAMESPACE

#define NUM_LEDS 120
#define LED_TYPE WS2811
#define LED_PIN 13
CRGB leds[NUM_LEDS];

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_RGB + NEO_KHZ400);

#define ESPALEXA_ASYNC
Espalexa espalexa;

#define RELAY_PIN 12

boolean connectWifi();

void colorLightChanged(uint8_t brightness, uint32_t rgb);

const char* ssid = "****";
const char* password = "****";
boolean wifiConnected = false;

void setup()
{
  Serial.begin(115200);
  delay(2000);

//  FastLED.addLeds<LED_TYPE, LED_PIN>(leds, NUM_LEDS);
//
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);

  digitalWrite(RELAY_PIN, HIGH);
//
//  for (int i = 0; i < NUM_LEDS ; i++) {
//    leds[i] = CRGB(0, 0, 0);
//  }
//  FastLED.show();

  strip.begin();
  strip.show();

  wifiConnected = connectWifi();

  if(wifiConnected){
    espalexa.addDevice("Lights", colorLightChanged);

    espalexa.begin();

  } else
  {
    while (1) {
      Serial.println("Cannot connect to WiFi. Please check data and reset the ESP.");
      delay(2500);
    }
  }
}

void loop()
{
   espalexa.loop();
   delay(1);
}

void colorLightChanged(uint8_t brightness, uint32_t rgb) {
  for (int i = 0; i < NUM_LEDS; i++) {
//    leds[i] = CRGB((rgb >> 16) & 0xFF, (rgb >>  8) & 0xFF, rgb & 0xFF);
//    FastLED.setBrightness(brightness);
      strip.setPixelColor(i, (rgb >> 16) & 0xFF, (rgb >>  8) & 0xFF, rgb & 0xFF);
  }
//  FastLED.show();
    strip.show();

  if(brightness == 0) { //lights off
    digitalWrite(RELAY_PIN, LOW);
  }
  else { //lights on
    digitalWrite(RELAY_PIN, HIGH);
  }

//  Serial.print("Brightness: ");
//  Serial.print(brightness);
//  Serial.print(", Red: ");
//  Serial.print((rgb >> 16) & 0xFF); //get red component
//  Serial.print(", Green: ");
//  Serial.print((rgb >>  8) & 0xFF); //get green
//  Serial.print(", Blue: ");
//  Serial.println(rgb & 0xFF); //get blue
}

boolean connectWifi(){
  boolean state = true;
  int i = 0;

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  Serial.print("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 40){
      state = false; break;
    }
    i++;
  }
  Serial.println("");
  if (state){
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("Connection failed.");
  }
  return state;
}

I've tried both Neopixel and FastLED with the same outcomes. Those outcomes are totally wrong colours:
This is supposed to be cyan except it's mostly yellow with a bit of blue.

This is supposed to be purple

And I think you get the idea. The lights strips light up with wrong colours (I've had whats supposed to be gold, be purple), blotches of colours or just make some look really similar (on Alexa, warm white to cool white look almost identical apart from a change in brightness).
I don't know what could be causing this though. I've made sure theres a common ground, I've made sure the pin on the ESP is right (i.e. just a plain output pin with no other fancy stuff), I've tried 2 different libraries and still no luck.
Could anyone help me out?
EDIT: These are these the strips I bought if it helps: https://www.superlightingled.com/65ft20m-roll-ws2811-dc24v-36ledsm-addressable-led-light-strips-digital-full-dream-color-chasing-flexible-led-strips-p-3163.html

at this point it is unclear if the problem is with alexa, or with the LED strip itself .... remove all of the alexa code ... light the whole strip one color, pause 5 seconds, light whole strip another color , and so on .... start with red, then green, then blue

I tried it without Alexa code and they work perfectly. What confuses me is there is nothing wrong with the RGB values that come from the Alexa. Red comes through as 255 0 0 purple comes through as 171 35 255 and so on. Could it be that the LED libraries don't like being run in a callback?

If it's the callback issue, try moving strip.show(); to your loop function. If that too fails, try moving everything into the loop, and have colorLightChanged only store the new values in a global (volatile) variable, that your loop uses.

Just tried putting the FastLED code in loop and using a flag to determine when to set the  colour. Unfortunately, still doesn't work. My last idea is just to try changing the colour on a different core so espalexa and fastled are totally separate. I'm not hopeful but it's worth a shot

why are you using adafruit and fastled at the same time? I don't think that will work. Also, it's much faster to use .fill() instead of setPixelColor if they are all the same color.

In the code above the fastled code is commented out. I included the neopixel library to make sure it wasn't just an issue with fastled

That strip seems to be BGR instead or RGB.
Use NEO_GRB instead in your initializer. So:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_BGR + NEO_KHZ400);

I'll still try it but would that make a difference to the colours? I didn't mention it (probably should have) but all the primary colours (red, green, blue) show up correctly. If I set the strip to red, it shows red.

Giving the new information you provided, this probably won't fix it.


text:
ISP Programmer with Serial and 5v/3.3v power
I currently use a Pololu USB AVR Programmer v2.1 for programming 328p chips and I really like it. The ability to have ISP and Serial in one physical device, enumerating as two separate COM ports on the PC, the programmer powering the circuit at 3.3v, with the programmers windows GUI interface to set voltages, programming frequency and give feedback on the programming when things go wrong, is all brilliant.
However, many of my circuits either have a power requirement higher than that on the Pololu (80mA), or to much capacitance (33uF) so that the power surge on connection is too much for the Pololu and it resets.  The reset disconnects my serial debugger, disconnects the Pololu GUI, and sometimes does not come back on at all due to the startup current draw.
I am looking for suggestions for an alternative device, or way of stopping the brown out on power up?
Thanks very much
Kevin

To clarify, you are avoiding powering your programmer from the target's VCC because you don't want the programmer to re-enumerate when the target power-cycles, correct?

Hi, I want the targets VCC to be 3.3v from the programmer, so that I don't have to provide a separate power supply.  It is normally Solar powered - but that is difficult inside in the winter in the UK :)

How about, connecting a tiny battery across the 3.3v output of the Pololu.  Lets assume a 3.7v LiPo, charged to 3.3v.
When the battery is connected at 3.3v, no current will flow.
When my device to be programmed is connected it will draw a spike of current, which will start to take the Pololu below 3.3v, but then the LiPo will start supplying current and stop the Pololu voltage getting dragged down and browning out.
The LiPo will then be slightly below 3.3v, so will get a Constant Voltage charge back to 3.3v.
Two potential issues I can see:

When the Pololu is disconnected from the USB will it be being 'back powered' by the LiPo?

When in CV charge mode, the only current limiting will be internal resistance of the Pololu output / LiPo cell, probably not an issue in practice due to the voltage drop being very small.

I know it is a hack, but thoughts welcomed.
Cheers
Kev


text:
Not Able to communicate with ESP8266
I just bought an Esp8266(not the node MCU) and tried connecting it with Arduino without a USB to serial converter but in vain. I am a beginner and don't know what to do. It is not responding to AT commands. Can anyone give me a detailed step by step process to connect it?
I am using Arduino UNO R3.
This is my connection diagram:-

I uploaded an empty code(Bare minimum example code), just to see if the AT commands are working, but it failed to respond. I reflashed it, then also it is not working.
when I type AT it shows nothing. But if I shake it, sometimes it shows gibberish.

Right now all I'm trying to go is get you to bring it up to the state of being an answerable question.  Already looks better than what you started with. Still a ways to go.  I'm confused as to what the thinking behind "uploaded an empty code" is.  How were you thinking that would help?

Does this answer your question? Arduino Uno with ESP8266-01 with AT

Hey @Juraj I tried to send some commands, it shows gibberish and wdt reset with rst_cause:4

If it shows gibberish when you shake it, you have a bad connection somewhere. Also, what code are you trying this with? Do the baud rates match and did you set them to a low enough value (9600 recommended)?

Hey, thanks for replying. Just bought another one and it worked properly.


text:
How to set SPI speed for ATmega1284P?
I am using MightyCore and platformio. My config file looks like this
My fuses are set as:
E:FD
H:D6
L:8F

I have controller running at 16 MHz and SCK frequency is 8 MHz.
My display is showing white color and that is it. I know to make it function properly I have to use 1 MHz SPI clocking.
If I program CKDIV8 fuse my controller doesn't start. I dunno why, kind of black magic going on there for me. My lack of knowledge is not helpful there.
I tried to use the following tricks:
Setting SPI speed using TFT library
// earlier in main.cpp
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// later in setup()
tft.setSPISpeed(1000000); // has no effect on SCK

Trying to set it directly via SPI class instance:
// in setup()
SPI.setClockDivider(SPI_CLOCK_DIV128); // no effect

Or statically:
// in setup()
SPIClass::setClockDivider(SPI_CLOCK_DIV128); // still no effect

Also I tried to pass DEFAULT_SPI_FREQ build flag with frequency preset.
I ran out of ideas.
Schematic is here:

is setSPISpeed after init?

"If I program CKDIV8 fuse my controller doesn't start." How are you determining this?

@Juraj  no. It was before. I placed it after and it works now.

@timemage I have some pin manipulations later in setup() and they aren't happening.

why would you place it before? init initializes SPI and then of course sets the default value.

Per this issue setSPISpeed has to be made after initR like this:
tft.initR(INITR_BLACKTAB);
tft.setSPISpeed(1000000);

init initializes SPI and of course sets the default value. you can change it only after that

@Juraj I have no idea what was going on in Adafruit engineers head. The display fails to init @ 8 MHz because SPI is too fast for it. It has to be initialized at 1 MHz then it supposed to function properly.


text:
Max. external ADC speed with ESP32 (SPI or I2C)?
What is the maximum speed for external ADC I can expect to get with ESP32? I'm planning to have 16-bit ADC connected to I2C or SPI whichever gives more speed.
How that information is calculated from information in ESP data sheet?

Depends on the ADC and what technology it uses. Instead you should be asking what would be a suitable way of sampling whatever it is you want to sample. SPI will always be faster than I2C, but neither may be the right system to use. We need more detail about what you want to achieve.

How fast do you want it, or: how fast is you adc? There are different options to interface the spi/i2c peripherals (polling, interrupt, dma).

I2S is even faster, and supported on the 32.


text:
utf8 to hex macro
I would like to replace utf8 characters to byte values for easier character display handling.
The actual replacement table comes from the lcd datasheet therefore it is not utf8 to ascii conversion. Hence I would like to define some macros, where I put the utf8 character, and it returns some matching hex code.
Here is the bare minimum code:
#define IV('┌') 0xC9
#define IV('°') 0xB2

char line0[4] = {0xC9, '4', 0xB2, 0}; // works
char line1[4] = {IV('┌'), '4', IV('°'), 0}; // do not work

void setup() {}
void loop() {}

It does not compile and I must be missing something obvious or rather basic.
Any help is much appreciated.

#define IV('┌') 0xC9

That really isn't how macros work. What goes in the brackets is a named parameter that is then used in the body of the macro. You can't have multiple macros named the same like that.
The simplest thing to do is just make a set of macros named after what the character is.  For example:
#define CHR_DEGREE 0xc9
#define CHR_BOX_TL 0xB2

char line1[4] = {CHR_BOX_TL, '4', CHR_DEGREE, 0};

I do not want to have english names of the chars as defines, the whole point of my post is be able to do semi-ascii art. Some kind of lookup table is desirable.

UTF-8 is not a simple 1:1 mapping. It uses character sequences of variable length. A simple lookup table is not possible.

I came up with a solution, please see below. I hope you or someone else has a better way to do it.

@user12933 There's a flaw in your design: a char can't contain a UTF-8 multi-byte character,

Does it count that it compiles and works as expected irl on a real lcd screen? (just tested it, no artifacts every char/symbol show up)

@user12933 If the first byte of each of those characters is unique then fine. It will discard any subsequent bytes in the character. You'd be better using wchar_t and UTF-16 instead (L'┌')

Let us continue this discussion in chat.

After some googling I came up with this solution.
I really hope someone finds a more elegant way to express it.
These embedded ternary operators are really error prone.
#define IV(i) ( \
(i)=='┌' ? 0xc9 : \
(i)=='⎩' ? 0x15 : \
(i)=='⎭' ? 0x17 : \
(i)=='⎰' ? 0x18 : \
(i)=='°' ? 0xb2 : \
(i)=='™' ? 0xd0 : \
(i)=='Ξ' ? 0xd8 : \
(i) )

char line2[21] = {0x15, '_', 0xd8, '_', 0x17, 0xd0, '1', 0xc9, '5', 0x18, '5', '0', '0', 0xb2, ' ', ' ', ' ', ' ', ' ', 0}; //original
char line4[21] = {IV('⎩'), '_', IV('Ξ'), '_', IV('⎭'), IV('™'), '1', IV('┌'), '5', IV('⎰'), '5', '0', '0', IV('°'), ' ', ' ', ' ', ' ', ' ', 0}; //wanted

void setup() {}
void loop() {}

Macros can give weird errors is you do not parenthesize them properly. Here, you have lots of useless parentheses, yet the ones that would be needed to make the macro safe are missing. With only the required parentheses it would look like: #define IV(i) ((i)=='┌' ? 0xc9 : (i)=='⎩' ? 0x15 : (i)=='⎭' ? 0x17 : (i)=='⎰' ? 0x18 : (i)=='°' ? 0xb2 : (i)=='™' ? 0xd0 : (i)=='Ξ' ? 0xd8 : (i))

@EdgarBonet ty, corrected.


text:
Initializing Array of structs
I defined myself a struct:
typedef struct {
  unsigned char current;
  unsigned char start;
  unsigned char target;
  unsigned long startTime;
  unsigned int duration;
} led;

I was able to initialize an instance of that like this:
led h_red = {0,0,255,0,300};

However, when I try to have them in an array:
led leds[LEDS];
leds[0] = {0,0,0,0,0};
leds[1] = {0,0,0,0,0};
leds[2] = {0,0,255,0,300};

I get this error
signal:28:1: error: 'leds' does not name a type
 leds[0] = {0,0,0,0,0};
 ^~~~
signal:29:1: error: 'leds' does not name a type
 leds[1] = {0,0,0,0,0};
 ^~~~
signal:30:1: error: 'leds' does not name a type
 leds[2] = {0,0,255,0,300};
 ^~~~

And I have no idea what I'm doing wrong here. You can see the full change here on GitHub

led h_red = {0,0,255,0,300};

Here, you are defining a variable, and at the same time giving it an
initial value. This is called an initialization.

led leds[LEDS];

Here you are defining an array. Since it is in global scope, and not
explicitly initialized, it is implicitly initialized to all bytes zero.

leds[0] = {0,0,0,0,0};

Here, you are trying to give a value to an element of the array that has
already been defined previously. This is thus not an initialization,
but an assignment. Unlike initializations, assignments cannot exist
outside a function. If you want to assign initial values, you can do it
in setup().
Alternatively, you can initialize the array while you define it:
led leds[LEDS] = {
    {0, 0,   0, 0,   0},
    {0, 0,   0, 0,   0},
    {0, 0, 255, 0, 300}
};

This is the key part to notice: Unlike initializations, assignments cannot exist outside a function. If you want to assign initial values, you can do it in setup(). OP's call to leds[0] = {0,0,0,0,0}; is perfectly valid within another function, such as setup(), but is NOT allowed outside of all function scopes, where only initialization can take place. The OP was accidentally trying to do this assignment in the global scope, where new assignments and regular logic code are not allowed.

I've upvoted @Edgar Bonet's answer, because it is correct.
I want to add some more examples and explanations though.
Key summary:
In C and C++, you can NOT have code logic outside of functions. The global context outside of functions is intended for declarations, definitions, and some initializations/constructors only. All code logic must be inside of a function. Code logic includes post-construction variable assignments, if statements, etc.
Examples:
1. NOT allowed:
Therefore, you can NOT do the following, since it attempts to do non-initializing assignments outside of all function scopes.
Notice also that in C++ (which Arduino is), you don't need to use typedef for structs either, so I've removed that from the struct definition. I'm also using the stdint.h types, which are considered safer and "best practice" for data types, as they specify the exact type size in bits. Use uint8_t in place of unsigned char, uint32_t instead of the Arduino Uno's unsigned long, and uint16_t instead of the Arduino Uno's unsigned int. Also, in C++ in particular, constexpr or enums are preferred over #define to set variable constants.
constexpr uint8_t NUM_LEDS = 3;

struct Led {
  uint8_t current;
  uint8_t start;
  uint8_t target;
  uint32_t startTime;
  uint16_t duration;
};

Led leds[NUM_LEDS];
// NOT OK: Variable (re)assignments are NOT allowed outside of functions in
// C and C++.
leds[0] = {0, 0,   0, 0,   0};
leds[1] = {0, 0,   0, 0,   0};
leds[2] = {0, 0, 255, 0, 300};

void setup()
{
}

void loop()
{
}

2. IS allowed:
You CAN, however, have variable initializations outside of functions, so long as they occur at the same time as construction, so this is perfectly valid:
Led leds[NUM_LEDS];
// This form of aggregate initialization during construction is just fine in the
// global scope outside of all functions.
Led leds[NUM_LEDS] = {
    {0, 0,   0, 0,   0},
    {0, 0,   0, 0,   0},
    {0, 0, 255, 0, 300},
};

void setup()
{
}

void loop()
{
}

3. Also IS allowed:
Or, you can just move your reassignments into a function, such as setup():
Led leds[NUM_LEDS];

void setup()
{
    // This variable (re)assignment is just fine since it's inside
    // of a function.
    leds[0] = {0, 0,   0, 0,   0};
    leds[1] = {0, 0,   0, 0,   0};
    leds[2] = {0, 0, 255, 0, 300};
}

void loop()
{
}

4. Full, runnable example on a PC:
Here's a full, runnable example on a PC, with printing to verify the contents of the struct were changed:
Run it online yourself on OnlineGDB here, or from my eRCaGuy_hello_world repo here: struct_array_initialization.cpp:
#include <stdint.h>
#include <stdio.h>

// Get the number of elements in a C-style array
#define ARRAY_LEN(array) (sizeof(array)/sizeof(array[0]))

constexpr uint8_t NUM_LEDS = 3;

struct Led {
  uint8_t current;
  uint8_t start;
  uint8_t target;
  uint32_t startTime;
  uint16_t duration;
};

// To initialize once at construction. This form of aggregate initialization
// can be used anywhere: both inside and outside functions.
Led leds[NUM_LEDS] = {
    { 1,  2,  3,  4,  5},
    { 6,  7,  8,  9, 10},
    {11, 12, 13, 14, 15},
};

// Print the full contents of an array of `Led` structs
void printLeds(const Led ledArrayIn[], size_t ledArrayLen)
{
    for (size_t i = 0; i < ledArrayLen; i++)
    {
        printf("ledArrayIn[%lu]\n"
               "current   = %u\n"
               "start     = %u\n"
               "target    = %u\n"
               "startTime = %u\n"
               "duration  = %u\n\n",
               i,
               ledArrayIn[i].current,
               ledArrayIn[i].start,
               ledArrayIn[i].target,
               ledArrayIn[i].startTime,
               ledArrayIn[i].duration);
    }
}

int main()
{
    printf("Hello World\n\n");

    printLeds(leds, ARRAY_LEN(leds));

    printf("==============\n\n");

    // Do this to set or change the structs at any time AFTER construction!
    // This variable (re)assignment is only allowed inside of a function, NOT
    // in the global scope outside of all functions!
    leds[0] = {10, 20,  30,  40,  50};
    leds[1] = {60, 70,  80,  90, 100};
    leds[2] = { 0,  0, 255,   0, 300};

    printLeds(leds, ARRAY_LEN(leds));

    return 0;
}

Sample output:
Hello World

ledArrayIn[0]
current   = 1
start     = 2
target    = 3
startTime = 4
duration  = 5

ledArrayIn[1]
current   = 6
start     = 7
target    = 8
startTime = 9
duration  = 10

ledArrayIn[2]
current   = 11
start     = 12
target    = 13
startTime = 14
duration  = 15

==============

ledArrayIn[0]
current   = 10
start     = 20
target    = 30
startTime = 40
duration  = 50

ledArrayIn[1]
current   = 60
start     = 70
target    = 80
startTime = 90
duration  = 100

ledArrayIn[2]
current   = 0
start     = 0
target    = 255
startTime = 0
duration  = 300

Other references:

https://en.cppreference.com/w/cpp/language/aggregate_initialization
[my answer] https://stackoverflow.com/questions/61240589/how-to-initialize-a-struct-to-0-in-c/61240590#61240590

Regarding the first paragraph of your answer; What does "I've upvoted @Edgar Bonet's answer, because it is correct." have to do with the question?


text:
Wemos D1 mini won't connect to WiFi: status code 6
So I have a Wemos D1 mini which I want to connect to my WiFI in order to let is push sensor data to my server. But I cannot connect it with my WiFi as I get a code 6.
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
  Serial.print(WiFi.status());
}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

The Serial.print(WiFi.status()); prints 6 which is WL_CONNECT_FAILED if I'm right.
I checked the router and it uses WPA/WPA2, the ssid and password are correct. The router is using 2.4 GHz with WiFi 802.11b and 802.11g.
I used the board to scan, with the example code provided by the esp8266 board manager library thing, and it found my SSID with the ones of my neighbors.
Can somebody tell me what is going wrong?
I already checked solutions like: This one , github answers, etc.
Edit: It can connect to a mobile phone hotspot. It gives code 6 1 time and then it connects. Any one an idea how I connect to the WiFi the router is providing ?

6 is WL_DISCONNECTED. what is while while?

@Juraj I see I copied a code I tried. One solution was to take WiFi.waitForConnectResult instead of WiFi.status(). It is fixed now. Where did you find that 6 is WL_DISCONNECTED?

in the source code of esp8266 Arduino 2.7.4 in libraries/ESP8266WiFi/src/include/wl_definitions.h

run a sketch with WiFi.disconnect() only. run it only once.

@Juraj that did not fix it

@dandavis Yes it is, it is a requirement by the router

i always start my wifi section with   WiFi.disconnect();delay(24);  WiFi.mode(WIFI_STA);, which fixes a few problems for me.

@dandavis I tried it but the code 6 still remains

Apparently, something went wrong with connecting to the router. The router was casting 802.11 g + n, which for some reason, made the esp8266 give a code 6. I have tried 802.11 b, 802.11 b+g+n, 802.11 n, which work all fine.
So I updated the settings that the router now uses 802.11n and the esp8266 can now connect to the internet!

If you can later say more definitively what it was, you can edit your answer for future readers.  In a little over a day, I think, you'll be able to accept your own answer, and probably should.

For me, the solution was manually setting the mode to 802.11g as explained here: https://github.com/esp8266/Arduino/issues/8412
Add the following code before connecting the WiFi:
WiFi.setPhyMode(WIFI_PHY_MODE_11G);


text:
Troubleshooting WS2812b LED strip with toggle on/off button
I have a very rudimentary setup with an arduino nano, an LED strip, a pushbutton and a resistor.
I was trying to use the pushbutton as a toggle, using this code
#include <stdio.h>
#include <stdlib.h>
#include<FastLED.h> // header file

#define NUM_LEDS 14 // number of led present in your strip
#define DATA_PIN 12 // digital pin of your arduino

CRGB leds[NUM_LEDS];

const int button = 2;            // GPIO 8 for the button
int status = false;

void setup() {
  //Serial.begin(9600);
  pinMode(button, INPUT);         // define button as an input
  pinMode(DATA_PIN, OUTPUT);           // define LED as an output
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}

void loop() {
  if (digitalRead(button)==true) { // if button is pressed
    // flip status
    //Serial.println("Changing status");
    status = !status;
    //Serial.println(status);
    toggle(status);
  }

  while (digitalRead(button) == true) {
    //Serial.println("while loop");
    delay(50);
    //Serial.println(status);
  }//

  delay(50);
} // begin again

void toggle(bool status) {
  if (status == true) {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::White;  //set the all leds to white
    }
    FastLED.show();
  } else {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;  //set the all leds off
    }
    FastLED.show();
  }
}

This is my circuit

I am powering this from a battery (PNY model 12200, 2200 mAh, Output 5 V=1A) via USB into the arduino board. I am having some issues. Mainly, the lights would go on by themselvs after a while, maybe not full power but still would be on. Not sure where the problem is, any hints appreciated.
I also sometimes get the lights turned off, maybe I'm feeding current into the wrong place and a safety mechanism either on the arduino or the battery stick turns everything off to protect itself?

the switch data pin is floating ... its value is indeterminate ... connect the pulldown resistor to the data pin (the other side of the switch)

use INPUT_PULLUP mode so you don't have to mess with external resistors.

@jstola Unless I misunderstood what to do at the level of the hardware, connecting a resistor from the output of the pushbutton to D2 didn't change the behavior.

@dandavis using INPUT_PULLUP didn't change the behavior either.

while(digitalRead(button) == true);{  I doubt the semicolon there is intentional.  It may help to format your code.  Tools/Auto Format will do that for you.  If the commented out code isn't relevant to the question you might remove it.

"battery via USB", more about the battery. Also what happens if you power from the USB jack via a wall adapter, like you would use to charge a tablet or phone?

@timemage thanks for the code edits. See battery info in the post. It might actually be a battery problem, maybe power supply is not stable, when plugged to an outlet it seems to not turn spontaneously on. I need it to be battery powered for my application so I will try another battery pack

The manual for the T2200, which I think is what you're referring to, says:

Note: If the PowerPack does not automatically power on when a device
is connected press the power button. The PowerPack will turn off after
90 seconds when there are no devices connected.

This is a common feature for USB battery banks meant for charging phones and similar devices.  It probably shuts off when the current drops below some set limit, say 50mA for more than 90s.  But it could also be looking every 90s for the average current over the course of 10ms.  They just don't say.  Given their description it sounds likely that it regularly turns on for some short time to probe for a load.  All in all, not knowing the specifics of this may drive you nuts.  Part of the thing to keep in mind is that someone using this thing to charge a cellphone wouldn't necessarily notice or care if it cut in and out every few seconds.  If you want to use this to power an Arduino it's worth getting a good handle on how it behaves through some experimentation.  Some of these power banks do have a way to disable their load detection and auto-shutoff feature; I did not see anything about that for this model.
The Nano, the official one anyway, has a 500mA PTC polyfuse on the USB VBUS ("5V").  Your code says #define NUM_LEDS 14.  The WS2812b LEDs use something on the order of 50mA each at max output.  You should probably measure what you're actually drawing, with the intensity you are commanding them to be, to be sure you're a good margin below 500mA.  If you are in fact using 14 of them, and if it's possible that all can go full brightness, then you are perhaps trying to use something like 735mA, quite a bit above 500mA.  You way find that it's necessary to route 5V around your Arduino to your LED strip, ideally through its own over-current protection.
Each time you power on or reset your project there's going to be some time before the sketch sets the pin connected to WS2812 data signal to output and some defined level.  It may be a good idea to add an external pull resistor on the LED data signal, probably to GND, so that during power-up and reset the LED strip data signal is not picking up noise and trying to interpret it as color data and changing your load on your power source in the process.  Having the powerbank potentially turning your project on and off gives extra opportunities for this to happen.  If you trip the polyfuse, either by commanding the LEDs to draw too much or having the floating data pin do likewise, the voltage on the Nano side of it will drop.  When the voltage drops it may trip the AVR microcontroller's brownout detector, which in turn will reset it the AVR, again bringing about a floating data pin on your LED strip.


text:
What module should I use for high precision localization?
I have a toy car and I want to measure the coordinates/location of that car in my house.
It need to bee high precision equipment so GPS won't work here.
My precision requriments is 5+- cm and the distance is like 10-20 meters as maximum raduis.
What module should I use then?

you could mount cameras to the walls and track the object optically

@jsotola that won't work for me. It need to be very like GPS, but local.

While there certainly are systems, that work like a local GPS, they will be very expensive and most likely not easy to use. Honestly I wouldn't know, where I would be able to source such a system. Please explain more about the requirements. Why won't cameras work for you?

@chrisl because cameras can't see through walls.

@DanielMårtensson So much I already thought. Please add a description of your general goal and setup to your question. I don't think, that a "local GPS" is really a viable option here. But maybe - when we know your setup and requirements - we can suggest different sensors (or maybe a combination of sensors)

there is no "module" you can use. Heck, there's not really anything you can use with an Arduino. There's a few systems that do things like this, though not to that level of precision, and those are lab-based proof of concepts more than working systems. Ultrasonic triangulation might be your best bet fi you can lower the precision requirements a notch or two, but even that's complex AF.

@dandavis Thank you. I think I have to quit my idea then if it's not possible to have a high precision Local Position System inside my house.

@chrisl I don't know my setup or requriments, except it need be small, have 4 wheels and have a precision about 5+- cm. That's all I need.


text:
Is it possible for Arduino as ISP board to flash an ISP master board?
I have a setup of 2 Arduino Leonardo boards. Let's refer to them as Board A and Board B.
Board A is a master SPI board that is constantly communicating via SPI to an array of sensors. At some point, board A will need to be flashed with a new sketch.  That's where Board B comes in.
I want to use Board B go use an Arduino as ISP sketch to go and flash a new sketch onto board A. Problem is that Arduino as ISP uses SPI, which conflicts with the code on board B since board B is a master device communicating to other sensors via SPI.
Is it possible for board B to flash board A via ISP?

the ISP flashing is done in reset state. there is no SPI used then. but the connected SPI slave can interfere

Your code is not running when your new code is uploaded.

Yes, you can flash an MCU using ISP even if the MCU acts as an SPI device (be it master or slave). The programmer puts the MCU into reset mode, so at the time the sketch is uploaded, SPI will be disabled anyway.
Another thing you need to think of are the other SPI devices (the sensors or what ever the MCU controls). They can pick up the SPI signals sent by the programmer and occasionally write on the bus themselves, therefore disturb communication on the MISO line, which would be critical. There are two options to handle this:

Simply disconnect any SPI slaves during code upload
Make sure there are pullups on the CS lines so they have a defined state (they might be floating while the MCU is in reset). Some slaves might require pulldowns to be deactivated, but that's uncommon.

Thanks for the detailed reply! Questions: when you say CS lines, are you referring to the slave select lines? And are pull ups resistors where one end goes to vcc, and the other goes to the slave select port on the sensor? Right now I'm imagining that somehow the pull up resistor is keeping the slave select line high during reset. I guess because it's common for slaves to be active low. If a pull-up keeps the SS high, how does board A in normal operation drive the SS line low to say "hey sensor, send me data"?

the SPI protocol says that the selected slave has SS LOW and slaves with SS HIGH should not access the bus

@SomeGuy yes, I'm referring to slave select lines. yes, pullups are connected between Vcc and the line to be pulled up. if all of your slaves have pullups anyway, you should have no problems to upload code


text:
ESP8266 and interrupts - not possible?
I'm planning to use an ESP8266 (Wemos D1 Mini) to use as a software SPI monitor to send over WiFi.
As a test, I've done a cut-down sketch that just counts the interrupts, a simple frequency counter. I've made it as simple as possible but it won't stay connected to WiFi and crashes after about 10 seconds.
The input signal to CLKPin is 6667 Hz.
Here's the sketch:
#include <ESP8266WiFi.h>

const char* ssid     = "SSID";
const char* password = "PASSWORD";

long nextPrint = 1000; // when to print the next message to serial

const int CLKPin = 5; // Pin connected to CLK
volatile long ClkCount = 0; // number of times clock interrupt has fired

void CLK_ISR() {
  ClkCount++;
}

void setup() {
  Serial.begin(115200);
  long startTime = millis();

  WiFi.begin(ssid, password);             // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");

  while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to wifi");

  attachInterrupt(CLKPin, CLK_ISR, RISING);

  //Set the CLK-pin to input
  pinMode(CLKPin, INPUT);
}

void loop() {
  if (millis() > nextPrint) {
    Serial.print("Freq is: ");
    Serial.println(ClkCount);
    ClkCount = 0;
    nextPrint += 1000;
  }
  yield();
}

It always gets in a reboot/crash loop (no idea why the first few counts are wrong - I guess the ESP isn't ready yet):
Connecting to SSID ...
.Connected to wifi
Freq is: 1
Freq is: 1
Freq is: 0
Freq is: 0
Freq is: 1
Freq is: 0
Freq is: 2313
Freq is: 6667
Freq is: 6666
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667

Exception (0):
epc1=0x40202034 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys
sp: 3ffffc40 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffde0:  401067da 00000026 00000000 00000001
3ffffdf0:  c0017025 3ffe8d04 3ffee188 00000001
3ffffe00:  00000003 00000008 3ffee99c 00000022
3ffffe10:  3fffc200 401067a0 3fffc258 4000050c
3ffffe20:  40004384 00000030 00000012 ffffffff
3ffffe30:  60000200 00000006 30043003 80000000
3ffffe40:  20000000 3fff0c38 80000000 203fc120
3ffffe50:  00000000 3fffc6fc 00000001 3fff0c3c
3ffffe60:  00000154 003fc120 60000600 00000030
3ffffe70:  40106845 00000080 00000022 3fffc200
3ffffe80:  c0017025 3fffc258 4000050c 00000022
3ffffe90:  3fffc200 401067a0 3fffc258 00000022
3ffffea0:  3fffc200 401067a0 3fffc258 4000050c
3ffffeb0:  40202b20 00000030 00000012 ffffffff
3ffffec0:  40000f49 3ffee9e8 00000000 3fffd9d0
3ffffed0:  00000000 00000000 00000000 fffffffe
3ffffee0:  ffffffff 3fffc6fc 00000001 3fffdab0
3ffffef0:  00000000 3fffdad0 3ffee9e8 00000030
3fffff00:  3ffee99c 0000000a 3ffe8bc8 402094cc
3fffff10:  00000000 400042db 3ffeff84 40104580
3fffff20:  40004b31 3fff0b84 000001f4 003fc080
3fffff30:  40105aac 000001f4 3ffed190 401004f4
3fffff40:  40106e4d 3fff0b84 00000000 00f8676f
3fffff50:  3ffe8bc8 3ffe8d04 3ffed190 40224d02
3fffff60:  40223d49 40223d52 3ffed004 3ffee1b0
3fffff70:  40228445 3ffed004 3ffee1b0 00f857fe
3fffff80:  4022848a 3fffdab0 00000000 3fffdcb0
3fffff90:  3ffee1c8 3fffdad0 3ffee9e8 40202b43
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(1,6)

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

wdt reset

What am I doing wrong, or is it just not possible to stay connected to WiFi while using interrupts on an ESP8266?

Does it still crash if you reduce your CLKPin rate from 6667Hz to something lower?  The reason I ask is that I'm not sure what the maximum interrupt rate the ESP8266 but you may be exceeding it.  The error is a "wdt reset" which means that you have done something to prevent the watchdog timer from being cleared and so it generated a reset.

If you want to get the time difference of the last counter reset and the actual millis() value then  nextPrint += 1000; is nonsense. Use nextPrint = millis() + 1000; if you need to capture the ClkCount for an interval of a second. I'm pretty sure that's the reason for the low values at the beginning. In addition to what @jwh20 said: I'm not convinced that the Watchdog is the cause, I think another Error  (perhaps caused by the WIFI lib) crashed the ESP and then the Watchdog did it's job and performed a reset. But it's a guess, jwh20 might be right, so try what he/she wrote.

Just tested, and it did stay connected at 5kHz for 15 mins when I stopped testing. Unfortunately I'm not sure if that'll be fast enough for my application. I still would like to know if there's anything I can do to keep the WiFi connected. I don't really mind about missing data but I need the WiFi to stay connected. I hoped that yield() would work.

@PeterPaulKiefer I didn't put much thought into getting accurate data for this test, I was just testing if the interrupts would work and stay connected to WiFi, so that timer code is just the first thing that came to mind.

What I suspect is going on, but have never tried this myself on an ESP8266, is that you are interrupting so often that the WiFi can't work properly and it disconnects.  I'm not sure if you can do what you are trying to do with an 8266.  Have you looked at an ESP32?  These have a dual-core CPU so you can handle the WiFi on one processor and handle your interrupts on the other.

You can always try to run your CPU at 160MHz (it's there in the board options if you have the Wemos D1 Mini board).

@jwh20 I agree, but it is disappointing. I tested the ESP32 and it worked fine up to 10kHz which is all I tested to, but I was hoping to get use out of some of these ESP8266's that I have lying around!

@jwh20 I found the solution, see my answer.

I found the solution on another forum.
You need to add the ICACHE_RAM_ATTR attribute to the interrupt so it stays in cache.
void ICACHE_RAM_ATTR CLK_ISR() {
  ClkCount++;
}

Now:
Freq is: 332596 - connected for 680s, operating at 160MHz

That's all I tested to, but 330kHz is a bit better than crashing at 7kHz, lol!
edit: I've discovered that it now crashes after exactly 1200s (20mins), repetitively.
I'm still investigating why, but I believe that it's some kind of watchdog timer.

Yes possible, but the ESP8266 only has one core and one set of peripherals. WiFi uses time, interrupts, and even the ADC peripheral, and maybe more.
This is why anything timing-critical, or time-intensive, is a pain to get to work properly on an ESP8266. It depends one what you are trying to do, of course, and also on if you can unload what you want to a peripheral the WiFi doesn't use, or if switching off WiFi is an option during parts of your code.
Generally, for applications such as yours, I would get an ESP32 or an Arduino Nano 33 IoT or any other solution that has a core for handling WiFi, and a core for you to use without restrictions. It makes development a more pleasant experience.
If, for some reason, you are bound to using an ESP8266, you would have to be more specific about what your eventual goal is; maybe a workaround can be found.

could also use a 2nd ESP8266 w/ wifi disabled, they are cheap, and w/o wifi, very fast and responsive.

Honestly I think ESP8266 is a poor choice for most things except wifi. PWM is flaky, it has no waking from sleep on external interrupt, and relatively high power usage compared to, eg STM32 or AVR. The only thing it's really good for is WiFi and large flash storage. Yes it could be an option in some circumstances, but two won't fit in the application I'm planning for right now.

@localhost fair nuf, I most like the cost and cpu/ram. Tbf, those issues are better w/o wifi; stable pwm, lower power, quick reboots.


text:
Replacing the IC (atmega328) if lifespan has been arrive
Consider if the lifespan of atmega328 has been wear out.
It said on datasheet of atmega how many times we can upload sketch about 10.000times (cmiiw), should i change the arduino or only the microcontroller after 10.000 times have been arrive? what if that times has been arrive? What happened with that IC? If it will starting problem, can we change only the microcontroller (atmega328PU)?? Or any there's thing or stuff we must change too?
Should i burn the bootloader to that IC after replace it?

You realize, I hope, that it's very unlikely that you will ever upload a sketch to an Arduino 10000 times.

10,000 is 30 times a day for a year, surely it deserves a retirement with benefits after that service.

You only need to change the IC, not the entire board. The microcontroller IS the IC.
Also, you will not see any degradation, it will just 'suddenly' fail, or starting to fail sometimes, without any warning or counter that counts up/down to 10,000.
Also keep in mind that this number is the MINIMUM guaranteed value, most ICs will go much further.
The best way to prevent getting into problems related with this issue is:

When you have a finished project and it works, just keep that IC for that project.
In case you fear getting into this problem during development, only change it if you are sure you have problems (i.e. you cannot upload your sketch anymore).
Think before uploading 100 times per day a sketch for debugging purposes (add Serial.print lines, or even better, use a PC to debug all non Arduino related code.

So what you mean is Serial.print  for debugging instead of uploading code many times which it makes lifespan of atmega328 decreased, i was used to use arduino simulator on tinkercad.com, until i bought arduino board. So it's a bad habit to upload many times only for debug?

I don't have experience with the simulator. Uploading 100 times per day is quite a lot, and you can do it for 100 days to reach 10K, and probably many more. I wouldn't worry that much. However, another reason to add Serial.print statements or testing code on a PC is that is normally saves a lot of time (to really see what is happening and not 'guessing' or trying randomly to get things right.

It will be a long time before you reach the maximum number of sketch uploads so don't worry too much about it. Serial.print is meant to speed up the development/debugging process and can help reduce the amount of testing and code uploads needed as well as reduce the overall time needed for your software to work.

Can i debug with only with Serial.print without upload to board, i think it's impossible. So what u mean with reduce and overall time needed? I was debugging with lcd 16×2. Which that lcd actually a part of my project.

Actually Serial.print is not really debugging (meaning stepping through the code), but it's better than nothing. You have to upload to the board because the code only is executable on the Arduino. What I meant was that you can create some code on a PC, test it, and copy it to the Arduino, but only if it's not related to the hardware. E.g. a class that calculates something.  In principle you could create a class that 'mimics' the 16x2 to be run on a PC but that is quite tricky to do. In your case, I would just use print statements to see if your code is functioning well.

you can use tinkercad's online Arduino simulator to test code without any wear on equipment. it even simulates some hardware. I use it to work on libraries since it's faster than constantly uploading.

@dandavis That sounds like a good approach too. Myself used for one project self written stubs using a PC, more work but it was for a dedicated DMX (light) project.


text:
Extend program space by getting rid of bootloader on NANO
I just have a complex program that runs on a NANO. Now when I use my printlns for debugging I am running out of memory.
I read about using a programmer to get rid of the bootloader that uses 2K space on a NANO. I bought an USBTinyIsp and got it to work successfully... almost I can program the nano as I wanted, but I do not get any additional space.
When programming with debug printlns I run into the same message as before which states the same maximum space within (I guess it was 30700).
Why is this the case? I thought the bootloader gets overridden when using a programmer and so frees 2K of programmable space.
Please note: I am not asking how to optimize my program code! Thank you for taking notice ;)
Thank you very much.

the 'New bootloader' has only 0.5 kB, but arduino didn't change nano.menu.cpu.atmega328.upload.maximum_size

When I get in space crunch I will do the code on a mega then when it is debugged shrink it to the nano. Not a perfect answer but a workable one.

It's enforcing this line from the arduino:avr boards.txt
nano.menu.cpu.atmega328.upload.maximum_size=30720

To be clear, the board is assumed to have a bootloader, even if you're not using it to get the code onto the board, that is upload via programmer.
You could edit that and change some fuses yourself.  But you could also probably just use MCUdude MiniCore, choosing an option that does not use a bootloader, e.g. ATmega328P with No bootloader, which gives you maximum upload of 32768:
328.menu.bootloader.no_bootloader.upload.maximum_size=32768

Keep in mind that in either case you'll have needed to set the fuses for not having a bootloader.  As weird as this sounds, choosing the No Bootloader option in MCUdude MiniCore for the ATmega328P, and then doing Burn Bootloader sets these fuses for you, despite the name not actually burning a bootloader in this case.  If you were to edit the maximum upload size for the Nano board, you would need to manually set the fuses similarly to what Burn "Bootloader" does for the MiniCore ATMega328P with No-bootlader option.

Thank you very much! Just tried your first point which worked like a charm! Saved me a lot of time, I owe you a beer!

Additional information: As i had a reinstall of my System, I also had to reconfigure my boards.txt. I stumbled over this blog, which is explaining the fuses quite well: http://www.martyncurrey.com/arduino-atmega-328p-fuse-settings/

I would make a point of reading the datasheet rather than that.  For one thing it says "I imagine RSTDISBL is implemented for security reasons to stop the chip being reprogrammed or the firmware being downloaded".  No, not really, there other features for that.  RSTDISBL exists mostly to allow that pin to function as normal GPIO.  Anyway, read the datasheet for more accurate descriptions.