text:
interface pcf7991at to arduino
I wanted to try to interface the pcf7991at with arduino, I assembled the pcb containing the pcf7991at following the diagram shown in the datasheet.
I saw that a frequency of 125khz must go on the CLK pin of the pcf, so I ask you if it is possible to use an internal arduino timer to try to see if the pcf7991at works.

are you asking if the Arduino is able to output 125 kHz signal at one of its pins? ... what diagram are you talking about?

The communication between MCU (Arduino) and IC (PCF7991AT) can work at any frequency (like SPI or I2C). The 125khz antenna frequency is generated in the IC internally. But you need to set the divider of the clock source (your crystal hooked up to the IC)
https://datasheet.lcsc.com/lcsc/2208260930_NXP-Semicon-PCF7991AT-1081-M_C5143533.pdf
See
page 7 -> 8.4 short explanation
page 13 -> to set the register
Hope this helps!

The Arduino is indeed capable of generating a 125kHz signal.
This example generates a 125kHz signal (50% duty cycle) on digital pin 3 of an Arduino Uno/Nano using Timer 2.
const int pulsePin = 3;  // note OC2B Pin D3 ! ! !
volatile uint32_t pulseCount = 0;

void setup(){

  pinMode(pulsePin, OUTPUT);

  cli() ;
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  OCR2A = 127 ; // f =  125kHz @16MHz clock
  OCR2B = (float) OCR2A * 0.5 ;
  TCCR2A |= (1 << WGM21) | (1 << WGM20) | (1 << COM2B1 ) ; // Mode 7 (fast PWM )
  TCCR2B |= (1 << CS20) | (1 << WGM22) ;   // ps /1  mode 7
  sei() ;
}

void loop() {
}

and how i check rising of the timer?, i need to read a particular register to see if timer is rised and eventually set to 0 after?


text:
Arduino IDE Auto Format Error
Whenever I try to format a sketch in the IDE (1.8.19) I get this output in the terminal:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: 'java.lang.String cc.arduino.packages.formatter.AStyleInterface.AStyleMain(java.lang.String, java.lang.String)'
          at cc.arduino.packages.formatter.AStyleInterface.AStyleMain(Native Method)
          at cc.arduino.packages.formatter.AStyle.run(AStyle.java:80)
          at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
          at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
          at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
          at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
          at java.base/java.security.AccessController.doPrivileged(Native Method)
          at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
          at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
          at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
          at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
          at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
          at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
          at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
          at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

...And formatting fails.
I can use astyle from the command line (linux mint) and it works well.
Guessing that some basic package was missing, or corrupted, I reinstalled Arduino, but the issue remained.
I don't precisely recall any specific changes made to my system prior to encountering this behavior, as it's been like this for at least 8 or 9 months now. I hadn't used Arduino for some time up until that point and it may have been a fresh instal.
Since I just started a new project for a buddy of mine and encountered the bug again I decided maybe it was time to see about a better solution.
Any help troubleshooting this would be greatly appreciated.

https://github.com/arduino/Arduino/issues/11728 might be similar (from package manager it didn't work, downloaded from arduino.cc worked)

Thanks. Yes, the version from https://www.arduino.cc/en/software does work.

I googled the first line of stack trace and found similar issue on github (but for SUSE linux). In this issue the Arduino IDE was installed by system package manager and after downloading latest package from arduino.cc/en/software it started working.
In general Arduino IDE linux packages are somehow problematic (as far as I know Ubuntu has still version around 1.0.6) and it's better to use latest version directly from arduino.cc

I'm not sure that it's a version issue, maybe something in the dependencies... I installed from the Ubuntu Jammy package, and got Arduino 1.8.19, which yielded the error in the original post, on multiple installations. Then I installed that same version from the Arduino site and it worked fine.

source: Stack Exchange

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

sort: votes


text:
SIM7600 MQTT CONNECTION TO shiftr.io broker
I am trying to use SIM7600 MQTT command to publish and subscribe to shiftr.io broker.
I have not been able to get pass stage of connecting to broker.
I use this
AT+CMQTTCONNECT=0,"tcp://instance.cloud.io:1883",90,1,"username","token"
I get this error code.
+CMQTTCONNECT:  0, 25
Of which code 25 indicate DNS error

I doubt that username is actually a valid user name ... same with token

You answered your own question with "DNS error".
The domain name that you're using, instance.cloud.io, is currently not valid. You can verify this quite simply by searching the web for any web site that looks up domain names for you and searching for that domain name.
In this case, "instance" is most likely a placeholder for the correct name. You need to go back to whatever tutorial or instructions you were following for this and use the correct name for this to work.

The "instance " is the name i gave. I used the same pattern to pub/sub using SIM800L. But not witj SIM7600. So i am sure the issue is with understanding MQTT stack in SIM7600.

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


text:
attachInterrupt has no effect on Industruino SAMD21
I'm using Industruino D21G (SAMD21G version) with Visual Studio Code extension for Arduino. attachInterrupt seems to have no effect. I tried Industruino CH1, CH6 and CH7 with the same result. When I poll these channels in a loop, I detect signal level change as expected. Here is the code:
#include <Arduino.h>
#include <Indio.h>

constexpr int PROXIMITY_SENSOR_NC = 6;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Indio.digitalMode(PROXIMITY_SENSOR_NC, INPUT);
  attachInterrupt(digitalPinToInterrupt(PROXIMITY_SENSOR_NC), blink, FALLING);
  digitalWrite(LED_BUILTIN, HIGH);
}

void blink() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void loop() {
}

Any ideas what could be wrong?

Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed.

Industrial level I/O on Industruino, which includes CH1, CH6 and CH7 I tried, is not connected directly to the microcontroller. It uses a buffer and communicates through I2C in pull mode. That's why interrupt on I/O change has no effect.


text:
fatal error: avr/io.h: No such file or directory (on Windows 11)
So I'm using arduino 1.8.18 installed on zip file. I am using the HardWire library. The project is the STM32 quadcopter by joop brokking. http://www.brokking.net/ymfc-32_downloads.html
complete error -
Arduino: 1.8.18 (Windows 10), Board: "Generic STM32F103C series, STM32F103C8 (20k RAM. 64k Flash), Serial, 72Mhz (Normal), Smallest (default)"

C:\Users\ishaa\Documents\Arduino\libraries\HardWire\src\utility\twi.c:26:20: fatal error: avr/io.h: No such file or directory

Multiple libraries were found for "Wire.h"

 #include <avr/io.h>

 Used: C:\Users\ishaa\Desktop\arduino-1.8.18\hardware\Arduino_STM32-master\STM32F1\libraries\Wire
                    ^
 Not used: C:\Users\ishaa\Desktop\arduino-1.8.18\hardware\Arduino_STM32-master\STM32F1\libraries\WireSlave

compilation terminated.

exit status 1

Error compiling for board Generic STM32F103C series.

As you can see I'm using the stm32 lib by roger clark. The ide is unable to detect any of the avr/.h files. I tried replacing the path in twi.c, but then the other avr files start giving errors.
Why is this happening?

For this arduino ide you can add  portable  directory (arduino-1.8.18\portable) and add only cores/libraries you want to use for STM32. Or just delete all colliding libraries


text:
Connect ESP32 cam to the Nodemcu motor shield
Is it possible to connect ESP32 cam to the Nodemcu motor shield? I already have a ESP8266 chip connected to the Nodemcu motor shield.
In get this error after connecting this ESP32 cam to the Nodemcu motor shield like this
VCC: Connect to 5V on the NodeMCU motor shield
GND: Connect to GND on the NodeMCU motor shield
UnR: Connect to TX on the NodeMCU motor shield
U0T: Connect to RX on the NodeMCU motor shield

A fatal esptool.py error occurred: Failed to connect to ESP8266: Timed out waiting for packet header


text:
How can when the button is clicked to display its name
I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. How can when the button is clicked to display its name. I have PIC12F615 microcontroller with this code: code and 5 buttons connected to him and I need recognise which button pressed. I have some code but it gives different hex codes if I pressed the same button.
byte IRpin = 2;

volatile boolean remote = false;
volatile unsigned long irCode = 0;

void remoting ()
{
  if ( remote )
  {
    remote = false;
    unsigned long T;
    for ( byte n = 0; n < 32; n ++ )
    {
      do
      {
        T = pulseIn ( IRpin, HIGH, 2200 );
      }
      while ( T < 64 );
      bitWrite ( irCode, n, T > 1120 );
    }
  }
}

void setup ()
{
  Serial.begin ( 9600 );
  Serial.println ( "\n\tReady for keyboard reading!\n" );
  pinMode ( IRpin, INPUT_PULLUP );
  attachInterrupt ( digitalPinToInterrupt ( IRpin ), remoting, FALLING );
}

void loop ()
{
  if (irCode)
  {
    Serial.println (irCode, HEX);
    irCode = 0;
  }
  delay (40);
  remote = true;
}

Schema:

the remote control may be outputting changing code

and how can I make it so that when the button is clicked to display its name

please do not ask question in a comment ... edit your post and add your question

Do you have a PIC12F615 as in your question, or a Uno as in the tags and the schematic?

You appear to be using pulseIn() in an interrupt service routine against the same pin which is used to initiate the interrupt. This is certainly odd. pulseIn() may be unreliable in an ISR and you should anyway not block an ISR.
It is certainly a novel solution to attempt to interpret what appears to be NEC IR protocol generated by that PIC.

Is either the Arduino or the PIC (or both) running on a simulator?

Both run on the simulator

Is that simulator working in real time? If not, is there any way of checking that all simulated objects are running in the same time domain, say by trying (fast) serial communications between them ?

I work in Proteus

Proteus has a logic analyser. Connect that to pin 5 of PIC and, at the same  time, pin 2 of the Arduino.  Add sample traces  and the corresponding arduino serial console output to your original question. This should help clarify if this is a PIC, Proteus or Arduino issue.

I used an oscilloscope link, yellow pin 5, blue pin 2

The function pulseIn() has this comment in the source code: "This function performs better with short pulses in noInterrupt() context" see: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_pulse.c. It is not clear if your code violates the "short pulse" rule, however, blocking an Interrupt Service Routine (in your case, the external interrupt call back routine remoting() ) for the entire length of an IR data stream is certain to cause other problems, for example, with the millis() timer.
This is in the style of your code but avoids using interrupts. It has been tested against an NEC remote control and gives repeatable results. Your code fails the same test.
byte IRpin = 2;

unsigned long irCode = 0;

void setup ()
{
  Serial.begin ( 9600 );
  Serial.println ( "\n\tReady for keyboard reading!\n" );
  pinMode ( IRpin, INPUT_PULLUP );
}

void loop () {
  while ( digitalRead ( IRpin ) );  // wait until start of first pulse
  unsigned long T;
  uint8_t validPulses = 0 ;
  for ( byte n = 0; n < 36 ; n ++ ) // enough to drop long header
  {
    T = pulseIn ( IRpin, HIGH , 12000 );  // 12ms timeout
    if ( T < 4000 && T > 400 && validPulses < 32 ) {
      // valid pulse
      bitWrite ( irCode, validPulses++, T > 1120 );
    }
  }
  if (irCode > 0 ) Serial.println (irCode, HEX);
  else Serial.println ("no code");
  irCode = 0 ;
}

is it possible to do this through the interrupt on the pin or timer interrupt?

@GoodYork Indeed there are and the one I would recommend in your case is to use the input capture mode of Timer 1. That would be non blocking, if done carefully. Does this exercise come with any other constraints such as which pin to use or that the use of pulseIn() is mandatory ? If so, add these all in to your original question. Anyway, with what you have got, you should be able to verify if the PIC is working.

Task: When writing a program, it is NOT allowed to use libraries for working with IR remotes/receivers. The signal from the receiver should be processed using an external interrupt. Your code works, here i have a code  that works through timer 1 but it doesn't work


text:
It is required to turn on the LED if the distance to the object is less than or equal to 200 centimeters. Find the error in the code
int trigPin = 10;

const int echoPin = 8;

int led = 7;

const int distance = 200;

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(led, OUTPUT);
}
void loop()
{
    int duration, cm;
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    cm = duration/58;
    if (cm < distance)
    {
        digitalWrite(led, HIGH);
    }
    else
    {
        digitalWrite(led, LOW);
    }
    delay(100);
}

What exactly is your problem with the code? Or is that a  school excercise?

I can't find the error in the code myself.

How do you know, that there is an error. Give us a description of your problem

Tested via https://www.tinkercad.com. Does not work correctly, did not complete the task.

In the image trigger is connected to pin 9, your code says pin 10. Does it solve your problem if you use the correct pin?

please describe the problem ... what does it do? ... Does not work correctly is a useless description of a problem

Does not work correctly - OK you've said what it doesn't do. What does it do? Does the LED light up or not?

You have trigPin as pin 10, however your wiring diagram shows it connected to pin 9, so that won't work.

pulseIn returns an unsigned long (microseconds) - see pulseIn. You are collecting the results in an int which has a maximum value of 32767. The value may be overflowing and thus not be correct.


text:
Arduino Readings Update Correctly on Windows but not Linux
I have written a simple script to get angle measurements from a magnetic sensor. The script works very well on Windows. However, when compiling the script on a Linux VirtualBox (Ubuntu 20.04), the sensor repeats the first angle reading and does not change from this, despite the angle changing. There are no errors/warnings given by Windows or Linux at any stage of compiling/uploading.
Uploading the script on Windows and then viewing in Linux serial monitor works. However, uploading it on Linux and then viewing in Windows serial monitor does not work ("Board is not available"), even when connecting the board to Linux and not Windows.
I've compared both systems and everything seems to be the same: the same Arduino Uno R3 board, Arduino IDE 1.8.19 on both systems, Arduino AVR Boards 1.8.3 on both, "Arduino Uno" selected as the board on both, the library is SimpleFOC v2.2.0 on both. The only difference I can see is that the Windows port is COM3, whereas the Linux port is /dev/ttyACM0.
My script is the following and I would appreciate any help or advice to get this working on Linux. Thank you.
#include <SimpleFOC.h>

#define PI 3.1415926535897932384626433832795

// Magnetic sensor instance
MagneticSensorSPI AS5x4x = MagneticSensorSPI(8, 14, 0x3FFF);

void setup() {
  // initialize magnetic sensor hardware
  AS5x4x.init();

  // use monitoring with serial
  Serial.begin(9600);

  Serial.println("Ready.");
  _delay(1000);
}

void loop() {
  Serial.println(AS5x4x.getAngle()); // display angle
}

Compile/upload under linux and then move the board to the windows system and open the serial monitor. And vice versa. Let us know if the behaviour follows from the system that it was compiled/uploaded from or the system that it is attached to. If it follows the system it was built/uploaded from, maybe provide version numbers to everything IDE, libraries, board core, etc.

Windows upload + Linux serial monitor works. Linux upload + Windows serial monitor does not work ("Board is not available"). Using Arduino 1.8.19 on both Windows and Ubuntu; Arduino Uno R3 board. Thanks for any further help/suggestions.

The "everything IDE, libraries, board core, etc"  Realistically, you liable to be the only person that can definitively answer this question. Whether or not you should is a different question. In either case, the information needed to answer it should be in the question when it it is answered. You're almost certainly going to find a difference in what you have installed.  But simply pointing that out alone is not a useful answer. The "board core" I mentioned is the version that lists in your Boards Manager for whatever board you're using.

Ok, I've compared both systems but everything seems to be the same... Arduino IDE 1.8.19 on both systems, Arduino AVR Boards 1.8.3 on both, the library is SimpleFOC v2.2.0 on both. Let me know if you've any other suggestions, thanks again for help.

Please compare the selected Arduino board, too. Did the compile and upload work without error on Linux? Did Linux upload and Linux serial monitor work, before you connect the Arduino to Windows? Please add these important information to your question by [edit]ing it, do not post a comment. I suggest to take the [tour] to learn how this site works. It is not a forum.

Ok, I've edited and updated the original question with these details. Would appreciate any help or suggestions you can provide.

It turns out that the Arduino Library Manager was giving me incorrect information about the library version installed. By removing the library it was using and then installing the correct library that corresponds to the required version number, the code now works well.


text:
FreeRTOS is not solving my problem to run tasks parallelly
I'm pretty new to esp32 and I'm trying to combine two codes in one, they are simple codes from projects that I found online, the first one uses PIR sensor to send message to telegram each time motion is detected, second code uses RFID to open door lock. When I tried directly merging the two codes together the esp32 went crazy on serial monitor and nothing worked even the WIFI failed to connect.
Then I tried creating task for each one using freeRTOS and I did it like this:
task1: for Wifi connection running on CORE 0 //wifi function is taken from sketch 1
task2: for RFID and door lock running on CORE 1 //taken from sketch 2
task3: for motion detection and sending telegram message running on CORE 0 //taken from sketch 1
Again esp32 went crazy when I opened serial monitor and it gave me this error:" Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled. "
I have no clue why is this happening, does it really require RTOS to combine the two sketches and run them at the same time, or a simple delays and if statements would solve the problem? I need some help please.
Sketch 1: Motion detection from enter link description here
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/telegram-esp32-motion-detection-arduino/

  Project created using Brian Lough's Universal Telegram Bot Library: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
*/

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Initialize Telegram BOT
#define BOTtoken "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  // your Bot Token (Get from Botfather)

// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "XXXXXXXXXX"

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

const int motionSensor = 27; // PIR Motion Sensor
bool motionDetected = false;

// Indicates when motion is detected
void IRAM_ATTR detectsMovement() {
  //Serial.println("MOTION DETECTED!!!");
  motionDetected = true;
}

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

  // PIR Motion Sensor mode INPUT_PULLUP
  pinMode(motionSensor, INPUT_PULLUP);
  // Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
  attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org

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

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

  bot.sendMessage(CHAT_ID, "Bot started up", "");
}

void loop() {
  if(motionDetected){
    bot.sendMessage(CHAT_ID, "Motion detected!!", "");
    Serial.println("Motion Detected");
    motionDetected = false;
  }
}

Sketch 2: RFID door lock from enter link description here
/*
 * This ESP32 code is created by esp32io.com
 *
 * This ESP32 code is released in the public domain
 *
 * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-rfid-nfc-door-lock-system
 */

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN    5  // ESP32 pin GIOP5
#define RST_PIN   27 // ESP32 pin GIOP27
#define RELAY_PIN 22 // ESP32 pin GIOP22 connects to relay

MFRC522 rfid(SS_PIN, RST_PIN);

byte keyTagUID[4] = {0xFF, 0xFF, 0xFF, 0xFF};

void setup() {
  Serial.begin(9600);
  SPI.begin(); // init SPI bus
  rfid.PCD_Init(); // init MFRC522
  pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output.
  digitalWrite(RELAY_PIN, HIGH); // lock the door

  Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader");
}

void loop() {
  if (rfid.PICC_IsNewCardPresent()) { // new tag is available
    if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
      MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

      if (rfid.uid.uidByte[0] == keyTagUID[0] &&
          rfid.uid.uidByte[1] == keyTagUID[1] &&
          rfid.uid.uidByte[2] == keyTagUID[2] &&
          rfid.uid.uidByte[3] == keyTagUID[3] ) {
        Serial.println("Access is granted");
        digitalWrite(RELAY_PIN, LOW);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, HIGH); // lock the door
      }
      else
      {
        Serial.print("Access denied, UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();
      }

      rfid.PICC_HaltA(); // halt PICC
      rfid.PCD_StopCrypto1(); // stop encryption on PCD
    }
  }
}

No, you don't need an RTOS to do something simple like:
if (motionDetected)
    open_the_door ();

You basically have two loops:
void loop ()
  {
  if (motionDetected)
      send_a_message_to_open_the_door ();
  }

And:
void loop ()
  {
  if (message_received_to_open_the_door)
     open_the_door();
  }

So, you combine them into a single loop:
void loop ()
  {
  if (motionDetected)
     open_the_door();
  }

I'll leave you to make the actual code changes.


text:
Why NEC IR remote control decoder does not work
I need to recognize a signal from an IR remote, not to use a library for working with IR remotes/receivers. How can when the button is clicked to display its name. I have PIC12F615 microcontroller with this code: code and 5 buttons connected to him and I need recognise which button pressed. Why NEC IR remote control decoder does not work, it doesn't set nec_ok to true.If output nec_state to the terminal, I get 0 1 0 1 0 1 and so on.
    boolean nec_ok = 0;
byte i, nec_state = 0, command, inv_command;
unsigned int address;
unsigned long nec_code;

void setup() {
Serial.begin(9600);
// Timer1 module configuration
TCCR1A = 0;
TCCR1B = 0; // Disable Timer1 module
TCNT1 = 0; // Set Timer1 preload value to 0 (reset)
TIMSK1 = 1; // enable Timer1 overflow interrupt
attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
}

void remote_read() {
unsigned int timer_value;
if(nec_state != 0){
timer_value = TCNT1; // Store Timer1 value
TCNT1 = 0; // Reset Timer1
}
switch(nec_state){
case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse)
TCNT1 = 0; // Reset Timer1
TCCR1B = 2; // Enable Timer1 module with 1/8 prescaler ( 2 ticks every 1 us)
nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space)
i = 0;
return;
case 1 : // End of 9ms pulse
if((timer_value > 19000) || (timer_value < 17000)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse)
return;
case 2 : // End of 4.5ms space
if((timer_value > 10000) || (timer_value < 8000)){
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
return;
case 3 : // End of 562µs pulse
if((timer_value > 1400) || (timer_value < 800)){ // Invalid interval ==> stop decoding and reset
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
}
else
nec_state = 4; // Next state: end of 562µs or 1687µs space
return;
case 4 : // End of 562µs or 1687µs space
if((timer_value > 3600) || (timer_value < 800)){ // Time interval invalid ==> stop decoding
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
return;
}
if( timer_value > 2000) // If space width > 1ms (short space)
bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i)
else // If space width < 1ms (long space)
bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
i++;
if(i > 31){ // If all bits are received
nec_ok = 1; // Decoding process OK
detachInterrupt(0); // Disable external interrupt (INT0)
return;
}
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
}
}

ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR)
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}

void loop() {
Serial.println(nec_ok);
if(nec_ok){ // If the mcu receives NEC message with successful
nec_ok = 0; // Reset decoding process
nec_state = 0;
TCCR1B = 0; // Disable Timer1 module
address = nec_code >> 16;
command = nec_code >> 8;
inv_command = nec_code;

attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
}
}

Schema:

There are some coding issues to clear up before proceeding much further. Variables set in an ISR but used in the loop() should be volatile, e.g. nec_ok. Ensure also that compiler warnings are enabled in the IDE and clean up as required. There are probably other issues.

changed variables to volatile, if a warning is displayed: warning: 'timer_value' may be used uninitialized in this function, note: 'timer_value' was declared here
unsigned int timer_value;

unsigned int timer_value;  make this static as so  static unsigned int timer_value = 0; . As static, it is initialised only once and holds its value between invocations of the calling routine (which is probably what you want here).

nothing changed, the same problem

I think that you have at least one basic problem that timer1 (16 bit) with a prescaler of /8 has a period of ~32ms. A typical NEC data stream is twice that. In the overflow vector of timer1 you reset everything. Anyway, instead of manipulating Timer1, you can simply use micros(). When you enter the routine, calculate the length of the last pulse and preserve the time (in microseconds) you entered the routine for the next entry. Something like pulseLengthLastUs = micros() - enteredAtUs ; enteredAtUs = micros() ;

To find out how far you are getting, create a global error variable, say volatile uint32_t errFlag Set it when there is a value out of range say errFlag = 2000000 + timer_value where the 2000000 represents case 2. Stop the program as soon as there is an error by doing something like this in the loop(): if (errFlag > 0) { Serial.println(errFlag) ; while(true) ; }

I changed to micros but still not working code

It looks much simpler but (a) remember volatile variables volatile boolean nec_ok = 0; (b) adjust the times for us and not the doubled timer ticks (c) add the suggested debug stuff so you know where it first fails.

If output nec_state to the terminal, I get 0 1 0 1 0 1 and so on,  if output pulseLengthUs to the terminal, I get 338020
380
176
200
180
196
176
200
176
200
180
196
180
964
1148
1056
1404
2680
2676
804
1164
1656
528
1552
39964
304
200
176
200
176
200
176
840
2800 for one click

you should have at least 67 time intervals ... read this https://techdocs.altium.com/display/FPGA/NEC%2bInfrared%2bTransmission%2bProtocol ... or this https://www.digikey.ca/en/maker/blogs/2021/understanding-the-basics-of-infrared-communications ... and this https://circuitdigest.com/microcontroller-projects/build-your-own-ir-remote-decoder-using-tsop-and-pic-microcontroller

If use timer I have this time values: 0
122
122
96
96
32
32
33
33
28
28
33
33
32
32
33
33
31
31
1827
1827
1736
1736
133
133
3422
3422
1072
1072
1072
112
112
95
95
32
32
29
29
150
150

you don't have enough time intervals ... the ones that you do have, are not in correct proportions

then what's wrong?

Please show your latest code. Maybe use the same link as before.

code

start by examining the remote control ... is it sending the correct code? ... also, please clean up your code ... it is a mess ... indent it properly and move comments away from the code ... comments are not part of the code

I used an oscilloscope link, yellow pin 5, blue pin 2, and this solution works solution

why are you posting this question again?

here is another question and code

looks like the same question

External interrupt version of NEC protocol decoder using micros() for timing instead of Timer 1.
Drops NEC repeat codes,
Otherwise, in the style of the code in the question.
volatile boolean nec_ok = 0;
byte command, inv_command;
volatile byte nec_state = 0 ;
unsigned int address;
volatile unsigned long nec_code;
volatile uint32_t errFlag = 0 ;
volatile uint32_t decodeStartAtMs = 0 ;

void setup() {
  Serial.begin(9600);
  pinMode( 2, INPUT_PULLUP ) ;
  attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0)
}

void remote_read() {

  static byte i = 0 ;
  static bool wasSpace;
  static unsigned long enteredAtUs = 0 ;
  static unsigned long pulseLengthLastUs ;

  wasSpace = ! digitalRead( 2 ) ;
  pulseLengthLastUs = micros() - enteredAtUs; // Calculate pulse length
  enteredAtUs = micros(); // Store current time for next entry

  switch (nec_state) {

    case 0 : // Wait here until 9ms pulse found )
      if ( pulseLengthLastUs > 8000 && pulseLengthLastUs < 10000 ) {  // got a 9ms pulse
        decodeStartAtMs = millis() ;  // for timeout
        nec_state = 1 ;
        nec_code = 0 ;
        i = 0 ;
      }
      break;

    case 1 : // handle 4.5ms space
      /*
      if ((pulseLengthLastUs > 2000) && (pulseLengthLastUs < 2500)) {
          // silently drop repeat codes !!!
          nec_state = 0; // Reset decoding process
      }
      else
      */
      if ((pulseLengthLastUs > 5500) || (pulseLengthLastUs < 3500)) {
        errFlag = 10000000 + pulseLengthLastUs ;
        nec_state = 0; // Reset decoding process
      }
      else
        nec_state = 2; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
      break;

    case 2 : // handle 562µs or 1687µs space
      if ((pulseLengthLastUs > 1900) || (pulseLengthLastUs < 400)) { // Time interval invalid ==> stop decoding
        errFlag = 20000000 + pulseLengthLastUs ;
        nec_state = 0; // Reset decoding process
        break;
      }

      if ( wasSpace ) {
        // we are interested only in the space length
        if ( pulseLengthLastUs > 1000) // If space width > 1ms (short space)
          bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i)
        else // If space width < 1ms (long space)
          bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
        i++;
        if (i > 31) { // If all bits are received
          i = 0 ;
          nec_ok = 1; // Decoding process OK
          detachInterrupt(0); // Disable external interrupt (INT0)
        }
      }
      break;
  }
}

void loop() {

  if ( errFlag > 0 ) {
    Serial.print( "Error: " ) ;
    Serial.println( errFlag ) ;
    errFlag = 0 ;
  }

  if ( nec_state > 0 && millis() - decodeStartAtMs > 90 ) {
    Serial.println( "Timeout" ) ;
    nec_state = 0 ;
  }

  if (nec_ok) {
    Serial.print( "Code received = " ) ;
    Serial.println( nec_code, HEX ) ;

    address = (nec_code >> 16) & 0xFF; // Extract address from received code
    inv_command = (nec_code >> 8) & 0xFF; // Extract inverted command from received code
    command = nec_code & 0xFF; // Extract command from received code
    if (command == ((~inv_command) & 0xFF)) { // Verify command validity
      Serial.print("Received valid NEC code: ");
      Serial.print(address, HEX); Serial.print(", ");
      Serial.print(command, HEX); Serial.print(", ");
      Serial.println(inv_command, HEX);
    }
    else {
      Serial.println("Received invalid NEC code!");
    }
    nec_ok = 0; // Reset decoding process
    nec_state = 0; // Reset decoding state
    attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Re-enable external interrupt (INT0)
  }

}

This utility can be used to verify the output of an IR receiver showing the timings of the pulses and spaces to  4us resolution.
// protocol analyser utility
// intended to dump timings to the serial console for example from demodulated NEC IR codes
// Connect the IR receiver output to pin 2

const uint8_t DATA_SIZE = 100 ;

struct intervalRead_t {
  uint32_t durationUs ;
  bool space ;
} ;

intervalRead_t intervalRead[ DATA_SIZE ] ;

volatile unsigned long enteredAtUs = 0 ;
volatile uint8_t index = 0 ;
volatile bool firstPulse = true ;

void saveTimes() {

  bool wasSpace;
  uint32_t pulseLengthLastUs ;

  wasSpace = ! digitalRead( 2 ) ;
  pulseLengthLastUs = micros() - enteredAtUs; // Calculate pulse length
  enteredAtUs = micros(); // Store current time for next entry

  if ( firstPulse ) {
    firstPulse = false ;
    index = 0 ;
  }
  else {
    if ( index < DATA_SIZE  )  {
      intervalRead[ index ].durationUs = pulseLengthLastUs ;
      intervalRead[ index ].space = wasSpace ;
      index++ ;
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode( 2, INPUT_PULLUP ) ;
  attachInterrupt(digitalPinToInterrupt(2), saveTimes, CHANGE); // Enable external interrupt (INT0)
}

void loop() {
  if ( !firstPulse && micros() - enteredAtUs > 500000UL  ) {
    for ( uint8_t i = 0; i < index ; i++ ) {
      Serial.print( i ) ;
      Serial.print( "\tinterval= " ) ;
      Serial.print( intervalRead[ i ].durationUs ) ;
      Serial.print( "us  \t") ;
      Serial.print( intervalRead[ i ].space ? "space" : "pulse" ) ;
      Serial.println( ) ;
    }
    Serial.println( ) ;
    firstPulse = true ;
  }
}

For some reason it does not output anything to the console

nec_state always zero and pulseLengthLastUs 238000
380
176
196
176
196
184
192
184
192
176
196
184
960
1072
1132
376
804
2292
2676
1552
2676
1500
1604
40988
304
196
176
196
176
196
176
836
2800

If using your code, print from console when button pressed:  no code
no code
1C0
1DF
3
E
no code
1

How did you get those figures? You can't put a print() statement in function remote_read() because it is an ISR and will any way mess up the timings especially when printing so slowly at 9600 baud. The PIC software appears to generate an NEC repeat code if the button is held in. The code I supplied ignores these. Try only momentarily pressing the button when testing.

I only momentarily pressing the button when testing, but it doesn't print anything

i changed to your updated code but still not working

You've removed any print statements you added to the ISR? Did you see any message on the console at all? You can try temporarily changing the 31 here to say 30 or 29 just to see if there is a missing end pulse. if (i > 31) { // If all bits are received. If that does nothing, you'll have to work out how to use the proteus logic analyser. The oscilloscope resolution is too poor. I tested that code with an NEC remote control before posting it, but not the changes.

pulseLengthLastUs is always false in this condition: pulseLengthLastUs > 8000 && pulseLengthLastUs < 10000 on any button press

There is then a mismatch between the code https://github.com/circuitvalley/IR-Remote-Control/blob/master/NEC%20IR%20Transmitter%20Remote/main.c (NEC) and its performance on a virtual PIC in that Proteus environment. That the 9ms NEC header could not be found is a strong indication of a timing problem. Use a logic analyser/(oscilloscope) to check the wave form and that the carrier is 38kHz. The carrier frequency is not critical but could be an indication that the PIC or environment is incorrectly configured. Maybe, just for testing, use an Arduino IR library.

The results don't look like proper NEC codes and the program will block the ISR for an extended period which may cause other things to go wrong. Whether that matters is another question. Anyway, I added an additional sketch to the end of the one that I provided in the answer. It will print out the timings of an IR data stream and could be used to see where the timing issues are.

displays the following when I press the button: screen

That is an ~8kHz signal with a 33% duty cycle. It is one quarter of the expected speed. It looks like the speed is too slow for that IR receiver component you are using to demodulate it and is passing it directly through, assuming you measured it at pin 2 of the Arduino. Anyway, without proper use of the tools in that simulator to check the timings, the exercise is like tapping in the dark.

but the frequency on the irlink component is 38kHz


text:
override pinMode, digitalWrite and digitalRead
I am using the ESP32 Arduino Framework and I have some GPIO expanders attached via I²C. They work fine and I now want to map some unused pin numbers to them so I can used my custom pin numbers in pinMode, digitalRead and digitalWrite.
Luckily, the Arduino core links these functions weakly.
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));

I defined my own functions like so:
void pinMode(uint8_t pin, uint8_t mode) {
    if(pin<0x80)
        // call conventional handler
    else
        // communicate with GPIO expander via I²C
}

Unfortunately, calling any of the functions will not result in the linker picking my implementation but the linker picks the default implementation.
Any ideas how to override the weakly linked pinMode, digitalWrite and digitalRead?

use a different parameter type. some struct MyPin {int pin;} create constants like MP0, MP1,..

It used overloading before and it works for my custom code. However, I want all 3rd party libraries and the Arduino core to call my functions. E.g. when a display library call digitalWrite on some pins, I want that to work even if that GPIO is on my GPIO expander. Overloading would require me to rewrite the Arduino core and 3rd party libraries to use my function instead. I want to avoid that.

there are very few uses of these functions in core (analogWrite, tone, shift). with which libraries you want to use the io expander?

E.g. in MD_AD9833. My project will a tons of peripherals attached so I would have to fork many different libraries. That would not be viable...

that library uses SPI. do you need to run the CS pin over io expander? most libraries use SPI, I2C, PWM or direct register manipulation

You are exactly right. I need to run the CS pin over an SPI expander. In fact, my project has five different CS signals attached to IO expanders in addition to the native GPIOs of the ESP32. The other GPIOs on the expanders are used for relays and MOSFETs so I could address them with an overloaded function as you proposed. But the five CS pins are addressed by some thrid party libraries using the builtin digitalWrite.

I found the issue: I ran platformio run --target clean instead of platformio run --target cleanall. It seems that only the latter command cleans all build artifacts. The next time I compiled and uploaded, it worked as expected.
Another issue occurs only with Adafruit libraries: Some libraries do not use uint8_t for ports but int8_t and they do checks like
if(pin_number >=0)  {
    // code that only works with pin numbers between 0x01 and 0x80
}

Take the Adafruit GFX library as an example. As a workaround, I will map my GPIO expander ports to 0x40, 0x41, ...


text:
timing changes once DC motors are connected to power
I'm using an arduino uno with two DC motors. I'm also using the built in LED to tell me when the motors should be on as a debug tool. The code is a simple while loop that turns both the motors and the LED on for 10 seconds, and off for 5, and repeat, while a witch is on. This works fine when the motors are not connected to power (when the switch is on, the LED turns on for 10 secs, off for 5 and repeat), but when the motor driver is connected to the power the timing is changed. The motors and the LED are on for less than a second, and off for 5. the "on" period changes a bit, once it even reached the intended 10 seconds.
Why is that and how do I fix that? I tried changing batteries (though i don't know how that might change things, as the led is also working incorrectly and it works of a seperate power source).
the Arduino is connected to a 9V battery and the motors are connected to 4 AA batteries through a L298N motor driver.
this is my code:
#include <Arduino.h>
int RightSpeedPin = 5;
int Rdir2 = 6;
int Rdir1 = 7;
int led = 13;
int LeftSpeedPin = 10;
int Ldir2 = 8;
int Ldir1 = 9;
int SwitchPin = 4;
int ReadVal;
void setup() {
  // put your setup code here, to run once:
  pinMode(Rdir1, OUTPUT);
  pinMode(Rdir2, OUTPUT);
  pinMode(RightSpeedPin, OUTPUT);
  pinMode(LeftSpeedPin, OUTPUT);
  pinMode(Ldir1, OUTPUT);
  pinMode(Ldir2, OUTPUT);
  pinMode(SwitchPin, INPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  ReadVal = digitalRead(SwitchPin);
  while (ReadVal == 1)
  {
    digitalWrite(led, HIGH);
  // starting situation- both motors heading forward
    // running for 10 secs
    digitalWrite(Rdir1, HIGH);
    digitalWrite(Ldir1, HIGH);
    digitalWrite(Rdir2, LOW);
    digitalWrite(Ldir2, LOW);
    analogWrite(RightSpeedPin, 255);
    analogWrite(LeftSpeedPin, 255);
    delay(10000);
    // off for 5
    analogWrite(RightSpeedPin, 0);
    analogWrite(LeftSpeedPin, 0);
    digitalWrite(led, LOW);
    ReadVal = digitalRead(SwitchPin);
    delay(5000);
  }
}

link to the schematics. its rough, I'm not very experienced at drawing schematics. Note that all the ground wires are connected to a breadboard ground rail other that the 9V that powers the arduino. its connected with a round plug, so i don't have individual wires.
EDIT: fixed the schematic

A schematic of your setup would help.  Maybe a picture if all wires can be clearly seen.  Also your sentence: "...and it works of a seperate power source)." sounds important but is confusing.  I'd write an ANSWER, but I am only guessing w/o a schematic... did you connected the 5V power between the Arduino and L298N motor board?

my first guess is that the state of the switch is not being detected correctly ... use a pullup resistor ... second guess is that the arduino is resetting ... you have no code to tell you when setup() executes ... use Serial.print() for debugging messages ... or blink the led twice inside setup()

added schematics.
what would blinking inside of the setup tell me?

think about when setup() executes ... read all of my comment again

Please embed the schematic in your question, do not use external resources, as they can disappear.

the battery symbols are drawn backwards

After debugging by printing:
sTime = millis();
analogWrite(RightSpeedPin, 255);
analogWrite(LeftSpeedPin, 255);
delay(5000);
analogWrite(RightSpeedPin, 0);
analogWrite(LeftSpeedPin, 0);
Serial.print(millis() - stime);

I got times that are less than 300 ms, and no reset (added print to setup). I still have no idea why.
after that, I just replaced delay with while (millis() < Stime + t) { which solved my problem.


text:
ESP8266-01S only coming back from DeepSleep every 2nd time
I'm using an ESP8266-01S for a battery-powered project. The ESP is in DeepSleep, a doorbell relay pulls RST to GND, bringing the ESP to life to do some stuff, before going back to DeepSleep.
My problem is that once the program ran successfully and the ESP is in DeepSleep, the next RST will not bring it up properly. Instead, it will linger in some undefined state, eating around 33.7mA constantly (I went through that battery quite quickly without realizing it).
With serial output enabled, I reliably get something like this when entering those undefined states:
rll�r$�n�l�b|���rb�b�nnlnnbbp�$blrl
Edit: setting the Baud rate to 74880 revealed the above to be the following:
11:58:17.042 -> �
11:58:17.042 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,6)
11:58:17.042 ->

The next RST will then perform successfully, i.e. the ESP comes up, does its thing and goes into DeepSleep. My multi meter shows a power consumption of roughly 15uA, which looks like proper DeepSleep to me.
Another RST would then bring the ESP back into the undefined state, and so on.
Cutting power provokes the same behaviour, so it feels like it could be a hardware thing, some lingering current or something.
I created a minimal version of my program that shows the behaviour on the ESP:
int Led = LED_BUILTIN;

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

void loop() {

  digitalWrite(Led, false);
  delay(4000);// Delay 4 seconds
  digitalWrite(Led, true);
  delay(1000);// Delay 1 second

  ESP.deepSleep(0);
}

Is there anything I'm missing or doing wrong, maybe something on the hardware side, to make DeepSleep work on an ESP8266-01S? Do the pins have to be initialized or brought in a defined state somehow? Also, is there a better way than Serial Output to figure out what's going on?
I believe I don't have to connect GPIO16 to RST, since I don't want to wake the ESP by software, but through hardware events only.
Edit: I left the device in DeepSleep over night and RSTed it in the morning, and this time it recovered fine for once.

that is exactly what should be in the included in the question

I reliably get something like this when entering those undefined states perhaps if you set the baud rate of the terminal software to match what the esp is using, the text will provide some insight into the problem - 74880 I believe is the default for ESP's

will check that out, thank you @JaromandaX

thanks again, I got some new information and edited my question accordingly


text:
LiquidCrystal_I2C, lcd.begin() causes runtime error on Arduino Mega2560
I have tested the library and LCD with simple script and everything worked fine. Now I am trying to add the LCD functionality to my working program but the code reaches the lcd.begin(); function it causes a runtime error and no following lines are executed. I have tried many different configurations and none of them have worked; including have lcd.begin() in the setup(), in the InitSM(), loop(), and RunSM() and it crashes every time.
I am wondering if I am running into a similar issue described here.
Following thebusybee's advice, I started with a simple working script that could print to the LCD screen. I then started adding initializing functions in the setup until it stopped working. InitSM(&AFC); is the line that causes the LCD functions to stop working. InitSM(&AFC); calls millis(), enables watchdog timer interrupts, and external interrupt on digital pin 2. Below is the exam code.
// Library
#include <Arduino.h>
#include <EventTimers.h>
#include <EventCheckers.h>
#include <avr/sleep.h>
#include <Timeout.h>
#include <AFCSM.h>
#include <DoorServo.h>
#include <EventTypes.h>
#include <HardwareInterrupts.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);
//LiquidCrystal_I2C *lcdA; //0x27,20,4
//lcdA = &lcd;
//lcdA->begin();

// global variables
static uint8_t TimerCheck = 0;
static uint8_t Timer30;
static EventType LCDButton;
static EventType BatteryEvents;
static EventType BumperEvents;
static EventType FogEvents;
static EventType CurrentEvent;
static EventType FrontDoor;
static EventType BackDoor;
static AFCDATA AFC;
static AFCState PreviousState;

void setup() {
  // set up serial communication with computer
  Serial.begin(9600);

  // uart for MiniOFS to MCU
  Serial1.begin(1200, SERIAL_8N1);

  /*** set up interrupts, not init ***/
  SetUpWatchdogT(); // 8sec interrval counter for 32sec environ sensor check
  SetUpButtonInt(); // external button interrupt for LCD screen

  // init LCD
  lcd.begin();

  // Enable interrupts
  sei();

  // Set the sleep mode to Power-Down
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // initi doors
  initDoor();

  // init statemachine
  InitSM(&AFC);
  PreviousState = AFC.State;
}

void loop() {
  Serial.flush();

  lcd.clear();
  // lcd.setCursor(2,0);   //Set cursor to character 2 on line 0
  lcd.print("LED INIT!");
  Serial.println("printed");
}

ISR(WDT_vect) {
  // Add to timer
  TimerCheck += 1;

  // check if 30secs have elapsed time has
  if (TimerCheck >= 3){
    TimerCheck = 0; // reset counter
    Timer30 = true; // raise flag
  }

}

void Buttonisr(){
  // Button Flag
  LCDButton = BUTTON_ON;
}

I narrowed it down to being the external interrupt enable on digital pin 2. Below are the functions for the setup and enable of the external interrupt.
void SetUpButtonInt(){

    // set up the pin as an input and attach a isr
    pinMode(ButtonPin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(ButtonPin), Buttonisr, RISING); // interrupt on rising edge of pin

    return;
}

void EnableButtonInt(){

    EIMSK |= (1 << INT0); // enable external interrupt
    Serial.println("enable external interrupt");
    return;
}

How can this setup affect the lcd I2C setup?

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]". Then come back and format your code, it is easy. Then add the specific error message or explain what you mean by "runtime error". To help us help you, minimize your program to the absolute minimum that still shows the erroneous behavior.

Initialize the LCD only once in setup and not with every update

@KIIV I tried this first and it would never make it past setup

If you suspect the line lcdA->begin(); to crash your program, PLEASE write a minimized sketch just with this initialization in setup() and an experimental output. I don't think anyone will rebuild your full hardware setup and debug the complete thing. Investigate step by step. Please [edit] your question and add this minimal sketch and its outcome.

Just a guess. The minimum timeout for the watchdog timer is 16ms. This lcd.begin() may well block for longer than that since the begin method if filled with delay() statements. Just for a test, replace lcd.begin() with delay(1000) to see if you get the same symptoms. Where, incidentally,  is this defined: SetUpWatchdogT()


text:
unable to program esp32cam via cloned esp32-cam-mb
I bought a couple of ESP32CAMs from aliexpress... althought the listing shows them with two buttons, I got the ESP32-CAM-MB boards with just the reset button...
I have my computer set up to dual boot Windows and Linux so when I got an error in windows, I rebooted and installed the ESP32 boards for Arduino 2.1 and went ahead. I had to also install esptool and pyserial for it to work, but it ended up recognizing the port and every time I try to program it the flash flashes, but the programmer responds with

A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0xb)! The chip needs to be in download mode.

When I enable the serial console and press the reset button I get the following:
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:6968
load:0x40078000,len:13072
ho 0 tail 12 room 4
load:0x40080400,len:3896
entry 0x40080688
[0;32mI (31) boot: ESP-IDF v4.1-dirty 2nd stage bootloader[0m
[0;32mI (31) boot: compile time 16:15:01[0m
[0;32mI (31) boot: chip revision: 3[0m
[0;32mI (34) boot_comm: chip revision: 3, min. bootloader chip revision: 0[0m
[0;32mI (41) boot.esp32: SPI Speed      : 40MHz[0m
[0;32mI (46) boot.esp32: SPI Mode       : DIO[0m
[0;32mI (51) boot.esp32: SPI Flash Size : 4MB[0m
[0;32mI (55) boot: Enabling RNG early entropy source...[0m
[0;32mI (60) boot: Partition Table:[0m
[0;32mI (64) boot: ## Label            Usage          Type ST Offset   Length[0m
[0;32mI (71) boot:  0 nvs              WiFi data        01 02 00009000 00005000[0m
[0;32mI (79) boot:  1 otadata          OTA data         01 00 0000e000 00002000[0m
[0;32mI (86) boot:  2 app0             OTA app          00 10 00010000 00300000[0m
[0;32mI (94) boot:  3 spiffs           Unknown data     01 82 00310000 000f0000[0m
[0;32mI (101) boot: End of partition table[0m
[0;32mI (106) boot_comm: chip revision: 3, min. application chip revision: 0[0m
[0;32mI (113) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x1d2048 (1908808) map[0m
[0;32mI (849) esp_image: segment 1: paddr=0x001e2070 vaddr=0x3ffbdb60 size=0x04d3c ( 19772) load[0m
[0;32mI (857) esp_image: segment 2: paddr=0x001e6db4 vaddr=0x40080000 size=0x00400 (  1024) load[0m
[0;32mI (858) esp_image: segment 3: paddr=0x001e71bc vaddr=0x40080400 size=0x08e54 ( 36436) load[0m
[0;32mI (880) esp_image: segment 4: paddr=0x001f0018 vaddr=0x400d0018 size=0x9df74 (647028) map[0m
[0;32mI (1127) esp_image: segment 5: paddr=0x0028df94 vaddr=0x40089254 size=0x0b6a0 ( 46752) load[0m
[0;32mI (1159) boot: Loaded app from partition at offset 0x10000[0m
[0;32mI (1159) boot: Disabling RNG early entropy source...[0m
�
SD Size: 29557MB  OK

I can see that the board is in SPI_FAST_FLASH_BOOT mode which according to the linked documentation is wrong... but how to I get it to reboot in the correct mode?
Others have had similar issues, but they use another tool stack, so I am not sure what their solution would translate to in the Arduino 2.1 IDE...

While making sure I included all the correct links and pictures in the question, I found the answer - if an SD card is inserted, the flashing cannot be performed.
Removing the SD card and resetting the ESP32 works. I now have a very bright flashing LED


text:
Error while uploading "A fatal esptool.py error occurred: Write timeout"
I have constantly been getting this error while trying to upload a sketch on Wemos D1 Mini R1 & R2 type board.

A fatal esptool.py error occurred: Write timeout

I've recently updated my Arduino IDE, so I assumed that it might be due to a bad installation. But after reinstalling everything including the Board Manager lib for ESP, Arduino IDE itself nothing worked. When I click on the Board Info, it displays an error "Native serial port, can't obtain info".
I've also tried different type of ESP boards (e.g. NodeMCU) but for all boards the problem is same. When I plug an Arduino to the same USB Port, it auto-detect the board, but when I plug-in the ESP boards, it doesn't recognize the boards automatically. So my guess is it has something to do with the CH34X driver. However I have tried reinstalling few versions of the driver from authentic sources, but nothing made an impact.
Any help is appreciated.
Following is the full trace of log getting printed:
. Variables and constants in RAM (global, static), used 28104 / 80192 bytes (35%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ DATA     1496     initialized variables
╠══ RODATA   920      constants
╚══ BSS      25688    zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 59667 / 65536 bytes (91%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ ICACHE   32768    reserved space for flash instruction cache
╚══ IRAM     26899    code in IRAM
. Code in flash (default, ICACHE_FLASH_ATTR), used 232148 / 1048576 bytes (22%)
║   SEGMENT  BYTES    DESCRIPTION
╚══ IROM     232148   code in flash
esptool.py v3.0
Serial port COM8
Connecting...

A fatal esptool.py error occurred: Write timeout

Following is the IDE Settings while uploading:

The "most common reason" mentioned in this answer was actually the problem I had. Unfortunately I was using a charge only cable even though the cable package clearly said it was a data-cable. At times, these cheap electronics products confuses us a lot and we often miss to critically scrutinize the most obvious problems. As described in this Adafruit tutorial this problem seems to be a very common one.

I've run into this a bunch recently, and typically, but not always, the cause is that I was using a GPIO pin that was reserved and couldn't be used during boot up. It's surprising how many of the pins cannot be used.
Check out this chart I found and saved, unfortunately I do not know the source, but I have found it to be very accurate, and I reference it a lot:

For my case, a simple Blink program is not getting uploaded. I am not sure how
failure to upload a program to the board can be caused by a reversed GPIO pin. Do you mean the board is damaged and it can't be used? I do not see an solution or conclusion to the problem, in your answer. Still need help.

I had the same problem.
My solution:
Program for blinking led ESP8266MOD (cheap Chinese esp8266mod module)
I used Arduino IDE 2.1.0
info from https://vimalb.github.io/IoT-ESP8266-Starter/Lesson_01/lesson.html
Connect resistor 220 Ohm and LED in serial. Connect resistor on D8 and the LED
on G (Ground). I used a breadboard and connect 5V pin on the esp board and
the pin G on the esp board to the Red en Bleu line on mij breadbord.
Write the program.
// Base ESP8266

#include <ESP8266WiFi.h>

WiFiClient WIFI_CLIENT;

#define LIGHT_SENSOR A0

#define LED 15    // this is pin D8 on the board

#define BUTTON 4

void setup() {

  // Initialize the serial port

  Serial.begin(115200);

  // Configure light sensor pin as an input

  pinMode(LIGHT_SENSOR, INPUT);

  // Configure LED pin as an output

  pinMode(LED, OUTPUT);

  // Configure BUTTON pin as an input with a pullup

  pinMode(BUTTON, INPUT_PULLUP);

}

void loop() {

  // Turn the LED on (HIGH is the voltage level)

  digitalWrite(LED, HIGH);

  // Wait for 1000 milliseconds

  delay(1000);

  // Turn the LED off by making the voltage LOW

  digitalWrite(LED, LOW);

  // Wait another 1000 milliseconds

  delay(1000);

  // Send a message over the serial port

  Serial.println("Finished loop");

}

Compile the program.
If Fault check the program.
Go to Tools -> Port  (I used com6)
Push the reset button on the espboard and keep it.
Connect the usb-cable on the espboard.
Release the reset button.
Besure everthing is connect.
Upload the program by using the upload button arduino IDE.
Start the serial monitor and check text "Finished loop" every 2 seconds.
Maybe this will help


text:
Using 2 VL53L4CD ToF sensors and getting error after getting first reading
pretty new to arduino stuff and was hoping to get some help with my code.
I'm trying to use 2 ToF sensors and get continuous readings from them. I understand that I have to use the xshut feature and switch them on and off to alternate them but I'm stuck in an error loop and I'm not quite sure where to go from here. Does anyone know what's going on and how to solve this?
Here's my code:
/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <WiFi.h>
//#include <ESPAsyncWebServer.h>
#define DEV_I2C Wire
#define SerialPort Serial
char report[64];
//address we will assign if dual sensor is present
uint8_t sensor1add = 0x30;
uint8_t sensor2add = 0x31;
// set the pins to shutdown
#define xshut1 A0
#define xshut2 A1
#define GFX_BL DF_GFX_BL
//this holds the measurement
VL53L4CD_Result_t results1;
VL53L4CD_Result_t results2;
float sensor1, sensor2;
//Components.
VL53L4CD sensor1_vl53l4cd_sat(&DEV_I2C, A0);
VL53L4CD sensor2_vl53l4cd_sat(&DEV_I2C, A1);
//init Wifi
/*void initWifi(){
    Serial.print("Setting AP (Access Point)...");
  // No password
  WiFi.softAP (ssid);
  // Start WiFi Access Point
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.print(IP);
    // Print ESP8266 Local IP Adress
  Serial.println(WiFi.localIP());
}*/
//init sensors
void initSensor(VL53L4CD sensorX, uint8_t sensoradd)
{
  // Init sensor1
  //Set sensor address.
  sensorX.VL53L4CD_SetI2CAddress(sensoradd);
  // Configure VL53L4CD satellite component.
  sensorX.begin();
  // Switch off VL53L4CD satellite component.
  sensorX.VL53L4CD_Off();
  //Initialize VL53L4CD satellite component.
  sensorX.InitSensor();
  // Program the highest possible TimingBudget, without enabling the
  // low power mode. This should give the best accuracy
  sensorX.VL53L4CD_SetRangeTiming(200, 0);
  sensorX.VL53L4CD_SetOffset(-10);
  // Start Measurements
  sensorX.VL53L4CD_StartRanging();
}
//getSensor1Reading
void getSensor1Reading(uint8_t status, uint8_t NewDataReady)
{
  sensor1_vl53l4cd_sat.VL53L4CD_On();
  Serial.println("Sensor 1 is on");
  if ((!status) && (NewDataReady != 0)) {
    // (Mandatory) Clear HW interrupt to restart measurements
    sensor1_vl53l4cd_sat.VL53L4CD_ClearInterrupt();
    // Read measured distance. RangeStatus = 0 means valid data
    sensor1_vl53l4cd_sat.VL53L4CD_GetResult(&results1);
    snprintf(report, sizeof(report), "Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
             results1.range_status,
             results1.distance_mm,
             results1.signal_per_spad_kcps);
    sensor1 = results1.distance_mm;
    Serial.println((String)"This is Sensor1 " + (float)sensor1 + (String)"mm");
  }
  sensor1_vl53l4cd_sat.VL53L4CD_Off();
}
//getSensor2Reading
void getSensor2Reading(uint8_t status, uint8_t NewDataReady)
{
  sensor2_vl53l4cd_sat.VL53L4CD_On();
  Serial.println("Sensor 2 is on");
  if ((!status) && (NewDataReady != 0)) {
    // (Mandatory) Clear HW interrupt to restart measurements
    sensor2_vl53l4cd_sat.VL53L4CD_ClearInterrupt();
    // Read measured distance. RangeStatus = 0 means valid data
    sensor2_vl53l4cd_sat.VL53L4CD_GetResult(&results2);
    snprintf(report, sizeof(report), "Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
             results2.range_status,
             results2.distance_mm,
             results2.signal_per_spad_kcps);
    sensor2 = results2.distance_mm;
    Serial.println((String)"This is Sensor2 " + (float)sensor2 + (String)"mm");
  }
  sensor2_vl53l4cd_sat.VL53L4CD_Off();
}
/*void offset()
{
}*/
/* Setup ---------------------------------------------------------------------*/
void setup()
{
  // Initialize serial for output.
  SerialPort.begin(115200);
  SerialPort.println("Starting...");
  // Initialize I2C bus.
  DEV_I2C.begin();

  initSensor(sensor1_vl53l4cd_sat, sensor1add);
  initSensor(sensor2_vl53l4cd_sat, sensor2add);
}
void loop()
{
  uint8_t NewDataReady1 = 0;
  uint8_t NewDataReady2 = 0;
  uint8_t status1;
  uint8_t status2;
  do {
    status1 = sensor1_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady1);
    status2 = sensor2_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady2);
  } while (!NewDataReady1 || !NewDataReady2);
  getSensor1Reading(status1, NewDataReady1);
  getSensor2Reading(status2, NewDataReady2);
  if (!sensor1_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady1))
  {
    Serial.println((String)"NewDataReady1 is not ready");
  }
  else if (!sensor2_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady2))
  {
    Serial.println((String)"NewDataReady2 is not ready");
  }
  else{Serial.println("New data unable to be parsed");}
}

But I keep getting this error:
--- forcing DTR inactive
--- forcing RTS inactive
--- Terminal on COM9 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
This is Sensor1 0.00mm
This is Sensor2 30.00mm
[  2883][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3884][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error 263
[  3884][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3886][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3893][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3900][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3907][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3914][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[  3921][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1


text:
How to change the I2C address of the AS5048B?
I saw this video from James Bruton. See the links to the GitHub repos in the video description.
I bought a few AS5048B boards from AMS, so I can measure the position of my stepper motors.
In the sosandroid repo, I ran program_address and was able to get one of them working, but they all have the same I2C address, and because I want to have 6 of them running simultaneously, it of course won't work. I know I could get an I2C multiplexer...
I also tried setting the A1 and A2 pins on the AS5048B to high and low, which change the I2C address (for a total of 4)... But I want to change the I2C address permanently for each board.
It looks to me like program_address is supposed to permanently program the I2C address, which the user can specify in the .ino file:
// Construct our AS5048B object with an I2C address of 0x40
AMS_AS5048B mysensor(0x40);

But no matter what I set it to (e.g. 0x40, 0x41, 0x42, 0x43, 0x44), the Arduino I2C scanner always finds 0x44, which is the default address, so the program_address must not be working.
EDIT: the default address is actually 0x40. I must have programmed it to 0x44 without knowing (I was playing around with this board trying to figure this all out).
I know that normally the I2C addresses cannot be changed, but it looks like this one can:
Here's a snippet from the link above. It says the OTP bits can be programmed/burned (only once!). My understanding is that the I2C address is saved in the OTP bits.

Program the OTP bits permanently:

Write dec.253 into the OTP control register (dec.3) to enable the special programming mode
Set the Burn bit (dec.8) in the OTP control register (dec.3) to enable automatic programming procedure
Write dec.0 into the OTP control register (dec.3) to disable the special programming mode

I am using the Teensy 4.1 using PlatformIO in VS Code, and I also tried using an Arduino Uno in the Arduino IDE.
My wiring is as follows:

So how do I program the I2C address on the AS5048B boards?
EDIT:

I changed an image to text, and cleaned things up.

As @6v6gt requested, I used the I2C scanner and it is still showing 0x40 (on this particular board), so it must not have been programmed (unless it's possible to program it to 0x40 even though 0x40 is its default value). The only thing I changed from the program_address repo is this line in the .ino file:
// Construct our AS5048B object with an I2C address of 0x40
AMS_AS5048B mysensor(0x48);

I changed the 0x40 to 0x48. But now I am getting this in the serial monitor:
Angle degree : I2C error: 2
359.9780273437

Since I must have programmed the other board to 0x44 successfully, I am trying to think of what I did differently, but I don't remember.
There are hundreds of lines of code in program_address (and the .h and .cpp file), so I probably shouldn't post all of it here. But here's the GitHub repo.

Or is this whole OTP bit programming only meant for the manufacturer, thus it has already been burned and I cannot change it, meaning I would have to resort to using the A1 and A2 pins? If this is the case, it would only allow 4 addresses, but I need 6, which means I would need a second I2C bus (which the Teensy 4.1 can do), but I don't know how to do that, or if the library supports it. I'm only 19 years old and don't have a lot of experience with this.

To whoever down voted my OP, please explain why

I don’t know why someone would downvote you; you posed a very thorough well-researched question.

probably for posting pictures of text, instead of posting the text  ... makes it difficult for visually impaired people to read the post

Don't worry about downvotes. I'm a moderator and my answers get downvoted! It goes with the territory. Some people enjoy making downvotes. :)

To me, it looks like the default address is 0x40 (assuming the 2 hardware pins are unset) so I can't understand why you are seeing 0x44. Show the command(s) which you used to put the MSBs of your desired address in register 0x15. Did you invert the MSB as is shown in the linked product document ?

@6v6gt Yes, it looks to me like the default address is 0x40. I think the OP programmed a new I2C address of 0x44 by using the example.

@jsotola I get that but a downvote because of that without an explanation isn't going to help anyone. I'd tend to complain about pictures of text rather than downvote because of them. I'm happy to downvote truly crappy questions though.

Thanks. I'll be more careful to paste in the text instead of an image

read here https://arduino.stackexchange.com/questions/69654/mcp4725-i2c-address/69658#69658

There is no obligation to provide a reason for a downvote, however it is courteous to do so, if the reason isn't blindingly obvious. Your question was very detailed, the sort of question we like to receive. Good questions tend to get good answers. :)

The device slave I2C address consists of the hardware setting on pins A1, A2 and upper MSBs programmable by the user. It is the setting of the MSBs, in addition to A1/A2 that I believe the OP is after.
The information provided by @Nick Gammon concerning A1 and A2 is correct, but does not consider the other 5 bits (the MSBs). It appears that you can, indeed, permanently set a new I2C slave address on the device.
You need to read the programming application note very carefully, but they explain how to burn those bits into the register....it seems straightforward and is really just four steps, but I suppose it can be a little daunting, e.g.,
"slave address consist of 5 programable bits (MSBs) and the hardware setting of Pins A1 and A2 I²C address <4> is by default not programmed and due
to the inversion defined as '1'"
The application note gives an example of the 4 steps....

It may be the case that you already changed the I2C address default to 0x44 by following the instructions. [edited to add] Can you post the complete program [Arduino IDE code] that you used to try to change the I2C address?

Good point about already having reprogrammed them. I uploaded the I2C scanner scetch and connected a new AS5048B and it said 0x40. So I tried programming 0x41, then uploaded the I2C scanner and it said "Angle degree : I2C error : 2

As I mentioned, if you post the code (preferring the Arduino IDE code that you mentioned), I am confident that we (if not me, someone else here) can figure out what is going on. More than likely, you are doing some inadvertent writes to that register and locking them in or something like that.

Alright, I'll do that when I get home tonight (9 hours from now)

@JohnDoe ". . .So I tried programming 0x41,". It is not possible to set the device to address 0x41 if you also want to avoid using the address pins A1 and A2. 0x41 can only be achieved by leaving the device with the default configuration "0x40" but then pulling A1 high. You could have the following I2C addresses without using A1 and A2: 0x40, 0x44, 0x48, 0x4C, 0x50 and 0x54 etc. Having said that, my own preference would be to keep four of the devices as 0x40 (default) and change two to 0x44 then make use of A1 and A2.

"It is not possible to set the device to address 0x41 if you also want to avoid using the address pins A1 and A2..."   Thanks! I didn't know that. What are the limitations to these address names? Can I just make them up, like can I do 0x51 even though you didn't list it.

Using a AS5048B with an address that was still 0x40, I tried programming the address to 0x48, but the serial monitor says "Angle degree : I2C error: 2". Is it possible to program it to burn the OTP bits to 0x40? I wonder if I did that by accident? I wish there was an easy way to tell if they have been burned already

The error message indicates the subsequent command that you entered failed to address the device with its correct  (possibly changed by the previous command ) I2C address. Check with the I2C scanner what address it shows (probably/hopefully still 0x40). Please show anyway the sequence of commands you used in your attempt to change the address to 0x48 (and also the commands used in your previous, apparently successful, attempt to change the address of another chip to 0x44). Add this information at the end of your OP.

Thanks. I edited my OP.

I must admit I didn't read the datasheet in great detail when I answered. It is clever of them to allow programming the  MSB, because that would give you a big range of addresses. That makes sense for this type of application.

@JohnDoe This is the line in program_address.ino (from the sosandroid repository as in the OP) which changes the I2C address for the chip (assuming A1 and A2 are pulled low) from the default of 0x40 to 0x44 :  mysensor.addressRegW(0x01); changing it to mysensor.addressRegW(0x02); would appear to set the address of a new chip to 0x48. The code appears to follow the data sheet to make the internal changes to the device. I can't explain why you have received the error message from the "Angle degree" test. Were A1 and A2 low (thus ensuring that the new chip had the default address of 0x40) ?

Thanks! That makes more sense. I will try this when I'm done work today. This should solve it. Now I just want to know what the limitations are. Can I set addressRegW(0x99)? How does changing the addressRegW affect the address?

Nice! I programmed it to 0x48 successfully. Thanks! Now I would just like to know the answer to the question I asked above. Also, does the number have to be a positive integer?

but they all have the same I2C address

No, they have 4 possible addresses, based on how you configure A1 and A2. So you can have 4 different addresses immediately.

But I want to change the I2C address permanently for each board.

For each board, set up A1 and A2 differently.
This only gives you 4 different addresses, not 6. You could conceivably connect 8 devices to two different Atmega328 chips, and have them do the readings and forward the results using a protocol you devise, to your "main" board. The Atmega328 chips only cost around $US 5 each so this isn't a big deal.
Another approach would be to run SDA and SCL through a multiplexer chip, so that you enable one batch of 4 chips and then the other batch. Without trying it out, it is hard to say if this would work satisfactorily.


text:
Arduino Uno not interfacing with GSM SIM900A Module
I am using an Arduino Uno with a SIM900A module. I want to send a simple SMS but it is not working, as it either has no response in Serial monitor or there are reversed question marks. I have attached a picture of my setup.

My module didn't work on day, then worked for a day and then now has stopped working, but it is not a hardware issue, as the board switches on and when I try to call the connected SIM, a ring is heard, meaning it has been connected.
I am using a 12V 2A power supply for the board, but I have previously tried with a 12V 1.5A power supply as well, and at the beginning even tried with the Arduino 5V pin. So I do not believe it is a power supply issue either.
Next, I checked the wiring. I confirmed the wires were working by testing them on another sensor, and then used them for this module. I also checked the connections. I have connected the GND pin of the SIM900A to the GND of the Arduino, connected the RX to D9 and then connected the TX to D10. This worked at first, but now shows no response in Serial monitor, so then I tried to reverse the pins (RX to D10 and TX to D9) while keeping the code the same, which produced reversed question marks. But then, upon trying again, this also produced no response.
One of the common online answers was a mismatch in baud rates, so I tried changing the GSM's baud rate from 9600 to everything up to 115200. When the reversed question marks were produced, changing the baud rate just produced weirder characters, and now, as there is no response at all, changing the baud rate has no impact.
I have also tried using pins 2 & 3 and 7 & 8 instead of 9 & 10, but there is no difference.
The code I am currently using is as follows, and is copied directly from here, but I have tried multiple other codes from different solutions to no avail:

SoftwareSerial mySerial(9, 10);

void setup()
{
  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);
}

void loop()
{
  if (Serial.available()>0)
   switch(Serial.read())
  {
    case 's':
      mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
     delay(1000);  // Delay of 1 second
     mySerial.println("AT+CMGS=\"+91xxxxxxxxxx\"\r"); // Replace x with mobile number
     delay(1000);
     mySerial.println("Technolab creation");// The SMS text you want to send
     delay(100);
     mySerial.println((char)26);// ASCII code of CTRL+Z for saying the end of sms to  the module
      delay(1000);
      break;

    case 'r':
      mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
      delay(1000);
      break;
  }

 if (mySerial.available()>0)
   Serial.write(mySerial.read());
}

Please help me out, I've tried everything I can think of.

On the Arduino serial monitor - have you set it to "Both NL & CR" ?

the picture is not useful ... it shows two boards and some wires, but it does not show where the connections are

@DrG yes I have set it to Both NL & CR

@jsotola sorry, but the connections are the same as mentioned above.


text:
How to write single binary code to output pin
I am relatively new to arduino and coding in general and im just looking for a code to write a single string of binary code e.g.; "01000111101"
To a specified output pin instead of copying and pasting
"Digital write (high)
Digital write (low)
Etc."
preferably with the option to change speed between bits.
Would be very appreciative for someone to help me out

look at example LED blink code for outputting single bit of data ... look at arrays for indexed list of data ... also at for loops for generating an index value

your question is a general programming question ... it is not Arduino specific, so it does not belong here

It would be easy enough to make this Arduino specific @Arbadatduino if you specified a specific Arduino board and pin.  So edit your TITLE and QUESTION.

If timing is not critical, consider dividing the number of interest by 2. If there was a remainder set the Arduino pin to 1. If not set it to 0. Then delay for as long as needed. Keep doing this until there is nothing left to divide 2 into.
However, sending out data in serial fashion is as old as computers. Likely older. Consequently there are a lot of built in features which do this.  Specifically, it is not necessary to explicitly code up a function to convert a value to serial data. Even on an Arduino.


text:
HC-08 Compatibility issues with iPhone
I am trying to connect my IPhone to an HC-08 Bluetooth module on an Arduino. The HC-08 is showing up in the new device section of android devices but it does not show up on an IPhone's Bluetooth device adding page. Also although it shows up on Android it will not successfully pair. I have an IPhone 13 which uses Bluetooth v5 and the HC-08 uses Bluetooth v4. I think Bluetooth v5 should be backwards compatible so that should not be the issue.
Here are my questions:

Could the problem be that I need to write some Arduino initialization code? Currently I am not writing any code and just trying to connect to the device to my phone.
Is it common that these modules will stop working over time? I have had this for several years and never used it.
Is there another common reason that this will not show up in the Bluetooth menu of an IPhone such as a security setting?

Have you tried to use Bluefruit Connect on the iPhone to see if it can detect your bluetooth module?


text:
Good practice to assign shift-register pins at the same time?
I'm new to bit register manipulation and am trying to set input and output values of some pins. The code sample I have on hand does it this way::
DDRD |= (1 << 2);
DDRD |= (1 << 4);
DDRD &= ~(1 << 5);
PORTD |= (1 << 2);
PORTD &= ~(1 << 4);
PORTD &= ~(1 << 5);

I have two questions:

This is part of a code where I'm attempting to determine the time for a capacitor's discharge between pins 2 and 4. The arduino helpfiles mention that there may be a benefit to triggering both pins at once. Therefore: Is it is it possible to do DDRD |= B00010100; and PORTD |= B00000100; or combine the first three DDRD  lines so it happens simultaneously, or does it have to be separately called?

Why is it PORTD &= ~(1 << 4) and not PORTD |= ~(1 << 4);Can this conflict with the previous state of PORTD.

(1 << 4) is 00010000,  they are interchangeable ... ~(1 << 4) is the inverse 11101111 ... think about what the OR function does and what the AND function does

so it happens instantaneously ... maybe you wanted to say simultaneously

OK, thanks. Writing this out in a simplified form helps. Since & only returns 1 if a = 1, and b = 1, therefore 0 & 0 = 0, and 1 & 0 = 0 which is exactly what we want no matter what happens. On the other hand 1 & 1 = 1, so anything on remains on, and 0 & 1 = 0 so what was off remains off.

Yes, sorry simultaneously. I was quoting from the Arduino help page but didn't add its context.  If I'm timing a capacitor discharge between pins 2 and 4, is there a benefit to triggering both pins at once instead of doing it line by line? eg B00010100 vs each pin individually?

Its context for the question. The original is because I don't know how it affects timings. It appears my question wasn't properly phrased from your feedback. I've amended it accordingly. Thanks.

DDRD |= (1 << 2);
DDRD |= (1 << 4);

The equivalent to that is:
DDRD |= (1 << 2) | (1 << 4);

However I prefer bit because it does the shift for you:
DDRD |= bit(2) | bit(4);

Why is it PORTD &= ~(1 << 4) and not PORTD |= ~(1 << 4);

PORTD &= ~(1 << 4) is turning a bit off. First you invert the sense of the bit with the ones complement operator (~) and then by anding it, it means that all bits are retained except that one. So this is basically turning bit 4 off. If you used |= it would turn all of the other bits on.
Equivalent code:
PORTD &= ~bit(4);

Based on your example you meant bit 5 not bit 4.

PORTD |= (1 << 2);
PORTD &= ~(1 << 4);
PORTD &= ~(1 << 5);

That is turning on bit 2, and turning off bits 4 and 5, and leaving the rest unchanged.

Thanks. In that case would DDRD &= B00000000; DDRD |= B00010100; have a similar result ...

If you do DDRD &= B00000000; then you are setting all bits to zero. So the simple equivalent to the above would be:
DDRD = B00010100;

This is a straight assignment, so you don't need to clear any bits.
Or, you could write:
DDRD = bit(2) | bit(4);

Do you know if bit() faster or is it cleaner compared to 1 << x; or is it better for me to hook up a scope to test this myself?

It is exactly the same. bit is just a #define  in the Arduino.h file, as follows:
#define bit(b) (1UL << (b))

So all it does is save you writing the brackets and the shift left operator. It expands out to the same as what you were writing and thus will execute at the same speed, and take the same amount of memory.

Thanks. In that case would DDRD &= B00000000; DDRD |= B00010100; have a similar result to your DDRD |= bit(2) | bit(4); DDRD &= bit(3) | bit(6); In my mind this first sets everything to input, then sets bits 2 and 4 to output. The malus would be that it changes all other settings due to the first DDRD &= B00000000 section?

See expanded answer.

Thanks. Do you know if bit() faster or is it cleaner compared to 1 << x; or is it better for me to hook up a scope to test this myself?

@Letshin See additional paragraph in answer.


text:
How to drive two Stepper motors and use an Ultrasonic sensor together?
I am working on an autonomous robot using two 4-pin stepper motors, HC-SR04 ultrasonic sensor, 2 L298N motor drivers (one for each motor), and an Arduino Uno. My problem is that when I use the stepper motors with the Stepper library, only one motor works at a time. My solution was to control the one step at a time in a short period of time, which worked, however, this introduces a new problem. The ultrasonic sensor requires a delay to work, but this makes the movement of the robot quite slow and jittery as it works only by one step at a time. When I remove the delay from the ultrasonic sensor, it starts returning the correct value, but then also returning 0 right after each correct value. My solution was to ignore the returned 0, but this is not ideal.
How can I use two stepper motors at the same time and use an Ultrasonic sensor?
Here is my code:
#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */
 Ultrasonic ultrasonic(13, 12);
 int distance;

 int driveSpeed = 100;
 int stepsPerRevolution = 200;
 int leftMotorStep = 0;
 int rightMotorStep = 0;

 // Time interval between steps for both motors
 const int stepInterval = 10;  // Adjust as needed

 // Last step time for each motor
 unsigned long leftMotorLastStepTime = 0;
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor(stepsPerRevolution, 4, 5, 6, 7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);
 }
 void loop() {
   distance = ultrasonic.read();

   Serial.print("Distance in CM: ");
   Serial.println(distance);
   delay(250); //This delay makes the motors behave strangely

   if (distance < 15) {
     Serial.println("AVOIDING OBSTACLE!");
     // Perform obstacle avoidance behavior
     avoidObstacle();
   } else if (distance < 30) {
     Serial.println("APPROACHING OBSTACLE!");
     // Perform slow approach behavior
     slowApproach();
   } else {
     Serial.println("DRIVING!");
     // Perform normal driving behavior
     drive();
   }
 }

 void avoidObstacle() {
   // Stop the robot
   halt();

   // Rotate the robot to avoid the obstacle
   leftM();

   // Delay to allow the rotation to complete
   delay(1000);
 }

 void slowApproach() {
   // Slow down the motors
   int slowSpeed = 50;
   rightMotor.setSpeed(slowSpeed);
   leftMotor.setSpeed(slowSpeed);

   // Move the robot forward slowly
   forwardM();

   // Delay to allow the slow approach
   delay(1000);
 }

 void drive() {
   // Set the motors back to the normal speed
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);

   // Move the robot forward
   forwardM();
 }

 void forwardM() {
   rightMotor.step(1);
   leftMotor.step(1);
 }
 void leftM() {
   rightMotor.step(1);
   leftMotor.step(-1);
 }
 void rightM() {
   rightMotor.step(-1);
   leftMotor.step(1);
 }
 void reverseM() {
   rightMotor.step(-1);
   leftMotor.step(-1);
 }
 void halt() {
   rightMotor.step(0);
   leftMotor.step(0);
 }

first, stop using delay()

When I don't use delay(), the Ultrasonic sensor returns 0 after every value (as mentioned int the post).

stop using the delay() function to introduce a delay ... see the blinkWithoutDelay example sketch in the Arduino IDE

Thank you, this definitely helps!

may be of interest ... https://wokwi.com/projects/327381547863769683

Try this code.
Here is a simulation. https://wokwi.com/projects/366108641014000641
Click on the sensor to set the distance in the simulation
NOTE: centimeters is cm, not CM.
Not tested on hardware.

// https://arduino.stackexchange.com/questions/93302/how-to-drive-two-stepper-motors-and-use-an-ultrasonic-sensor-together

#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */

 Ultrasonic ultrasonic(13, 12);

 int distance;

 int slowSpeed          =  100;
 int driveSpeed         = 1000;
 int stepsPerRevolution =  100;
 int leftMotorStep      =    0;                         // current step speed and direction
 int rightMotorStep     =    0;

 int stepSpeed          =   10;                         // this is the motor speed

 const int stepInterval =    1;                         // Time interval between steps for both motors

 unsigned long leftMotorLastStepTime  = 0;              // Last step time for each motor
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor (stepsPerRevolution, 4, 5,  6,  7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(1);
   leftMotor. setSpeed(1);
 }

 void loop() {

  distance = ultrasonic.read();

  Serial.print("Distance in cm: ");
  Serial.print(distance);  Serial.print("\t");

  switch (distance) {                              // used switch/case for cleaner looking code
    case 0 ... 14:
      Serial.println("avoid");
      avoidObstacle();                             // Perform obstacle avoidance behavior
      break;

    case 15 ... 29:
      Serial.println("approach");
      slowApproach();                              // Perform slow approach behavior
      break;

    default:
      Serial.println("drive");
      drive();                                     // Perform normal driving behavior
      break;
  }

  rightMotor.step(rightMotorStep);                 // this actually moves the motors
  leftMotor .step(leftMotorStep);
}

 void avoidObstacle() {
   halt();                                          // Stop the robot
   leftM();                                         // Rotate the robot to avoid the obstacle
 }

 void slowApproach() {
   rightMotor.setSpeed(slowSpeed);                  // Slow down the motors
   leftMotor. setSpeed(slowSpeed);
   forwardM();                                      // Move the robot forward slowly
 }

 void drive() {
   rightMotor.setSpeed(driveSpeed);                 // Set the motors back to the normal speed
   leftMotor. setSpeed(driveSpeed);
   forwardM();                                      // Move the robot forward
 }

 void forwardM() {
   rightMotorStep =  stepSpeed;                     // select direction of step only
   leftMotorStep  =  stepSpeed;                     // do not move motor
 }                                                  // actual stepping is done at end of loop()
 void leftM() {
   rightMotorStep =  stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void rightM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  =  stepSpeed;
 }
 void reverseM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void halt() {
   rightMotorStep =  0;
   leftMotorStep  =  0;
 }

Thank you, this is really helpful!


text:
Determine if a XIAO ESP32C3 is charging
When the XIAO ESP32C3 is charging a LiPo battery, there is a small LED on the board that lights up. Is there any way to access this information in an Arduino program?

yes, there is ... is that really all you want to know?

put an ldr or photodiode up to the LED. you can also use a clamp-style current meter to detect charge current.

No, according to the schematic it's not wired to any pin on MCU.


text:
How to pass AT commands to Lora from ESP32 UART?
I have connected "Reyax RYLR998" Lora module to ESP32 UART2, but AT commands passed through Hardware serial not working.
#define RXD2 16
#define TXD2 17

void setup()
{
    Serial.begin(115200);
    Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);

    Serial.print("\nSetting Lora Module \n");

    Serial2.print("AT+BAND=865000000\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);

    Serial2.print("AT+ADDRESS=1\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);

    Serial2.print((String)"AT+NETWORKID=5\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);
}

void loop()
{
    while (Serial2.available())
    {
        Serial.print(char(Serial2.read()));
    }
}

I tried
Serial2.print((String)"AT+NETWORKID=5\n");
Serial2.println((String)"AT+NETWORKID=5\r");
Serial2.print((String)"AT+NETWORKID=5\r");

Nothing worked, no response from AT command,
Please help me I have been working on same problem for 2days.

[![Here all AT commands works well][2]][2]

Add a wiring diagram to your question and a link to the documentation for your Lora module. You appear to have set the baud rate of the Lora module's UART to 9600 but Serial2 of the ESP32 is still at 115200. These have to match. The 9600 is stored in the Lora flash for subsequent connections.

It is a good idea to try using an FTDI device to connect between the LORA module and the PC so you can issue commands through the serial console to LORA as your second picture shows. However,  you appear to connected TX and RX incorrectly. These must be crossed over. TX on one device to RX on the other etc. Experiment with the baud rate on the serial console say 9600 or 115200.

Sorry, i connected it correct, wrong in image, i taken it from other place, i connected tx to rx and rx to tx

The documentation is here: https://reyax.com/products/RYLR998 . Try using the FTDI device connected to the Lora module with the USB cable connected to your PC. Ignore the ESP32 for the moment. Simply issue the command "AT" then  on the serial console and it should give a response "+OK". Start with a baud rate of 115200 on the serial console. If that fails, try down to 9600. The FTDI may not be able to supply enough power for the transmit function but should be enough for the "AT" test.

Yes, it works perfectly when connected to USB and give AT command. How long to wait and how to wait after i give AT command to lora module through ESP32 SoftwareSerial?

I would try issuing the AT command, waiting 1 second for the result to be available then do the following while (Serial2.available())  Serial.print(Serial2.read()); . Try with just the simple "AT" to start with. What baud rate did you use in the serial monitor for your successful tests with the FTDI adapter ?

Please either correct or delete the image in your question with the incorrect FTDI wiring of TX/RX. If you get a successful connection between the LORA and the ESP32 modules, please add an answer to your question with the code that you used. It may help someone else.

I literally gave-up, code is working with Node MCU, i think ESP32 need some setup etc. Thank you all.

I am new to Lora module and ESP32 and only playing around for a week.
I have successfully sent AT commands to RYLR998 module via ESP32 and received messages via other RYLR998 connected to another computer via USB UART serial.  You need use trim() before you send your string to Serial2.(ryltr998)
trim()
[StringObject Function]
Description
Get a version of the String with any leading and trailing whitespace removed. The trim() function modifies the String in place rather than returning a new one.

Syntax
myString.trim()