text:
How to handle class initialization when using brace-enclosed initializer lists
I'm working with a custom C++ library, CPSTL, for Arduino, which includes a cpstd::vector class that is designed to work with cpstd::initializer_list, cpstd::initializer_list is supposed to mimic std::initializer_list.
However, I'm having trouble initializing a cpstd::vector using brace-enclosed initializer lists.
I've looked up many sources online, and it seems there is not a lot of information in the topic, but came up to things such as FastArduino: initializer list, and Arduino STL: Initializer list. Giving me hopes that it is actually possible. (I can't use those libraries, because they lack the build system generation tools on the library I am developing, they also lack on customizability, and also as a good learning experience)
I've tried various approaches, but I keep getting the error:

could not convert '{0, 1, 2, 3, 4}' from 'brace-enclosed initializer list' to 'cpstd::vector'.

Here's an example of the code that's causing the issue:
    cpstd::vector<unsigned char> myVector = {0, 1, 2, 3, 4};

I have already implemented a custom cpstd::initializer_list and constructor that should handle this, but the issue persists. Is there something specific to the Arduino environment that could be causing this issue?
Additional Information:

I have verified that the cpstd::initializer_list is correctly defined and included in my code.

The cpstd::vector class is included and accessible.

I have reviewed my cpstd::vector class, and the constructor for cpstd::initializer_list is correctly implemented.

While reading the error log, I noticed that std::initializer_list constructor has two parameters, a pointer to the data, and also a variable telling the length of the braced enclosed list, however I noticed that the list ends up casting to a single parameter, hence having no possible constructor to call

What could be causing this issue, and how can I resolve it to initialize cpstd::vector using brace-enclosed initializer lists in the Arduino environment? I think the main issue is with boards that have no STL support. (i.e. AVR based boards)
I've came to the conclusion that it will not be possible to create such constructors/operators due to compiler limitations, I think I've tried anything that came to mind. But I don't want to give up on this without knowing if there is a workaround.
edit (removed previous code snippets for clarity, added minimal code example reproducing the error) :
minimal sketch reproducing the error:
#include <Arduino.h>
#include <stddef.h>

namespace cpstd {

  template<typename T>
  class initializer_list {
  public:
    using value_type = T;
    using reference = const T&;
    using const_reference = const T&;
    using size_type = size_t;
    using const_iterator = const T*;

  private:
    const_iterator _M_array;
    size_type _M_len;

    constexpr initializer_list(const T* array, size_type size) noexcept
      : _M_array(array), _M_len(size) {}

  public:
    constexpr initializer_list() noexcept
      : _M_array(nullptr), _M_len(0) {}

    constexpr size_type size() const noexcept {
      return _M_len;
    }
    constexpr const_iterator begin() const noexcept {
      return _M_array;
    }
    constexpr const_iterator end() const noexcept {
      return _M_array + _M_len;
    }
  };
}

template<typename T>
class exampleClass{
  protected:
    T buffer[10];
    size_t len;

  public:
    exampleClass(): len(0) {}
    exampleClass(cpstd::initializer_list<T> il){
      len = il.size();
      for(size_t i = 0; i < len; i++){
        buffer[i] = *(il.begin()+i);
      }
    }

    exampleClass& operator=(cpstd::initializer_list<T> il){
      len = il.size();
      for(auto i = il.begin(); i < il.end(); i++){
        buffer[i] = *i;
      }
    }

    size_t size() const {return len;}
    T data(size_t x) const {return buffer[x];}
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  exampleClass<uint8_t> myObject = {0,1,2,3};

  Serial.println(myObject.size());
  Serial.println(myObject.data(0));
  Serial.println(myObject.data(1));
  Serial.println(myObject.data(2));
  Serial.println(myObject.data(3));

}

void loop() {
  // put your main code here, to run repeatedly:

}

To the close voters because "off-topic": Since the Arduino build system does magic under the hood, it can well be the "culprit." Therefore, I see this question as on-topic.

The underlying compiler system is a common GCC, therefore I don't think that the compiler is limited. However, my current situation does not allow me to investigate by reproducing the issue. -- In the meantime, would you mind to [edit] your question and extend the provided source to a minimal, complete, and reproducible example, please? You don't want each of us to invest that time,do you?

@thebusybee my bad, I'll sure add a complete, and reproducible example

Just a random thought: does it work if you initialize the vector with cpstd::vector<unsigned char> myVector{0, 1, 2, 3, 4}; (without the =)?

@EdgarBonet I did try, but the same happens, since the problem is that the compiler wont convert {x, x, x} to a cpstd::initializer_list

So I have been messing around with the minimal example code and found a working solution, I'll post the solution just in case someone finds themselves having the same issue on the future, the only downside is that it feels a bit hacky to my taste, I still wonder if there is a better solution. And would gratly appreciate any feedback.
I found out that the compiler does not ackowledges the initializer_list class for braced enclosed initializers if the class is not under the namespace std.
The way I came arround this problem lies on using the preprocessor directive below:
#if __has_include(<initializer_list>)

With this line conditional compilation takes place, and we can specify what to do whenever std::initializer_list is present or not.

If std::initializer_list is not present an implementation is provided.
cpstd::intitlizer_list is only a template alias of std::intitializer_list

minimal sketch with the solution:
#include <Arduino.h>
#include <stddef.h>

namespace std {

  template<typename T>
  class initializer_list {
  public:
    using value_type = T;
    using reference = const T&;
    using const_reference = const T&;
    using size_type = size_t;
    using const_iterator = const T*;

  private:
    const_iterator _M_array;
    size_type _M_len;

    constexpr initializer_list(const T* array, size_type size) noexcept
      : _M_array(array), _M_len(size) {}

  public:
    constexpr initializer_list() noexcept
      : _M_array(nullptr), _M_len(0) {}

    constexpr size_type size() const noexcept {
      return _M_len;
    }
    constexpr const_iterator begin() const noexcept {
      return _M_array;
    }
    constexpr const_iterator end() const noexcept {
      return _M_array + _M_len;
    }
  };
}

namespace cpstd {
  template<class T>
  using initializer_list = std::initializer_list<T>;
}

template<typename T>
class exampleClass{
  protected:
    T buffer[10];
    size_t len;

  public:
    exampleClass(): len(0) {}
    exampleClass(cpstd::initializer_list<T> il){
      len = il.size();
      for(size_t i = 0; i < len; i++){
        buffer[i] = *(il.begin()+i);
      }
    }

    exampleClass& operator=(cpstd::initializer_list<T> il){
      len = il.size();
      for(auto i = il.begin(); i < il.end(); i++){
        buffer[i] = *i;
      }
    }

    size_t size() const {return len;}
    T data(size_t x) const {return buffer[x];}
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  exampleClass<uint8_t> myObject = {0,1,2,3};

  Serial.println(myObject.size());
  Serial.println(myObject.data(0));
  Serial.println(myObject.data(1));
  Serial.println(myObject.data(2));
  Serial.println(myObject.data(3));

}

void loop() {
  // put your main code here, to run repeatedly:

}

Well done! Unfortunately answer should not contain follow-up questions, and the one about the keyword looks as non-Arduino specific, too. I suggest to post this one separately on [so].

I added the questions in my answer in case someone else wanted to add another answer, I think those are arduino specific questions because it implies using the arduino toolchain to reproduce the problems, I did not have this issues when compiling on other systems

As I commented, the underlying compiler is a common GCC. There is apparently nothing Arduino specific. However, this second question is a different issue, and as such needs its own question. You might want to link back to here. Please note that this is not a forum.

@thebusybee, you're right, im removing the questions from the answer


text:
Triggering a picture with esp32-cam and GPIO13
I'm trying to trigger a picture using the GPIO13 of an esp32-cam, AI Thinker model.
I'm using that example as a base:
https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/
but instead of the PIR/Transistor combination, I'm using a press button with a pull-up resistor that pulls the GPIO13 pin down when pressed, simulating the PIR signal.
I'm feeding the esp-32 cam with a 5V power supply and the button circuit with the 3.3v
pin of the esp32, all grounded.
All hardware, SD card and so on is tested ok, I got the right voltages and I can see the GPIO13 Pin going to ground on my scope, but I just doesn't work.
Any ideas?
Edit 1: I'm using the ESP32-CAM-MB USB Board

What is it printing on the serial output?

I cannot watch the serial port while running this, as the board doesn't have a USB port.

@brunobhr Then use your programmer board to see the serial output. The same that you're using for flashing the chip.

You cannot run the board in flashing configuration.

I don't seem to have any problem running an ESP32-CAM while looking at its serial connection. I don't understand why you are. However, you can at least make a function that blinks an LED call that from places where error messages are also printed. You can add to the question what you find out.

If you're using the ESP32-CAM-MB: The -MB has an usual requirement with respect to control signals. It will not show you sketch serial output in just any terminal software. If you use the latest IDE and select the correct board it will set the control signals as necessary will show sketch output, including your diagnostic messages.

@timemage Thank you. Unfortunately my -MB model makes it impossible to hook up external circuits when plugged in. I'll have to desolder it and re-solder longer pins, or find a way to read the serial monitor on an LCD

I don't understand, but then I can't see your wiring either. If more information shows up in the question, e..g if you post wiring and/or take the LED blinking suggestion, maybe there will be some way of helping.

Checking the specs of the cam board, I see that GPIO13 has the function HS2_DATA3, suggesting that the SD card is using that pin (which is also corroborated by this article.)
This may or may not be a problem, as the state of GPIO13 is only relevant for sleep/wakeup when the chip is sleeping, and only relevant for SD card access when the chip is running; but there is an external addon: your pullup resistor on the button is still there when the chip is running. The PIR module from the tutorial that you're trying to replace probably has an open collector output (floating when inactive, pulled LOW when active).
My best hunch is to get rid of the pullup resistor on your button, so that the pin is floating during SD card access.
There still is the possibility that you then interfere with the SD card data when you keep the button pressed. If that is the case, you may need to put a resistor in series with the button, so that the wake-up signal is weaker than the SD card data signal (start at 100KOhm and reduce until wake-up works).
If that isn't it, the question is lacking details. As you did not even post a description of what exactly "just does not work", first thing would be to produce a minimal sketch just to test sleep/wakeup via GPIO13 and post that here.

Thank you, but how does the code provided in the link deals with that? I'm just replacing a signal by another..

Also, getting rid of the pullup resistor and adding any value in series doesn't change anything.

And doesn't work means it's not acting as intended eg. no picture on the SD Card.

The code in the example link is doing wakeup through GPIO13

@brunobhr Yes, you're replacing one signal with another, but we don't know what type of signal you're replacing. The PIR from the tutorial probably provides a weak open collector output to ground, but your button originally is a strong push-pull output.

@brunobhr You'll need to tell what exactly is "not working". An image on the SD card is the desired end result, but there are a lot of steps to check beforehand: Can you flash the cam board successfully? Which output on the serial line comes up after flashing? Does the chip go to sleep successfully? Does it wake up successfully? If no, can you make it wake up by other means (e.g. taking a wire to pull GPIO13 to 3.3V or GND)? What is printed on the Serial output after waking up? Are there any status LEDs on the board, and if yes, when are they lit up?

Sorry but have you read the link I provided?

Yes, I have read the link, but those tutorials never go into the details you need if you're altering the setup in the slightest.

I'm just trying to get a pin to ground, this example works according to the comments. Now asking me if I can flash my board is not gonna get us somewhere I think. Thank you anyway

source: Stack Exchange

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

sort: votes


text:
"if" condition problem / question
I'm new to Arduino and my question is rather theoretical. I have an Arduino Nano board (Atmega168 processor), a button, a display. I have written a button handler that does not stop code execution. My idea is: poll the button in "loop" cycle, and if it is pressed, perform k++. When k exceeds a specified value, perform cnt++ and print it on the display.
Code example №1 works correctly. I get 1 -> 2 -> 3 -> ...:
void loop() {
 if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
    }
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(cnt);
  }
}

Code example №2 is incorrect. I get 16 -> 27 -> 40 -> ... Seems like not cnt is printed, but k.
void loop() {
  if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(cnt);
    }
  }
}

Here's my program:
#include <LiquidCrystal_I2C.h>

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

void setup() {

  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);

}

void loop() {

  // button handler

}

My question is. Why examples №1 and №2 work differently?

The timings are different.
Every operation on the LCD takes time. This:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(cnt);

involves some I2C communication, and thus takes orders of magnitude more
time than k++;.
On the first version of your loop(), these operations are performed on
each iteration, while the button is being pressed. On the second
version, they are performed only when k reaches 20, thus twenty times
less often. The second version thus runs twenty times faster... too fast
for the LCD to correctly refresh and show all the values it is being
asked to display.
I recommend you do not rely on loop counting for controlling timings.
Instead, use the Arduino function specifically designed for time
management. For example, if you want to increment the counter every
200 ms, you should record the time when the button is pressed (the
falling edge of the signal), and increment cnt 200 ms later:
uint8_t previous_state;  // previous state of the button
uint32_t press_timestamp;  // time when the button was pressed

void loop() {
    uint32_t now = millis();
    uint8_t state = digitalRead(button_pd);
    if (previous_state == HIGH && state == LOW)  // falling edge
        press_timestamp = now;
    previous_state = state;
    if (state == LOW && now - press_timestamp >= 200) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }
}

Ah, understood... Thank you!

Unfortunately, result is still incorrect. Like 0 -> 10 -> 10 -> 10 -> 21...

I've modified your code a little. Modified version worked for me. Thank you for the idea!

Thanks. Somehow code example №3 works correctly. I have used a library for timer and simplified code from the answer above.
#include <LiquidCrystal_I2C.h>
#include <millisDelay.h>       // Timer

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

//uint8_t previous_state;  // previous state of the button

millisDelay d;

void setup() {
  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);
}

void loop() {

    uint8_t state = digitalRead(button_pd);
    if (state == LOW)
        d.start(300);
    //previous_state = state;
    if (d.justFinished()) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }

}

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


text:
Bluetooth (HC_06) on the Attiny85
I'm trying to make a hc_06 Bluetooth controller work on the attiny85-20pu.
In the end, I want to control a stepper motor through Bluetooth.
But for now to keep it simple I'm searching for a working code that can turn a simple LED on and off or something like that.
I've searched for a code like that, and I found a few, but they all don't seem to work when I try it.
I checked if the hc_06 maybe wasn't receiving any data or maybe that my wiring was wrong, but at this point I doubt it since I've tried so many different codes and re-wired it so much that I feel like at least 1 should've worked by now
For reference, here are 2 codes I've tried so far but didn't seem to work
source1: https://community.appinventor.mit.edu/t/attiny85-microcontroller-bluetooth-hc-06-arduino-ide/20252/2
source2: https://community.appinventor.mit.edu/t/attiny85-microcontroller-bluetooth-hc-06-arduino-ide/20252/2
#include <SoftwareSerial.h> //Software Serial Port
#define TxD 0 //pin 5 de l'ATtiny à relier au pin RXD du module bluetooth (pin5)
#define RxD 1 //pin 6 de l'ATtiny à relier au pin TXD du module bluetooth (pin4)

SoftwareSerial blueToothSerial(RxD,TxD);
int relais = 4; // pin 3 de l'ATtiny qui commande le relais

void setup()
{
  pinMode(RxD, INPUT);
  pinMode(TxD, OUTPUT);
  blueToothSerial.begin(9600);
  //delay(2000); // délai nécessaire
  blueToothSerial.print("Bluetooth connecté !\n");
  delay(4000); //Vérifie que tous les relais sont bien inactifs après un reset
  pinMode(relais, OUTPUT);
  digitalWrite(relais, LOW); // ouvre le relais
}

void loop()
{
  char recvChar;
  while (1) {
    //vérifie s'il y a des données envoyées à partir du module bluetooth
    if (blueToothSerial.available()) {
      recvChar = blueToothSerial.read();
      if (recvChar == '1')
        digitalWrite(relais, HIGH);
      else
        digitalWrite(relais, LOW);
    }
  }
}

Or this one
// Tiny85 y Bluetooth HC-06
// Juan A. Villalpando
// kio4.com

#include <SoftSerial.h>
#include <TinyPinChange.h>
#define LED4 4

SoftSerial Bluetooth(2, 3);
char caracter;

void setup()
{
  Bluetooth.begin(9600);
  pinMode(LED4, OUTPUT);
}

void loop()
{
  while (Bluetooth.available() > 0) {
    caracter = Bluetooth.read();
    if (caracter == '1') {
      digitalWrite(LED4, HIGH);
      Bluetooth.println('E');
    }
    if (caracter == '0') {
      digitalWrite(LED4, LOW);
      Bluetooth.println('A');
    }
  }
}

UPDATE
With this code it works but only if I disconnect TX from the HC_06 to RX to the attiny85. If I do that the LED will turn on after a few seconds
and if I then send a 0 it works fine.
hopefully this helps?
#define RxD 1
#define TxD 0

#define DEBUG_ENABLED  1

SoftwareSerial blueToothSerial(RxD,TxD);

int led = 4 ;

void setup()
{
  pinMode(RxD, INPUT);
  pinMode(TxD, OUTPUT);
  setupBlueToothConnection();

  pinMode(led,OUTPUT);

}

void loop()
{
  char recvChar;
  while(1){
    //check if there's any data sent from the remote bluetooth shield
    if(blueToothSerial.available()){
      recvChar = blueToothSerial.read();

        if(recvChar==0)
          digitalWrite(4,HIGH);

        else
          digitalWrite(4,LOW);
    }
  }
}

void setupBlueToothConnection()
{
  blueToothSerial.begin(38400); //Set BluetoothBee BaudRate to default baud rate 38400
  blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
  blueToothSerial.print("\r\n+STNA=MAVA_bluetoothcr\r\n"); //set the bluetooth name as "HC-05"
  blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
  blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here

  delay(2000); // This delay is required.
  //blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
  blueToothSerial.print("bluetooth connected!\n");

  delay(2000); // This delay is required.
  blueToothSerial.flush();
}```

how is everything connected and how is it powered?

depends on which of the 2 codes you mean. but I'm pretty sure its not a wiring problem. And as for the power I'm using a Arduino uno which only use is to power the Attiny85 and hc_06.

Does the HC-06 work correctly with the Unos Serial connection? It might be configured to the wrong baudrate

Its not hooked up to an Arduino but to the attiny85 itself but I did test it on the Arduino and it works just fine. the hc_06 still receives data no problem but somehow nothing happens with that data.

Mhh, is the Attiny running at the frequency, that the compiler is expecting? If you compile lets say for an 8MHz clock frequency, but the fuses still are set to 1MHz, that would also mess with the timing of the software serial interface

I'm not sure what you mean with the fuses of the attiny85 but I did calculate that I should put de baud rate on 38400 if I compile it with 8MHz I'm not sure if that helps?


text:
Make encoder work together with OLED display in Arduino Nano Every
I tried to sketch code to make an encoder to generate a number by each step and show it on OLED display. The OLED will connect with I2C, working on in Arduino Nano Every ATmega4809.
I separately made them for both encoder and OLED, they all work in separate code, encoder to generate Number and OLED display the text on screen.
But after combining them together, it seems to work only the OLED display. The encoder is not responding at all. The encoder will work again when I disable OLED.display() in loop section.
Anyone Please help me to them work together?
This is my sketch
//Display
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// กำหนดขาต่อ I2C กับจอ OLED
#define OLED_RESET     -1
Adafruit_SSD1306 OLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Encoder
#define R_START 0x0
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6
#define DIR_NONE 0x0
#define DIR_CW 0x10
#define DIR_CCW 0x20

const byte pin1 = 10;  // DT
const byte pin2 = 11;  // CLK
int state = R_START;
int counter = 0;
int counter_ini = 0;
int potstep = 0;

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};

unsigned char process(){

  // Grab state of input pins.
  unsigned char pinstate = (digitalRead(pin2) << 1) | digitalRead(pin1);

  // Determine new state from the pins and state table.
  state = ttable[state & 0xf][pinstate];

  // Return emit bits, ie the generated event.
  return state & 0x30;
}

void setup(){
  pinMode(pin1, INPUT_PULLUP);
  pinMode(pin2, INPUT_PULLUP);
  Serial.begin(9600);

  //Display
  if (!OLED.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
  } else {
    Serial.println("ArdinoAll OLED Start Work !!!");
  }
OLED.clearDisplay();
OLED.setTextSize(2);
OLED.setTextColor(WHITE);
OLED.setCursor(5, 10);
OLED.println("   TEST   ");
OLED.println();
  OLED.display();
  delay(5000);
}

void loop(){

  unsigned char result = process();
  if(result == DIR_CW){
    counter++;
    //Serial.println(counter);
  }
  else if(result == DIR_CCW){
    counter--;
    //Serial.println(counter);
  }
  if(counter > counter_ini){
    potstep++;
    Serial.println(potstep);
    counter_ini=counter;
  }
  else if(counter < counter_ini){
    potstep--;
    Serial.println(potstep);
    counter_ini=counter;
  }
  if(potstep > 255){
    potstep = 255;
    //Serial.println(potstep);

  }
  else if(potstep < 0){
    potstep = 0;
    //Serial.println(potstep);
  }
//Display
    OLED.clearDisplay();
    OLED.drawRect(3,3,125,47,WHITE);
    OLED.setTextSize(4);
    OLED.setTextColor(WHITE, BLACK);
    OLED.setCursor(27,12);
    OLED.println(potstep);

    OLED.display();
}


text:
I would like to know why my four gear motors are rotating at different speeds when connected to 2 L293D motor drivers, controlled by the arduino
Ignore direction of the motors(for now).
This is my connection diagram. Any and all improvements to this are welcome.
Bottom left motor seems to run at 210-224 rpm
Bottom right motor runs at 160-180 rpm
Top right motor runs at 210-224 rpm
Top left motor runs at 160-180 rpm

Code for running the below setup:

// Motor A connections

int enA = 7;

int in1 = 4;

int in2 = 5;

// Motor B connections

int enB = 6;

int in3 = 3;

int in4 = 2;

//Motor c

int enC = 9;

int in5 = 12;

int in6 = 13;

// Motor d connections

int enD = 8;

int in7 = 10;

int in8 = 11;

void setup() {

// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enC, OUTPUT);
pinMode(enD, OUTPUT);
pinMode(in5, OUTPUT);
pinMode(in6, OUTPUT);
pinMode(in7, OUTPUT);
pinMode(in8, OUTPUT);

  // Turn off motors - Initial state
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
digitalWrite(in5, LOW);
digitalWrite(in6, LOW);
digitalWrite(in7, LOW);
digitalWrite(in8, LOW);
}

void loop() {
  moveForward();
  delay(3000);
  motorOff();
  delay(1000);
}

void moveForward(){

  analogWrite(enA, 200);
  analogWrite(enB, 200);
  analogWrite(enC, 200);
  analogWrite(enD, 200);

  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(in5, HIGH);
  digitalWrite(in6, LOW);
  digitalWrite(in7, HIGH);
  digitalWrite(in8, LOW);
}

void motorOff(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in5, LOW);
  digitalWrite(in6, LOW);
  digitalWrite(in7, LOW);
  digitalWrite(in8, LOW);
}

Any change to the code is also welcome.

Pins 7 and 8 aren't PWM pins on the UNO.  So when you call analogWrite on them with a value greater than 127 it defaults to digitalWrite and just writes those pins HIGH.  Pins 6 and 9 are PWM pins, so they are responding as expected to the analogWrite.  Since they are outputting PWM and the signal to the other motors is constantly high, they run slower.
You should change your wiring so that all of the enable pins are connected to PWM capable pins.  On the Arduino UNO those are pins 3, 5, 6, 9, 10, and 11.


text:
Print text at any Y-value on SSD1306?
I'm attempting to print several rows of text, at certain Y-values, on an SSD1306 128x64 LCD display.
I'm using the ssd1306 library by Alexey Dynda. I initially wanted to use the more common LCD libraries out there, such as the Adafruit SSD1306 LCD library, however it unfortunately does not appear I can set custom I2C pins for most such libraries out there, which is required as I'm using a custom board with an ESP32-WROOM-DA chip. The ssd1306 by Dynda appears to be able to do so.
I have the following example code, which prints 6 lines of text:
#include "ssd1306.h"
#include "nano_gfx.h"

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

void LCDTextDraw(int x, int y, const char* text)
{
  EFontStyle fontStyle;

  ssd1306_printFixed(x, y, text, fontStyle);
}

void LCDRectDraw(int x, int y, int w, int h)
{
  ssd1306_fillRect(x, y, x + w, y + h);
}

void LCDScreenClear(bool fill)
{
  ssd1306_clearScreen();

  if (fill)
    LCDRectDraw(0, 0, 128, 64);
}

void LCDInit()
{
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_128x64_i2c_initEx(PIN_I2C_SCL, PIN_I2C_SDA, 0);
}

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

  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1");
  LCDTextDraw(30, 10, "TEST 2");
  LCDTextDraw(30, 20, "TEST 3");
  LCDTextDraw(30, 30, "TEST 4");
  LCDTextDraw(30, 40, "TEST 5");
  LCDTextDraw(30, 50, "TEST 6");
}

void loop()
{}

With which I wish to print out 6 lines of text, each line evenly vertically spaced out by 10 pixels.
Which produces the following output on my LCD:

As you can see, the text rows are not evenly vertically spaced out as I wish them to be, with a large space between the TEST 4 and TEST 5 strings.
After looking at the definition of the ssd1306_printFixed function I'm using to print out my text in the example above, it turns out that it can only print rows of text at certain fixed Y-positions:

@warning ssd1306_printFixed() can output chars at fixed y positions: 0, 8, 16, 24, 32, etc.
If you specify [10,18], ssd1306_printFixed() will output text starting at [10,16] position.

Hence, I also tried using the ssd1306_print function (which uses a cursor to delineate its printing location on the screen), which doesn't have that warning in its header declaration. I replaced my LCDTextDraw function with:
void LCDTextDraw(int x, int y, const char* text)
{
  ssd1306_setCursor8(x, y);
  ssd1306_print(text);
}

However, that still produced the exact same output on my LCD, with the same spacing issues.
What is the proper way to print text rows at any Y-value on an LCD?
Thanks for reading my post, any guidance is appreciated.

https://wokwi.com/projects/341940000159433299

@jsotola, a quick look at your linked to Adafruit code and I think I see the same vertical numbers restrictions that Rohit was commenting on.

@Runsva, this is just a guess, but after writing code to interface w/a small Sharp display, there may be some difficulties addressing anomalies which can be avoided by placing images (characters) in constrained locations. Also, these characters may be part of the display programming and their placement is constrained by the display. I think you can do what you want. But you may have to write all the code from scratch.

Turns out using the Adafruit SSD1306 library is much easier than I first thought. One just must specify the I2C pins used with Wire, and pass it as reference to the Adafruit_SSD1306 constructor. Additionally, the Adafruit library doesn't appear to have the uneven vertical spacing issue.
The equivalent code below using the Adafruit library:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

Adafruit_SSD1306 LCD(128, 64, &Wire);

void LCDTextDraw(int x, int y, const char* text, byte size)
{
  LCD.setCursor(x, y);
  LCD.setTextSize(size);
  LCD.print(text);
  LCD.display();
}

void LCDRectFill(int x, int y, int w, int h, int color)
{
  LCD.fillRect(x, y, w, h, color);
}

void LCDScreenClear(bool fill)
{
  LCD.clearDisplay();
  LCD.display();
  LCD.setTextColor(WHITE, BLACK);

  if (fill)
    LCDRectFill(0, 0, 128, 64, 1);
}

void LCDInit()
{
  LCD.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

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

  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  Wire.setPins(PIN_I2C_SDA, PIN_I2C_SCL);
  Wire.begin();

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1", 1);
  LCDTextDraw(30, 10, "TEST 2", 1);
  LCDTextDraw(30, 20, "TEST 3", 1);
  LCDTextDraw(30, 30, "TEST 4", 1);
  LCDTextDraw(30, 40, "TEST 5", 1);
  LCDTextDraw(30, 50, "TEST 6", 1);
}

void loop()
{}

Now produces the desired result:


text:
Get address of a I2C transaction when multiple addresses are registered
I have an application polling 4 ADCs by I2C. The application shall also write on some ADC registers. In order to test it, I'd like to use a single Arduino UNO, enabling it for receiving I2C messages over 4 different addresses by masking the TWAMR register. In this way I can have 4 ADCs "emulated" on a single Arduino.
When the application asks for a read to Arduino at some address, I'm able to get the value of the required address by reading the TWDR register:
void requestEvent(){
  byte addr = TWDR >> 1;
  if (0x4A == addr){ // do something }
  else if (0x4B == addr){ // do something }
  // ...
}

void setup(){
  // ...
  Wire.onRequest(requesEvent);
}

However, when the application requests to write something to a certain ADC (with its own address), I'm not able to get the address value in the onReceive(int) callback:
void receiveEvent(int howMany){
  byte addr = TWDR >> 1; // returns the first byte AFTER the address in the I2C message
}

Am I doing something wrong? Is there a way to reach my goal?
Thanks.
Luca
Edit:
Reading the ATmega datasheet (sec. 22.9.4, p. 241), the problem with reading the TWDR register is that it contains the last byte received, that in slave receiver mode is not the address but the last data sent by the master.
Anyway, is there any workaround for this problem?

This seems unnecessarily complicated to me. You say you are polling, so why not just send a request to 0x4A, and wait for a response, then 0x4B, and wait for a response, and so on?

Actually I've written something incorrect. The application is not only polling. but also writing to some registers of ADC in order to configure it. In particular, the procedure for each ADC is: 1) write to ADC config register to trigger a conversion; 2) poll it continuously until the conversion is completed; 3) request the measure when the conversion is completed. I'm not sure why the application is written in that way, I took it as is. Probably there are some possible improvements on this side, but I'm working on the other end, that is a simulator to test the application

It still seems simpler to me to do a round-robin approach. First, tell each ADC to start the conversion (ie. Start A, Start B, Start C, Start D), then  (Poll A, Poll B, Poll C, Poll D), until some or all have finished the conversion, then  (Read A, Read B, Read C, Read D). It seems too complex to me to be fiddling around with hardware registers when it isn't necessary.

I'm not sure if I've understood your answer. If your advise is to change the design of the device that my arduino is communicating with, unfortunately I can't control it.

I'm not advocating any hardware changes. Why not just send the commands to one ADC after another? If you ask a particular ADC for its response, and wait for it, then surely you know which ADC replied?

As said in the other thread, I'm simulating the behaviour of the ADC using arduino. Arduino implements the simulation of the ADC. Another piece of hardware (that I cannot control) is communicating with arduino believing it's the actual ADC.
Actually the thing is a bit more complex, since a single arduino simulates multiple ADCs.
Basically the actual hardware believes that it is communicating with ADC_i (with i = 1,...,6), but it's actually communicating with only one arduino that implements the logics of the multiple ADCs. I guess this is a common case in HIL simulation.

In this sense I cannot change what the real HW does and how it sends commands to the ADCs. The real HW (that is a microcontroller with its own control algorithms) is developed by others and I have only its requirements to understand how it communicates with the multiple ADCs. I shall make the ADCs simulation in arduino capable of handling all the stuff that the microcontroller is sending on the two wire interface. Hope this is clearer now.

Oh I see. You are pretending to be an ADC, not talking to other ADCs. That is clearer now. In that case what chrisl said makes sense.

Reading the TWDR register in the onReceive() callback doesn't give you the address because of the time, that it is called at. The onReceive() callback is called when all bytes have already been received and put in the Wire libraries internal buffer. Thus in that callback TWDR will still hold the last received data byte.
The onRequest() callback on the other hand is called right after the address was received. Thus TWDR still holds the received address.
You will need to modify the Wire library to achieve your goal. Similar to the onRequest() callback you can introduce a third kind of callback function, which will be executed after receiving the slave address to save the received address for later use (the address matching is still done via hardware, so you still need to mask the address via TWAMR).
You can find the files for the Wire library inside your used core (for me the Uno uses the path ~/.arduino15/packages/arduino/hardware/avr/1.8.5/libraries/Wire). Look at line 581 of src/utility/twi.c. This is inside the TWI ISR, the case clause TW_SR_SLA_ACK, which will be executed on address receive/match. Here you can insert your callback function.
If you want to do this in a similar handy way, that the Wire library does with the other callbacks, then you need to change a few other things:

Insert a function pointer for this at the start of the twi.c file, right besides the other function pointers:
 static void (*twi_onSlaveAddressMatch)(uint8_t);

Add the execution of that function to the case in the ISR described above and provide the content of TWDR (shifted to eliminate the direction bit) as a parameter:
 twi_onSlaveAddressMatch(TWDR >> 1);

Add a function to set the callback function pointer in twi.c:
 void twi_attachSlaveAddressMatchEvent( void (*function)(uint8_t) ){
     twi_onSlaveAddressMatch = function;
 }

Add the callback set function as a function prototype to twi.h:
 void twi_attachSlaveAddressMatchEvent( void (*function)(uint8_t) );

In Wire.h  add a function pointer for the new callback and the corresponding service function inside the private: section:
 static void (*user_onSlaveAddressMatch)(uint8_t);
 static void onSlaveAddressMatchService(uint8_t);

In Wire.h add a function to set the user callback function to the public: section:
 void onSlaveAddressMatch( void (*)(uint8_t) );

In Wire.cpp add the implementation of the service function:
 void TwoWire::onSlaveAddressMatchService(uint8_t address){
     if(!user_onSlaveAddressMatch){
         return;
     }
     user_onSlaveAddressMatch(address);
 }

In Wire.cpp add the implementation of the callback setter function:
 void TwoWire::onSlaveAddressMatch( void (*function)(uint8_t) ) {
     user_onSlaveAddressMatch = function;
 }

Now you should be able to set a callback for the address receive in your main code and save the address for later use:
uint8_t received_address = 0;

void getAddress(uint8_t address){
    received_address = address;
}

void setup(){
    ...
    Wire.onSlaveAddressMatch(getAddress);
}

In the onReceive() callback you can then check for that global variable.
Note: I have not tested or compiled this. I just looked at the logic of the Wire library and copied the way it already defines its existing callback functions.

Hi @chrisl, thanks for the reply. I asked here as my last hope not to rebuild the core libraries. I expected that.
Another workaround to solve my issue could be to add the following lines in twi.c (in case TW_SR_SLA_ACK):
if (twi_sr_store_address){ twi_rxBuffer[twi_rxBufferIndex++] = TWDR >> 1; }
where twi_sr_store_address is just a boolean that can be set through Wire. This way the Wire.read() method now will return also the address byte.
Do you think this solution could work as well as yours? If not, why?
I'm just asking to learn.
Thanks again for the help,
Luca

Sure, that would also work. Though I think using a callback function is a cleaner solution. For both solutions you need to modify the library.


text:
Sharing data between M4 and M7 on a Giga R1 at high speeds
I'm working on a project to implement an attitude controller for a quadcopter. Loop times are extremely important as you can imagine.
I already have tested code for a cascading controller (inner loop does angular rate, outer does attitude) for a single-axis on a see-saw-like physical setup.
My worry was that implementing for 3-axis would slow loop times to lead to system instability. Thus, I purchased a Giga R1 which features two cores to share the load.
One way I could implement the code is to collect all sensor/RC signals on the co-processor, while the main processor does all the PID computation and generates PWM signals for the motors.
This obviously means sharing data between the two cores. I tried using the RPC method the Arduino guide suggests to share data. However, I timed how long a remote call to return an integer takes and I'm getting around 20 milliseconds. This is far too slow.
Is there a faster way to share data between the cores? I'm open to changing how the system is configured (i.e. which core does what) if that helps.


text:
ESP32 cannot serial monitor
I use esp32 devkit v1 .
I code follwing this picture.

const int vavle = 1;
int d = 1;

void setup()
{
  Serial.begin(115200);
  delay(2000);
  while (!Serial);
  Serial.println();
  pinMode(vavle,OUTPUT);
  Serial.println(d);
}

void loop()
{
  Serial.print("Open Vavle");
  digitalWrite(vavle,HIGH);
  delay(3000);
  digitalWrite(vavle,LOW);
  delay(1000);
  Serial.print("Close Vavle");
}

but serial monitor has error when use serial monitor it show me square .
I confirm select true board rate.
you can solve this problem .

first thing to remember when posting here is never post a picture of text unless absolutely necessary ... please copy your code and paste into your question ... also copy and paste the entire content of the serial monitor

Side note: You probably want to open or close a valve.

The GPIO1 pin you are trying to use with  const int vavle = 1; ... pinMode(vavle, OUTPUT); is the same pin that carries serial data to the PC.
From the pinout:

Their schematic link is broken, but if you find schematic for pretty much any similar board using this module you'll see GPIO1/U0TXD connected to a serial transceiver chip which is then connected to the USB port.
You need choose some other pin. There are pin guides and official documentation containing the same details that you can use to figure out which GPIO to use.
GPIO numbers 16 through 33 inclusive are all output-capable and seem to have no special requirements, so they make sense to choose from.

Thank you ,I can solve this problem


text:
Using I2S MEMS microphone breakout (SPH0645) as frequency detector
Good day. I would like to ask for help regarding the code for my project. I am using an I2S MEMS microphone breakout (SPH0645) to my Arduino Nano 33 IoT. Here are my pin configurations LRCL to A2 of the Arduino Nano 33 IoT, DOUT to D4, BCLK to A3. The code that I am using is:
#include <I2S.h>
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ;
  }
  if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 32)) {
    Serial.println("Failed to initialize I2S!");
    while (1); // do nothing
  }
}
void loop() {
  int sample = I2S.read();
  if (sample) {
    Serial.println(sample);
  }
}

However, I still cannot see in the serial monitor if the microphone can detect sound. Also, every time I upload this to my Arduino, I encounter this problem:

appdata/local/arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: changing start of section .bss by 8 bytes

I followed the steps here. Thank you for your help.


text:
Can I use SPI-related pins as a Digital Output?
I am trying to use an esp32 (NodeMCU-32s) as a ringlight controller for my camera. All it should do is sense when an input pin goes low (the camera's output connects to ground when the shutter goes off) which is easy to detect with a simple digitalRead(). If low, then it raises 6 pins with digitalWrite() which are connected to transistors which let current flow from a 24v power supply and light up 6 banks of white LEDs. This entire setup was working great on an esp32wroom I bought from our school's shop - like I said it is very simple - but after ordering more esp32's online, I was greeted with slightly different looking ones that don't behave the same even when running the exact same code. Yes, I have verified that the pinout is the same on these two boards, although the footprint of the online boards (best datasheet I could find linked above) is one breadboard slot thinner.
Expected behavior:
I power it on, and nothing should happen until I connect pin 14 to ground, then the lights should turn on for a tenth of a second, then back off.
Actual Behavior:
I power it on, 3 banks of lights turn on rather dimmly. The other three stay off. When I connect pin 14 to ground, the three that were off turn on for a tenth of a second, then back off. While they are on, a blue light on the nodemcu-32s dev board turns on as well...
I did some digging:
On this random nerd tutorials website I found code that identifies which pins are your board's default SPI pins and when I ran it, I found that 3 of the 6 pins I was currently using (pins 23, 19, and 5) are SPI-related ones. These were in fact the pins that behaved correctly (they were off until 14 was pulled low.)
I am not sure if this is related to the root cause of my issue or not, but it seems suspicious. Any tips from you wise arduino wizards would be appreciated - this was supposed to be simple!
Code:
Below is the code I am using. You can ignore the rgb LED stuff (LED_PIN, NUM_LEDS, BRIGHTNESS, etc.) All that matters for what I am trying to get working here are the led banks connected to pins 23, 21, 19, 5, 16, and 2. I intentionally avoided pins 6-11 because many sites were saying to avoid them.
#include <Adafruit_NeoPixel.h>

#define LED_PIN 15      // Pin connected to the Data Input of WS2812B
#define NUM_LEDS 24     // Number of WS2812B LEDs in the strip
#define BRIGHTNESS 200  // Set the brightness (0-255)

#define SHUTTER_PIN 14  //Pin connected to the shutter signal of the cameras via 3.5mm jack
Adafruit_NeoPixel strip;

void setup() {
  // setup code here, to run once:
  pinMode(23, OUTPUT); // set each bank of 6 White Leds as outputs
  pinMode(21, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(2, OUTPUT);

  // set the shutterPin as a normally-high input
  pinMode(SHUTTER_PIN, INPUT_PULLUP);

  // To control rgb leds
  strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
  strip.begin();
  strip.setBrightness(BRIGHTNESS);
  strip.show();

 // Initialize all pixels to off
  digitalWrite(23, LOW);
  digitalWrite(21, LOW);
  digitalWrite(19, LOW);
  digitalWrite(5, LOW);
  digitalWrite(16, LOW);
  digitalWrite(2, LOW);
}

void loop() {
  //main code here, to run repeatedly:
  // if the shutter signal drops, flash on and off
  if (digitalRead(SHUTTER_PIN) == 0) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(16, HIGH);
    digitalWrite(2, HIGH);
    delay(500);
    digitalWrite(23, LOW);
    digitalWrite(21, LOW);
    digitalWrite(19, LOW);
    digitalWrite(5, LOW);
    digitalWrite(16, LOW);
    digitalWrite(2, LOW);
    delay(500);
  }
}

Could you provide the code you are using and all of the pin numbers, not just the three that work? From a quick look-up, it doesn't seem like you could actually use IO14 as GPIO14 on ESP32S and you shouldn't use any GPIOs from 6 to 11, unless you really know what you are doing, as those are connected to the internal SPI flash on the chip.

I just added the code that it's running, thanks for your time! Yes, I avoided pins 6-11. Also, why wouldn't I be able to use pin 14 as an input?

I was wrong, you are able to use the pin 14 as a GPIO, reading thru this manual a bit more thoroughly.

From the schematics, I can see that IO2 is for the board's blue LED. So that's probably your first problem... From this PDF, I see that IO21 is VSPIHD, Hold for Flash chips. No good. IO16 is HS1_DATA4, also used for the Flash chip. Also no good. You'll have to pick other pins.

The other issue is SIX pins supposed to deliver 3.3 volts at the same time. On a small ESP board. Not sure that's gonna happen...

Thanks for your response dda!

Why would a pin be labeled as a GPIO if in can't be properly used as a general purpose input or output? As in, shouldn't they just be labeled as just VSPI_HD etc instead to avoid confusion?

@Zach I don't think that's an issue, most of the pins on modern MCUs have multiple functions--you decide which ones to utilize. Checking the schematics, I don't see any external quad-SPI peripherals (as dda indicates, most commonly used for flash chips). Another indicator is that it's probably not the pins (aside from GPIO2, we've conclusively established that it's linked to a blue LED...but why is the LED bank dimly lightning up during initialization?) it worked with other ESP32-Wroom modules, which are also the modules used on the NodeMCU-32S board(s).

@Zach okay, I checked on the Espressif docs and yes, pin 16 is indeed not recommended to be used as a GPIO pin (it still can be, of course, but it could lead to unknown behavior as you've experienced)--nothing about pin 21 though.

@Zach it is possible to have different functionalities on the same pin - just don't use them all at once. In the case of the VSPI pins, if there's no Flash chip, and the VSPI bus isn't inited (eg if the code checked whether there's a chip, and didn't deinit afterwards, oops), they can be used.

I'm still not quite sure what's going on, but to troubleshoot this I would do the following:

First of all, verify it's not a faulty board and try it with another one of the new ones that you've got. If that doesn't help, then do the following:

Move the digitalWrite-s up, above the NeoPixel initialization code. See if that helps with the start-up.
If that doesn't help, add pull-down resistors to the LED outputs (try 10kOhm).
The blue LED lights up because GPIO 2's output is connected to it, looking at the schematic on the website you've linked. You might want to switch this one to a different GPIO on the board you're using.
Check the transistor circuits for the LEDs that are not functioning correctly. You've not posted anything related to it, so I can't help you much there, but if you do link it we might be able to use that info.

Will do, thanks

@Zach do you have an oscilloscope on hand? At least a multi-meter? If you run the main as an empty function, do the 3 LED banks still light up, even though dimly? If you can, check the voltage from the pin to the ground. Take notes. Then, put the main loop back in and measure the voltage on the pins with LED banks that aren't lightning up. What do you see? Of course, you could try just try other pins and if they work alright, just make compilation defines for each board and that'll make it easier to recompile your program as needed.


text:
ATmega328 drop-in replacement with more flash memory
Is there a ATmega328 drop-in replacement with more flash memory?
Needs to be 28 pin DIL to fit the socket.
Alternatively, is there a board that has the exact dimensions and pins as an Arduino UNO, but with more flash memory?
Everything in my project works fine, but I need more program memory. Can unfortunately not use a different board layout or size.

What did you try to find out? Did you visit the manufacturer's web site? Did you visit Arduino's web site for other models?

Would it be possible for you to use an external flash memory? Something like the Macronix MX25R6435F.

@Cowboy_Patrick: Thanks for the suggestion, but unfortunately not.

the  wemos D1 (not mini) has an uno form factor and a bajillion times more ram. it is 3.3v though. You probably could make a custom PCB with uno layout and an ESP32s2 and integrated logic level shifters. might be a useful project for many,

@dandavis Thanks, great suggestion. I looked at the Wemos D1 a few weeks ago, and if it had 5 V logic levels, it would be the board for me. I was hoping to get away with not making a custom PCB.

Is there a ATmega328 drop-in replacement with more flash memory?

No

Alternatively, is there a board that has the exact dimensions and pins as an Arduino UNO, but with more flash memory?

Yes, but it'll be probably something with ARM (UNO R4 minima has even 5V ARM), However libraries might be an issue
As for AVRs, there are for example AVR128DA28 but as far as I know, it's definitely not pin compatible.
However you could use some proto board for UNO and wire it up somehow on it.  (128kB, 28pin).
Also Atmega644/1284 (in pdip 40) could be used on proto board and it's much more compatible

Thanks, great answer. Will probably get the UNO R4 minima.

Well then aware it doesn't have such strong output drivers (8mA tops), mentioned libraries compatibility and it's relatively new, so even bugs in arduino core are possible


text:
Configure CA to connect to server with Ethernet
I'm using Ethernet module ENC28J60 with ESP32 on Arduino IDE.
I could establish a secure connection using WifiClientSecure.h
here code
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

const char* ssid = "wifi";
const char* password = "1234567890";

const char* serverName = "https://myserver.com/v1";

const char* userName = "admin";
const char* pass = "pass";

unsigned long previous;

const char* rootCACertificate =
  "-----BEGIN CERTIFICATE-----\n"
  ...
  "-----END CERTIFICATE-----\n";

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

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print('.');
    delay(1000);
  }

  Serial.println(WiFi.localIP());

}

void loop() {
  if ((WiFi.status() == WL_CONNECTED))
  {
    WiFiClientSecure client;

    client.setCACert(rootCACertificate);
    HTTPClient https;

    Serial.print("[HTTPS] begin...\n");
    if (https.begin(client, serverName))
    {
      https.setAuthorization(userName, pass);
      https.addHeader("Content-Type", "application/json");
      ...
      https.end();

    }
  }
  else
  {
    Serial.printf("Unable to connect to wifi\n");
  }
  Serial.println();
  Serial.println("Waiting 60sec before the next round...");
  delay(60000);
}

But there is no support for Ethernet.
Could anyone suggest a way to connect to server with EthernetENC or any other Library?

if you use ethernet module supported by the esp32, you can use the code you have. https://github.com/espressif/arduino-esp32/tree/master/libraries/Ethernet/examples

@Juraj So I just need to change Ethernet Module to Ethernet Hardware TCP/IP W5500 Ethernet Network Module? How to configure CA?

you will use the same code as with WiFi. only at the low level it will go through the W5500


text:
Arduino not reacting sometimes when reading serial commands
When I am sending hex numbers via computer to the arduino leonardo, it sometimes won't react, but the serial monitor says that it was sent. My code;
    void setup()
{
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(A0, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop()
{
  delay(100); // Wait for 100 millisecond(s)
  Serial.println(Serial.read());
  if (Serial.read() == 49) {
    Serial.println("left");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 50) {
    Serial.println("right");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 51) {
    Serial.println("backwards");
    analogWrite(9, 1023);
    digitalWrite(A0, LOW);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 52) {
    Serial.println("forwards");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, HIGH);
  }
  if (Serial.read() == 48) {
    Serial.println("stop");
    analogWrite(9, 0);
    digitalWrite(A0, LOW);
    analogWrite(10, 0);
    digitalWrite(11, LOW);
  }
}

When I send the numbers 1,2,3,4, and 0, it reads what the command does. Pins A0 and D11 are direction control for the motor controller, and pins D9 and D10 are speed.

the serial monitor prints a different byte from the one that controls the motors

Serial.println(Serial.read());
if (Serial.read() == 49) {

You are doing two reads here, not one. So you are reading and displaying, and then reading a second byte (not the one you displayed).
Much better would be:
int cmd = Serial.read();
Serial.println(cmd);
if (cmd == 49)  {
  ... do something ...
} else if (cmd == 50)  {
  .. do something else ...
}

And so on.
Also, why use numbers when you can show the ASCII characters? eg.
int cmd = Serial.read();
Serial.println(cmd);
if (cmd == '1')  {
  ... do something ...
} else if (cmd == '2')  {
  .. do something else ...
}

You may also want to consider using:
if (!Serial.available())
    return;

That way you don't test for serial data that does not exist.
Why the delay?

When I made it delay, it seemed to work better.


text:
How can I switch the power on/off to cut BIG currents (200A)?
Context: I have an off-grid cabin with PV powered 12V DC. I want to cut power to an inverter (12V DC ->220V AC) when I leave by pressing a button as it draws too much in standby.
Most relays I have seen that can be connected to the Arduino typically handle 10A. My inverter draws up to 180A@12V at full power (2000 W), which is way more than anything I have seen. How can I control the power to this inverter?
Someone told me of hacks that utilize the fact that you get manual switches/relays that handle big current, so you can use the Arduino to control a motor pressing the physical switch, but the concept seems somewhat brittle ... Any other takes?

            ┌────────────┐
            │  PV array  │
            └──────┬─────┘
                   │
             ┌─────┴───┐
             │ Charger │
           ┌─┴─────────┘
           │
           │
  ┌────────┴──┐         ┌─────────┐
  │ Batteries ├─────────┤Inverter ├────────────┐
  └────────┬──┘         └─────────┘            │
           │                                   │
           │                          ┌────────┴─────┐
           │                          │220V circuit  │
       ┌───┴───────────────┐          │  w/appliances│
Has    │ Fuse box          │          └──────────────┘
on/off │ / 12v distribution│
switch!└───────────────────┘

        ┌──────────────┐
        │12V appliances│
        └──────────────┘

What is the model number of the inverter?

I do not have it readily available (it's a 4 hour drive), but it is one of the many generic China versions readily available on BangGood. Paid like 200$ for the 2KW peak/1KW continuous version.

There may be better ways to go about it involving an Arduino, but they will largely be dependent on the capabilities of the device. The typical way inverters themselves solve the cost of standby is by offering a way to probe for a load a regular intervals sometimes called "search". But there's nothing really Arduino related about that aspect of it.

The motorized manual switch idea is good because it uses (builds upon) rated components, so your insurance won't deny a claim if the cabin burns down due to electrical problems stemming from ali express junk. If you want to do it "right", use a suitably rated contactor, not a relay. Or use a manual switch; they aren't any harder to use than a button.

@dandavis Of course there exists ali express junk for this, but if you use a properly rated relay or electric switch for automotive applications, these should conform to local regulations as well. Of course, they won't be in the $5 range.

I don't know the exact physical setup, but a manual switch is probably problematic due to the location of the different components. The wires between the battery and the inverter should be as short as possible, to avoid energy loss. A cable for 180A @ 12V is  very thick. So depending on the layout, it's not possible to install a mechanical switch in a convenient place without adding a lot of extra cable length.

That's exactly it. Cable length issue, Hence the need to disable it using another remote mechanism. Also, I cannot fit search lying on the inside of my walls

@PMF good point about placement, strike my manual switch suggestion. I still worry that automotive starter relays aren't designed to handle long-term current, whereas contactors/solenoids are. I doubt the price differential is enough to justify the risk in a high-stakes situation.

@dandavis Yea, I'll clarify that in my answer. Of course it's important to read the specs regarding long-term currents. The main point actually is that there are 12 V relays or solenoids for high currents, but none (or few?) that operate on 5V directly.

@PMF sorry to be a nit, but this is a possibly life safety or mega buck problem; i want fellow makers to be safe. Might mention that many starter relays consume dozens of watts too, a consideration for solar. A latching contactor is zero rest current.

You might look for something like a "starter relay" for an engine. Those switch on 12 V and can handle currents of 150A and more. I've seen various models on the site of my favorite distributor.
Check the data sheet to make sure the relay can handle a continuous current of 180A, as many starter relays can only handle the current for short periods of time (you're not running the starter motor of an engine for more than a few seconds). Other possible types are 12V-industry-rated high-current relays. Also mentioned in a comment above: The hold-current of the relay shouldn't be to big, so you don't waste energy just for the switch.
You might need to use a 2-step solution, to first convert the 5V output of the Arduino to 12 V to control the relay. (use a small relay for this, or just a mosfet).


text:
Getting a strange symbol when pressing buttons in a USB keyboard connected to the Arduino GIGA R1
I am using the following code:
#include "USBHostGiga.h"

//REDIRECT_STDOUT_TO(Serial)
Keyboard keyb;
HostSerial ser;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial);
  pinMode(PA_15, OUTPUT);
  keyb.begin();
  ser.begin();
}

void loop() {
  if (keyb.available()) {
    auto _key = keyb.read();
    Serial.println(keyb.getAscii(_key));
  }
  while (ser.available()) {
    auto _char = ser.read();
    Serial.write(_char);
  }
  //delay(1);
}

from here: https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-usb
I am using Arduino GIGA R1 on which I have connected a USB keyboard and I press buttons. I see the results on the Serial. However, I face the following problem: When I press a button, apart of the letter I get also a square next to it. For instance, let's say I press the 'A' letter. In the serial I get 'A' letter + a square symbol. When I press 'B', I get 'B' + a square symbol, etc. I am trying for 2 days to fix it, I tried to read the button as a char array with two positions and delete the [1] where the square should be, but nothing worked. The auto type is very strange in order to make a type casting, because the Arduino IDE continuously shows me error. I cannot find a way to remove the strange 'square' ASCII character which I take with each letter pressed...The only things I noticed is that the square ASCII character is displayed the time I release the keyboard button, and also it delays to appear when I increase the delay ms in the delay(...); command. Has anyone any idea how to solve this?

does [SHIFT]+[A] look the same as [A]? what does Serial.println(_key, HEX) look like?

I don't have GIGA R1, so no practical way to test this.
I also cannot explain why it's showing up as square for you. It is common behaviour for character codes that don't have a font glyph to render in that way, but the one in question (null character) does not do that for me under the 1.x 2.x IDEs.
However, the rest of what follows may help.
According to github,
the type that is returned by .read() is HID_KEYBD_Info_TypeDef, so if you want you should be able to:
const HID_KEYBD_Info_TypeDef _key = keyb.read();

However, there's not much wrong with using auto here.  So far as I can tell, what you're really receiving
is the content of Boot mode HID reports.
Not individual key information really, but rather the state which may include up to 6 pressed keys.
If you're only pressing one key (one non-shift state key; as in not "shift", "control", "alt". etc,
it shows up in array index 0, which is what getAscii
is ultimately interpreting.
So when you release the key (all of them) you are getting a report with nothing (no key code; represented with a zero value) in keys[0], and so there's nothing there from which to get an ASCII code.
What it seems to be doing is translating the 0 value that's there into another zero.
So, it would seem all you need to do is check to see if it's a zero after the call to getAscii, e.g.:
if (keyb.available()) {
  const auto keyboard_input_report /*not really a key*/ = keyb.read();
  const auto first_as_ascii = keyb.getAscii(keyboard_input_report);
  //  where getAscii really means getAsciiCodeOfFirstkeyIfThereIsOneInTheReport
  if (first_as_ascii != 0) {
    Serial.println(first_as_ascii);
  }
}

You could to check before translation with if (keyboard_input_report.keys[0] != 0) {. However, the former may make more sense. Because not every key on the keyboard will map unto may onto an ASCII code value anyway.  E.g. ASCII does not represent the arrow keys, function keys, or page-up/page-down.
In any case, this code may have issues if multiple keys are pressed. It looks like doing so correctly would involve using the internals of getAscii to consult the translation tables for all six of the entries in the report's keys array.


text:
Setting flag for sending data through advertisements using hm-10 mlt bt05 and arduino uno
I have succesfully connected to my hm-10 device and started configuring it using AT commands. I would like to know if it is possible to modify the data sent in advertisement and read it on another hm-10 device in some way.
I am using AT commands specified here: http://denethor.wlu.ca/arduino/MLT-BT05-AT-commands-TRANSLATED.pdf
And some from here (working less consequently): https://www.rhydolabz.com/documents/37/datasheet%20HM-10.pdf
This is the device I am using: https://elextra.dk/en-gb/p/bluetooth-modul-til-arduino-ble-40-at-09-hm-10/H45653
I am using Arduino UNO R3.
I can configure the HM-10 module as a slave or master, and I can set name, and check characteristics. But I am having issues in setting a flag for the advertisement. How is it possible for me to set data that can be broadcasted to all nearby bluetooth devices (mainly other HM-10 modules). It does not need to be a lot. I think the flag is one byte, which is more than enough.
Anybody has the same problem? Is there anyway to broadcast and read data with this module without connecting?
This is my current code for sending AT commands:
/*
  Software serial multple serial test

 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.

 The circuit:
 * RX is digital pin 10 (connect to TX of other device)
 * TX is digital pin 11 (connect to RX of other device)

 Note:
 Not all pins on the Mega and Mega 2560 support change interrupts,
 so only the following can be used for RX:
 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

 Not all pins on the Leonardo and Micro support change interrupts,
 so only the following can be used for RX:
 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

 created back in the mists of time
 modified 25 May 2012
 by Tom Igoe
 based on Mikal Hart's example

 This example code is in the public domain.

 */
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

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

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}


text:
Use class object inside an ISR
I have to simulate an ADC that behaves as an I2C slave. The simulated values that the ADC shall expose are sent over serial, saved on an attribute and are requested by a master device over I2C.
A simplified solution is the following. I have a struct ADC that describes the converter:
struct ADC
{
  uint32_t register_1;
  uint32_t register_2;

  void write_register_1(uint32_t data){
    register_1 = data;
  }

  void write_register_2(uint32_t data){
    register_2 = data;
  }

  uint8_t read(){
    return register_1;
  }

  // some other methods to setup...
};

In loop(), I read the serial in order to update the ADC::register value and in the onRequest handler I eventually send the requested data by accessing ADC::register:
ADC adc{};

void setup(){
  // setup adc, Wire and Serial here
  Wire.onRequest(slaveTransmitterHandler)
}

void loop(){
  if (Serial.available() > 0)
  {
     // read serial, parse received data and check them
     uint32_t data = parse_serial(); // do anything is needed to check data...

     // update adc attribute
     uint8_t oldSREG = SREG;
     noInterrupts(); // disable interrupts to update uint32
     adc.write_register_1(data);
     SREG = oldSREG;
  }
}

void slaveTransmitterHandler(){
  Wire.beginTransmission(ADDRESS);
  Wire.write(adc.read());
  Wire.endTransmission();
}

void slaveReceiverHandler(){
  uint32_t i2c_received_data;
  while (Wire.available){
    // fill i2c_received_data with Wire.read()
  }
  adc.write_register_2(i2c_received_data);
}

I'm not sure if I have to declare the adc object as volatile (this would mean to declare all ADC methods and variables as volatile). Is it safe to use an object inside the I2C handler called by the I2C interrupt?
As far as I know, it is not (I can find no reason why it should be different from non-class variables), but I have always worked with non-class variables and never with cpp objects. Also, I can't find any information about this topic.
It could be possible that I'm wrong with the whole design, even if it seems to me to be very consistent. I'm open to change it for something better, so please if this design is nonsense, comment on that! I'm here to learn :)
Thanks.
Luca
Edit:
Some clarification, since my question seems not to be clear enough: I'm doing HIL simulation, that is simulating the real hardware with its real interfaces with a simulated environment (that includes sensors and actuators). See here for more info.
One of my sensors measures a voltage and stores it in a register of an ADC (that has multiple registers). I'm simulating the behaviour of ADC registers in Arduino, and they shall communicate via I2C with the real hardware.
Hope this is more clear now.

I don't think the class has to be volatile here.  Nothing in the ISR is changing anything about the class, so there's no chance that the ISR fires in the middle of something else accessing the class and getting corrupted data.  The only possibility for corruption here would be if the ISR fired diring the write function but you seem to have handled that with a critical section around it.  It would be different if the ISR wrote to the object, but as written it only reads from it.  I think you're ok here.

@Delta_G This looks like an answer. Please post one and not a comment. Thank you.

Why are you doing Wire.onRequest(slaveTransmitterHandler)? That looks like you really are using I2C and not simulating it.

@Delta_G thanks! Let's say that I'm also setting some attributes of the adc object in an interrupt. How can I deal with that case? I've edited the original post to include this case (see slaveReceiverHandler). Shall I declare the object (and the whole class attributes and methods) as volatile? I guess so, but it seems that it's not really clear to me what volatile means when used in a C++ class (https://en.cppreference.com/w/cpp/language/cv this page goes above my understanding).

This isn't a forum. If you want to expand on the question please edit the question. Any answers given should address the question (as edited), not the question plus random comments. Nor should the answer be in a comment (not your fault).

If this is a simulation, and not actually using interrupts, then you hardly need to declare anything volatile. However your use of the Wire library makes it look less like a simulation. Personally I think your problem is under-explained. Please post all of your code. If you are simulating you won't need to worry about hardware interrupts. If you are using the Wire library you will.
Your other post Get address of a I2C transaction when multiple addresses are registered seems to be relevant here.

He is using the Arduino to fake an I2C ADC. The I2C link is real. The ADC readings are fake.

@EdgarBonet is right. I've edited the question with some more details.


text:
How do you use two piezos at the same time?
I'm trying to replicate a short music clip with two piezos, and I want them to play at the same time. While the right piezo is playing, I want the left one to still be looping. The problem is, I'm not sure how.

//Left hand
const int leftPin = 10; /Left pin
const int leftTones[] = {123.4, 103.83, 138.59, 92.50}; //The looping left tones
const int leftDelays[] = {700, 1300, 900, 900}; //How long those tones last
const int leftNotes = 4; //How many left notes there are

//Right hand
const int rightPin = 2; //Right pin
const int rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, //The looping right tones
659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88,
554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99,
587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33,
659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99,
698.46, 1174.66, 1318.51};
const int rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, //How long those tones last
300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200,
700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300,
200, 400, 300, 200, 400, 300, 200};
const int rightNotes = 40; //How many right notes there are

void setup(){
    pinMode(leftPin, OUTPUT);
    pinMode(rightPin, OUTPUT);
    delay(1000);
}

void loop(){
  for (int i = 0; i < leftNotes; i++){
    tone(leftPin, leftTones[i]);
    delay(leftDelays[i]);
    noTone(leftPin);
  }
  for (int i = 0; i < rightNotes; i++){
    tone(rightPin, rightTones[i]);
    delay(rightDelays[i]);
    noTone(rightPin);
  }
}

With this code, the left piezo plays first, and then the right piezo plays. It should be at the same time.
Edited Code:
long currentMillis = 0;
long leftPreviousMillis = 0; // previous time for left hand
long rightPreviousMillis = 0; // previous time for right hand

const int leftNotes = 4; // The amount of left notes
const int rightNotes = 40; // The amount of right notes
int leftIndex = 0; // The specific index for the left piezo
int rightIndex = 0; // The specific index for the right piezo
const int leftPin = 10; // The left piezo
const int rightPin = 2; // The right piezo

// The specific left pitches (as float)
const float leftTones[] = {123.4, 103.83, 138.59, 92.50};
// How long the left pitches last for
const long leftDelays[] = {700, 1300, 900, 900};

// The specific right pitches (as float)
const float rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88, 554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99, 698.46, 1174.66, 1318.51};
// How long the right pitches last for
const long rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, 300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200, 700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300, 200, 400, 300, 200, 400, 300, 200};

void setup() {
  pinMode(leftPin, OUTPUT);
  pinMode(rightPin, OUTPUT);
  Serial.begin(9600);
  delay(1000);
  tone(rightPin, rightTones[rightIndex]);
  tone(leftPin, leftTones[leftIndex]);
}

void loop() {
  currentMillis = millis();
  // Left hand notes
  if (currentMillis - leftPreviousMillis >= leftDelays[leftIndex]) {
    noTone(leftPin); // Turn off the left note
    leftPreviousMillis = currentMillis;
    leftIndex++;
    if (leftIndex == leftNotes) // Reset left hand index
      leftIndex = 0;
    tone(leftPin, leftTones[leftIndex]); // Turn on the new left note
  }

  // Right hand notes
  if (currentMillis - rightPreviousMillis >= rightDelays[rightIndex]) {
    noTone(rightPin); // Turn off the right note
    rightPreviousMillis = currentMillis;
    rightIndex++;
    if (rightIndex == rightNotes) // Reset right hand index
      rightIndex = 0;
    tone(rightPin, rightTones[rightIndex]); // Turn on the new right note
  }
}

I've done some testing, and I think it's a problem with the tones function. Right now, this code only plays the right hand notes. The problem is this part:
tone(rightPin, rightTones[rightIndex]);
tone(leftPin, leftTones[leftIndex]);

When I do this:
tone(leftPin, leftTones[leftIndex]);
tone(rightPin, rightTones[rightIndex]);

Only the left hand notes are heard. But, it's not perfect. There's little beeps and buzzes every now and then. This leaves me with the conclusion that if there are two tones at the same time, it only plays the one it reads first. I've tested it with simpler code, and it stands true.
So that begs the question, is it even possible to use two piezos at the same time with one Arduino? I'm testing it with the Arduino simulator tinkercad, so maybe that's the problem? My code works for the left piezo, and the right piezo. But when you put them together, everything messes up.

Google "non blocking code" and "timing without delay".  This topic is one of the single most discussed issues about programming.  You'll find that thousands before you have had this problem.  The solution is well documented.

I've completely overwritten my previous code in my edited version right above, but I think may be a problem with the tones function itself. My reasoning is above.

Please don't change your question after you have an answer.

Tone can only be used on one pin at a time. Tone uses unsigned int for it's "frequency" parameter, not floating point numbers. This library claims it can play 2 different ones on 2 different pins: https://github.com/nathanRamaNoodles/Noodle-Synth

It's always good to look at the documentation when you have a question about how a piece of code works.  In this case I looked at the page for the tone function which can be found here.  https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
And the second sentence on that page says it all:

Only one tone can be generated at a time. If a tone is already playing
on a different pin, the call to tone() will have no effect. If the
tone is playing on the same pin, the call will set its frequency.

Ah, you where faster than me. Also: The Polytone seems promising as alternative.

How do you use two piezos at the same time?

Consider using a finite state machine type of programming method.
As has been discovered, using calls to the delay() function (where the processor does nothing) blocks any other feature of the sketch (user's program). In a finite state machine programming pattern, there are no calls to the delay() function.  Instead the sketch's loop() function is allowed to execute as fast as possible. The trick is to control what code is executed in the loop() function based on a state machine.  And, in this case, use time to change between different states.
In an Arduino platform (the hardware and software you never or seldom see that makes up an Arduino) a counter is always tracking elapsed time.  Use the millis() function to retrieve the current value in milliseconds (1000 milliseconds = 1 second) each time through the loop() function. Consider using a 2 state state machine. In the 1st state get the current counter value, add to it the delay in milliseconds of the next note, start the note playing and finally change the variable tracking states to the 2nd state. The next time through the loop() function, while in the 2nd state, check if the response from calling millis() again is larger then the value saved while in the 1st state.  If it is, stop playing the note and change the variable tracking states to the 1st state.
Once working, create a second similar state machine to play the counter melody.
However, as delta-g has pointed out, the library picked out by the O.P. apparently can not play more than one note at a time.  But,ve7jro has pointed out that this Arduino tunes library may be able to satisfy the requirement of playing 2 notes at the same time as stated in the O.P.'s question.
Creating a state machine in a invaluable programming lesson.  However, this Arduino state machine library is available should the programmer wish to take advantage of it.

I've put my newest code at the bottom of my previous response.

@Harrisino, you have accepted an answer. So don't edit your question into a different one. Only edit it to make it better. If you have a different question, start over by asking a new question. The point of stackexchange is to accumulate questions & answers for people to search through who have similar questions. Think how confusing the altered question will be to those people. BTW, you accepted an answer that says you can not do what your question asked for. I still think a state machine is what you want. And perhaps a better tunes library.


text:
is #ifdef __SD_H__ considered a bad practice?
Say I'm working on a library^1 to which I want to add support for SD.h^2 but knowing for a fact that many microcotrollers don't support SD.h (therefore they result in compilation errors [eg. Attiny85]) I don't want to just #include <SD.h> (or even #ifndef __SD_H__ then #include <SD.h>) in Mylibrary.h and make it totally unusable for some microcontrollers. So I was wondering, is it considered ok to just add the functionality like...
// Mylibrary.h

#ifdef __SD_H__
    // Save functionality for those including `SD.h` to their `sketch.ino`
    void Mylibrary::save(String filename){
        SD.open(filename, FILE_WRITE)
        // ...
    }
#endif

...without ever including the SD.h in Mylibrary.h and hence force the user whenever he\she wants to use some SD functionallity, to just include SD.h in his\her sketch.ino?  +(it sound exhausting to do something like this for every MCU, as an alternative way)
[1] (in my case this library)[2] (in my case  something related to this)PS. The reason I'm asking is because I don't remember seeing it anywhere being used that way and I'm slightly confused as to if this is the right or wrong thing to do so

Chat-GPT says it's reasonable, but I really want to know your thoughts about how would you approach such an issue

Do not trust ChatGPT, always assume it is hallucinating.

It is bad and I have seen it :)

Note that identifiers that start with two underscores (or one underscore and a capital letter) are reserved: "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use."

Since you asked ChatGPT, I asked it as well: "in C++ is it good practice to put all of your code in a .h file?" And the answer was: "No, it is not considered good practice to put all of your code in a .h (header) file in C++. In C++, code is typically organized into header files and source files, and there are specific conventions for what should go in each type of file."  So no, putting all your code (declarations and definitions, that is, function prototypes and implementations) is not considered good practice. You can search other parts of the Internet for other opinions on that.

@NickGammon, When I started building this library, there wasn't ChatGPT available. Based on my research (and sure also empirically) that's what I found out that it was working. Also, I once had them seperate I later decided that I had to merge them into the .h for the sake of better MACRO optimization

Yes, it is in general a bad practice to use include guard define to detect if the header file is included. It will work only in a header file in a compilation unit which includes the detected header file.
In Arduino all ino files of the sketch are one compilation unit. But every C or C++ file is a separate compilations unit. They would not 'see' the include guard from an include in the ino file(s).
If you want to use the include guard define, don't relay on it exclusively. Use your own define and set it if you detect the include guard. This way user can set it if theirs SD library has a different name for the include guard.
#ifdef __SD_H__
#define XY_USE_SD_LIB
#endif

#ifdef XY_USE_SD_LIB
    // Save functionality for those including `SD.h` to their `sketch.ino`
    void Mylibrary::save(String filename){
        SD.open(filename, FILE_WRITE)
        // ...
    }
#endif

I use this in my popular ArduinoOTA library here.
There is other way to detect includes and it works across compilation units, but it doesn't work on all Arduino platforms. It is the __has_include 'directive'. I use it here.

That's so cool! clever one! It's exactly what i was looking for! Thanks!

you are fast :-). please read the last paragraph for an alternative

That's so interesting I didn't know about __has_include

I don't think this will work, however you could try it and see. Just set the board type to something that doesn't support SD.h.
My problem would be that your library is a separate compilation unit (ie. file) that would be compiled against the things you put as header files.
If your library user uses SD.h in the main .ino file, then your library (which is compiled separately) would not know about that. In other words, it wouldn't know whether or not to implement the Mylibrary::save function.
I think a fairly simple solution would be to put a define in the include file for your library, eg.
#define USE_FILE_SAVING false

Then check that in your code. You don't need a whole list of MCUs, just inform the user that if they want file saving implemented to change that one line.

For more information see How the IDE organizes things

Thanks! it's really interesting though, I also just realised that it depened if it works or not based on which board i select (eg. on arduino uno works, with espressif's ESP32 it doesn't consider that SD.h is already defined)

Wait It's so weird, it copiles just fine on both boards but with ESP32 the #ifdef __SD_H__ #pragma message("YES SD.h") #else #pragma message("NO SD.h") #endif  says "No ..."

Adding SD.h to your main project is not  going to affect how your library compiles. That is a separate compilation unit and does not look at what includes you have in your .ino file. See: https://arduino.stackexchange.com/a/13182/10794

It actually does effect in some cases (eg. with Arduino UNO)

@GiorgosXou This isn't a library, though, right? Of course it affects a compilation unit. You are showing in that GIF that putting the include inside a file in a compilation unit (that is, the file we are looking at) will of course affect how that file is compiled. But if you put that include in file A it won't affect  how file B (your library) is compiled.

Your library is compiled separately (in another compilation) from your .INO file. The library cannot know what includes you may or may not have put in your .INO file.

My whole library is in the .h file. There are no seperate cpp files, I just organise each class implementation with #pragma region file.cpp inside the .h (for the exact reason of extreme macro optimization)

"The library cannot know what includes you may or may not have put in your .INO file." in many cases like #ifdef __SD_H__ it knows, in other cases like @juraj said you have to use __has_include like #if defined __has_include #if __has_include(<SD.h>) #include <SD.h> .... But from what I understand, you shouldn't 100% only depend on those

OK, so the whole library is in a .h file? Then rather than asking whether it will work or not (which you can find out for yourself empirically) how about telling us whether or not it works, and if not, ask us why not?

I thought I made it clear, I even had a comment // Mylibrary.h on my code snippet. I didn't ask "whether it will work or not", I asked  "how would you approach such an issue" because empirically, I know I make mistakes...


text:
Compilation error: 'Serial' does not name a type
#include <IRremote.h>

IRrecv IR (11);

Serial.begin(9600);

void setup() {
  // put your setup code here, to run once:
  IR.enableIRIn();
}

void loop() {
  // put your main code here, to run repeatedly:
  if (IR.decode()){
    Serial.println(IR.decodedIRData.decodedRawData, HEX);
    delay(1500);
    IR.resume();
  }
}

In C & C++, executable statements must be within a function. Your third statement, Serial.begin(9600); is (or should be) executable but since it is outside any function, the compiler tried to interpret it as a declaration - thus, the error.


text:
Just one more pin!
I have an Arduino project to control a motor's speed at 3 levels, indicated by 3 LEDs, so level 1 is speed 1 and LED 1, and so on for levels 2/3.
Also, I added a low-battery voltage indicator to monitor the battery level.
I am going to use an ATtiny45, which has 8 pins(Vcc, GND, 1 analog pin, 5 digital pins). The project needs 6 digital pins and 1 analog pin, so only one more pin is needed.
I do not want to use an expander or I2C, as they will make the project more complex, and it is only one pin!
I can use a larger microcontroller but it would be the last choice.
Here is my project's diagram and code:

//********************************************^************************************************
//  https://forum.arduino.cc/t/control-motor-speed-with-npn-and-push-button-no-driver/1184925
//
//
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ====================================================================
//  1.00       20/23/02    Running code
//  1.10       20/23/03    Added motor and LEDs OFF if switch pressed for >= 3 sec.
//
//
//

#define PRESSED            HIGH
#define RELEASED           LOW

#define ENABLED            true
#define DISABLED           false

#define LEDon              HIGH
#define LEDoff             LOW

#define MOTORoff           0

#define lipo               A0

float lipoV = 0;

//GPIOs
const byte Button        = 2;
const byte ledpin        = 3;
const byte ledpin1       = 4;
const byte ledpin2       = 5;
const byte Motor         = 9;
const byte heartbeatLED  = 13;
const byte Red           = 6;

//Variables
byte lastButton          = RELEASED;
byte currSwitch;

int Speed_Level;

bool bCheckingSwitch     = DISABLED;

//timing stuff
unsigned long heartbeatTime;
unsigned long switchesTime;
unsigned long threeSecondTime;

//                                      s e t u p ( )
//********************************************^************************************************
void setup()
{
  pinMode(Button, INPUT);
  pinMode(lipo, INPUT);

  pinMode(ledpin, OUTPUT);
  pinMode(ledpin1, OUTPUT);
  pinMode(ledpin2, OUTPUT);
  pinMode(Motor, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);
  pinMode(Red, OUTPUT);

} //END of   setup()

//                                       l o o p ( )
//********************************************^************************************************
void loop()
{

  //************************************************              T I M E R  heartbeatLED

  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {

    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    if (digitalRead(heartbeatLED) == HIGH) digitalWrite(heartbeatLED, LOW);
    else digitalWrite(heartbeatLED, HIGH);
  }

  //************************************************              T I M E R  check switches
  //is it time to check our switches ?
  if (millis() - switchesTime >= 50ul)
  {
    //restart this TIMER
    switchesTime = millis();

    checkSwitches();
  }

  //************************************************              T I M E R  three seconds
  //if enabled, is it time to turn things OFF ?
  if (bCheckingSwitch == ENABLED && millis() - threeSecondTime >= 2000ul)
  {
    //we are finished with this TIMER
    bCheckingSwitch = DISABLED;

    //restart the sequence
    Speed_Level = -1;

    analogWrite(Motor, MOTORoff);
    digitalWrite(ledpin, LEDoff);
    digitalWrite(ledpin1, LEDoff);
    digitalWrite(ledpin2, LEDoff);
    digitalWrite(Red, LEDoff);
  }

} //END of   loop()

//                               c h e c k S w i t c h e s ( )
//********************************************^************************************************
void checkSwitches()
{
  byte state;

  //************************************************              Button
  state = digitalRead(Button);

  //has there been a state change in the switch ?
  if (lastButton != state)
  {
    //update to the new state
    lastButton = state;

    //*******************************
    if (state == PRESSED)
    {
      //enable the TIMER
      bCheckingSwitch = ENABLED;

      //start the TIMER
      threeSecondTime = millis();
    }

    //*******************
    //the switch was released
    else
    {
      //disable the TIMER
      bCheckingSwitch = DISABLED;

      Speed_Level++;
      lipoV = analogRead(lipo);

      //battery checker
      if(lipoV < 680){
        digitalWrite(Red,LEDon);
      }

       else
       {
        digitalWrite(Red,LEDoff);

       }

      //don't go over 3
      if (Speed_Level >= 4)
      {
        Speed_Level = 0;
      }

      //*******************
      if (Speed_Level == 1)
      {
        analogWrite(Motor, 50);
        digitalWrite(ledpin, LEDon);
        digitalWrite(ledpin1, LEDoff);
        digitalWrite(ledpin2, LEDoff);
      }

      //*******************
      else if (Speed_Level == 2)
      {
        analogWrite(Motor, 75);
        digitalWrite(ledpin, LEDoff);
        digitalWrite(ledpin1, LEDon);
        digitalWrite(ledpin2, LEDoff);
      }

      //*******************
      else if (Speed_Level == 3)
      {
        analogWrite(Motor, 100);
        digitalWrite(ledpin, LEDoff);
        digitalWrite(ledpin1, LEDoff);
        digitalWrite(ledpin2, LEDon);
      }

      //*******************
      else
      {
        analogWrite(Motor, MOTORoff);
        digitalWrite(ledpin, LEDoff);
        digitalWrite(ledpin1, LEDoff);
        digitalWrite(ledpin2, LEDoff);
        digitalWrite(Red,LEDoff);
      }

  }

}
}//END of   checkSwitches()

//********************************************^************************************************

Can I use tA0 as input and output at the same time like this?

Or can I reduce the LED pins, meaning use 1 pins for 2 LEDs?

You can combine your button and an LED by switching it in loop between input, reading it, then back to output. As long as you do that 50+ times a second the LED will look normal, and the button will block out the LED, providing visual feedback as a bonus.

@dandavis can you please give an example

Actually, thinking about it more, I would just replace your 3 status LEDs with neopixels, and drive all three+ from one pin. To combine, you take a 1k from 5v to the LED then ground. Button is parallel to the LED. LED on and off is just digitalWrite(x,1),  to read button pinMode(x, INPUT);st=digitalRead(x);pinMode(x, OUTPUT); to switch back to LED viewing.

This will be much complex in coding i think

the adafruit neopixel library or fastLED is pretty easy to use, and lets you change colors and brightness easily, which makes for a snazzier project. The other option does add code complexity, but that's what you need when straightforward hardware runs out.

@dandavis sorry did not catch you, i think my code and led setup have exactly what you are saying, leds are connect 1k to 5v then gnd as in my diagram and the code you said is in my sketch code!

To measure the battery, you need a second resistor from A0 to ground, or you'll still have 9V on the A0 pin, potentially damaging your arduino.

@Tito explore this https://wokwi.com/projects/361190433680191489

As a (slightly hacky and binary :) ) suggestion, you could use just two LEDs and free up a pin with the following...
Level 1 - LED 1 on, LED 2 off
Level 2 - LED 1 off, LED 2 on
Level 3 - LED 1 on, LED 2 on
This is a really simple change to your current set up and code
Alternatively (as suggested by @dandavis) use a set of 3 neopixels and drive from just 1 pin

simple and easy, that what i wanted

You may try charlieplexing your LEDs. Using only 3 digital pins
you can drive up to 6 LEDs. A web search for “charlieplexing
Arduino” should get you started.