message:
Question about using millis for alarm conditions - Arduino

I am new to programming in general and to Arduino as well.
I am working on a small project to improve my ability to write complete and kind of useful programming sketches.

I am facing a problem. I am using a few things in my circuit like 7-segment display and relays and several indicating LEDs and a buzzer.

Let's sat that when a condition occurs I want one LED to  blink while everything still works fine and sends data to the display and controls relays, and I solved that with the `millis` function.

But the problem came when I tried to implement the same concept to the buzzer (which in my case I want to buzz for a pre-set amount of time, and then stop, without keeping buzzing all the time which might be too long), without using the `delay` function.

I tried many many code but nothing would work for me so far. Here is the simple code of my sketch. I hope you guys will help me find a solution

```c++
const byte buzzer = 13;  // buzzer_PIN
const byte switch1 = 3;  // PUSH-BUTTON PIN

/* please NOTE:
that the switch in my project will actually represent a condition to start the buzzer alarm, then maybe that condition will not exist, and after that the condition might come back and need the buzzer again
*/

unsigned const int delaytime = 500; // delay time needed between on and off states for the buzzer
unsigned long previousBuzz = 0;     // Variable for millis
unsigned long currentTime = millis();
boolean buzzPreState = true;        // Boolean made to avoid repetition for the buzzer when not needed

void setup() {
  pinMode(buzzer,OUTPUT);
  pinMode(switch1,INPUT_PULLUP);
}

void loop() {
  unsigned long currentTime = millis();
  int switchVal = digitalRead(switch1);

  if (switchVal == LOW && currentTime - previousBuzz > delaytime && buzzPreState == true) {
    previousBuzz = currentTime;
    buzzPreState = false;
    buzzerStart(5);
    buzzPreState = true;
  }
}

void buzzerStart(int repeat) {
  for (byte i=0; i<repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer)); // to switch buzzer ON and OFF alternatively
  }
}
```

body:
You are missing a delay here:

```c++
for (byte i = 0; i < repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer));
}
```

Without the delay, the whole loop terminates so fast that you cannot
hear anything.

Now, if you want non-blocking code, you should instead use the approach
of the Blink Without Delay tutorial:

* have the program remember the current state
* when it's time to switch states (as determined by `millis()`), update
  the current state.

The difficulty is that, whereas the program state in that tutorial is
trivial (either the LED is off or it's on), in your case it is more
complex. In addition to the time of the last toggle, you have to keep
track of:

* whether the buzzer is off or on
* whether it is supposed to be making sound
* a counter for the buzzing cycles.

The approach I would use is to have a counter (let's call it
`buzzer_remaining`) telling how many cycles it still has to complete.
The counter would decrement when the pin goes `LOW`. When it reaches
zero, the buzzing is done. Note that this choice implies that, when the
condition for buzzing becomes true, we will start at the middle of a
buzzing cycle.

Here is a tentative implementation of this approach:

```c++
const uint32_t buzzer_half_period = 500;  // 500 ms in each state
const uint8_t buzzer_count = 5;  // buzz for 5 cycles
uint8_t buzzer_remaining;        // remaining buzzing cycles
uint8_t buzzer_state;            // LOW or HIGH
uint32_t buzzer_last_toggle;     // millis() at last toggle time

void buzzer_start() {

    // Ignore request to start if we are already buzzing.
    if (buzzer_remaining > 0)
        return;

    // Initialize the buzzer state.
    buzzer_remaining = buzzer_count;
    buzzer_state = HIGH;
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = millis();
}

// Call this periodically from loop().
void buzzer_update() {

    // Do nothing if we are not supposed to be buzzing.
    if (buzzer_remaining == 0)
        return;

    // Do nothing if it is too early to switch state.
    uint32_t now = millis();
    if (now - buzzer_last_toggle < buzzer_half_period)
        return;

    // Update the buzzer state.
    if (buzzer_state == LOW) {
        buzzer_state = HIGH;
    } else {
        buzzer_state = LOW;
        buzzer_remaining--;
    }
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = now;
}
```

I resisted the temptation to put all this inside a class. It would be
cleaner, but I think this “plain C” style of programming might be easier
on a newcomer.

Note that calling `buzzer_start()` when the program is already buzzing
has no effect: the request to start the buzzer is ignored. This is not
the only possible choice: one could instead want to reset the counter in
order for the buzzing to last longer. The choice I made is arbitrary,
and I only made it because, in your question, the program requirements
are not fully specified.


sender: user

message:
How to swap byte order

**Background**

I'm reading a 24-bit ADC value into a uint32. Using SPI bus, here's the logic:

    value = SPI.transfer(0);   // read first 8 bits (MSB first)
    value <<= 8;               // shift bits left
    value |= SPI.transfer(0);  // read next 8 bits
    value <<= 8;               // shift bits left
    value |= SPI.transfer(0);  // read final 8 bits

As such I'm left with this ADC reading:

    00000000 11111111 11111111 11111111
             MSB                    LSB

(Ignore the leading zeros for now.)

Now I transfer this value over ethernet like so:

    client.write((const byte*) &value, sizeof(value));

The problem is this:
- The value is stored as MS **bit** first.
- client.write() transmits it LS **byte** first.

I am using NodeRED as a TCP server. So at the other end, I receive the data like this:

    11111111 11111111 11111111 00000000
         LSB          MSB

I understand this is the expected behavior, but I would like to switch the BYTE order around before sending, so that it is read in NodeRed native endianness.

----------

**Question**

Perhaps I should do some bit shifting at the point of reading the ADC, to accommodate the fact that client.write() sends the least significant byte first, like this:

      byte1 = SPI.transfer(0);
      byte2 = SPI.transfer(0);
      byte3 = SPI.transfer(0);
      response = byte3;
      response <<= 8;
      response = byte2;
      response <<= 8;
      response = byte1;

Is this the most efficient way in terms of clock cycles?

Please note that my MCU is a Teensy 4.1, and I'm transferring 10,000 readings per second. I would like to keep the clock cycles for any necessary bitwise operations to a minimum, so that the timing of ADC readings are affected as little as possible.

sender: assistant

body:
You can use an array of `byte` to save the shifts at all. This solution should be the one with the least clock cycles, and with no additional memory usage.

```c
static byte value[4] = { 0 };

    /* ... */

    /* value[0] is still 0. */
    value[1] = SPI.transfer(0);
    value[2] = SPI.transfer(0);
    value[3] = SPI.transfer(0);

    client.write(value, sizeof value);
```

Some notes:

1. Using an array avoids the re-interpretation of a 32 bit variable as a byte array. You read bytes from SPI, and `write()` expects a byte array. This circumvents your endianness issue completely.

1. In the call of `write()` you don't need to cast the address of `value` to `const byte *`, because the `const` is a qualifier _for the called function_. It is not allowed to change the bytes pointed to.

1. Making the array static saves you from zeroing the first byte repeatedly. BTW, it is sufficient to provide the first byte, as all other bytes are zeroed automatically. However, the last bytes will be updated on each transfer.

1. `sizeof` is an operator, not a function. However, it is quite common to use it with a type instead of an object, and then you need parentheses because of the syntax. But it is better to use the respective object, actually you mean that.


message:
Using Random() and Greater Than

Total Arduino noob, I come from a Python "background", though I barely know that, either.

I'm writing a super simple script that will turn on a bulb when the random number generator generates a number greater than 100. Obviously, I have a syntax problem or something: What am I doing wrong? Secondly, How quickly does ```random``` query numbers? Is it possible to slow it down? I don't need my bulb turning on 50 times a second.

Thanks! And please be kind; I know this is Googleable, I just lack the prerequisite knowledge to Google this efficiently.

```
/*

*/
int relayPin = 7;
int randomNumber = random(1001);

void setup() {
  pinMode(relayPin, OUTPUT);

}

void loop() {

if(randomNumber > 100)
  digitalWrite(relayPin, LOW);

else{
   digitalWrite(relayPin, HIGH);}

}```

body:
There are a few things to be discussed in here.

First, the random number generation: in fact, the arduino **does not** generate random numbers. It has a list of numbers on its memory that just "seems" to be random. That's why it's called a pseudo-random number.
So, you need to declare a starting point on this sequence, from which you will get the "random" numbers. This is made with "randomSeed()" in void setup. For example:
```
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point,
                             //in this case, the analogRead value of an unconnected pin
}
```

Next, let's generate our number. The variable can be global (as you declared it outside any function), but **you must declare it with "random()" only inside "void loop"**. Otherwise, its value will be assigned just one time (that's what your code is telling it, to do it once).

Here is what I would do:

```
int relayPin = 7;
long randomNumber; //just declares the variable; it must be type "long"

void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  pinMode(relayPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  randomNumber = random(0, 301);
  //each time the code loops, it assings another value to randomNumber
  //in this case, the number will be between 0 and 300 (301 is the excluded limit)

  if(randomNumber > 100){
    digitalWrite(relayPin, HIGH);
  }
  else{
    digitalWrite(relayPin, LOW);
  }
  delay(500); //half a second delay

}
```

If you want to have more details about how random numbers are generated in the Arduino, visit the Arduino language Reference:
https://www.arduino.cc/reference/en/


message:
1 global variable consuming 19% of memory

I am working on a simple project on talking to the serial monitor, and my only global variable ("int" type, named "incomingByte") is consuming a lot of memory. There is no problem on running the scketch, but I am not satisfied to have it that way.

When I load it, I receive: "Global variables use 390 bytes (19%) of dinamic memory...".
Why is it happening, and how could I fix this?

```
int incomingByte = 0; //for the incoming serial data
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  Serial.begin(9600);
  //waits for serial initialization to send the messages:
  //(Serial) returns false for serial off, and true for serial on. This is inverted with !.
  while(!Serial){
    ;
  }
  //sending instructions:
  Serial.println("Initializing...");
  Serial.println(" ");
  delay(2000);
  Serial.println("Please select an option:");
  Serial.println("1 - greetings");
  Serial.println("2 - random number");
  Serial.println("3 - calculator");
  Serial.println(" ");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0){
    incomingByte = Serial.read(); // Serial.read() returns the first byte of incoming data

    //recognizing the command received:
    if (incomingByte == '1'){
      numberOne();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '2'){
      numberTwo();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '3'){
      numberThree();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
  }
}

void numberOne() {
  Serial.println("Hello, Vitor! Good to see you!");
}

void numberTwo() {
  //sets the random number to be picked between [0, 101[
  long randomNum = random(0, 101);
  Serial.print("Your random number is: ");
  Serial.println(randomNum, DEC);
}

void numberThree(){
  Serial.println("Tool not available yet");
}
```

body:
A few things that count towards the “global variables” that you may not
think of:

* all your literal strings, unless encapsulated within [the `F()`
  macro][F]; you have quite a few of them
* The `Serial` object, including its transmit and receive buffers (157
  bytes on an Uno)
* The [vtable][] for `HardwareSerial` (that's the class `Serial` belongs
  to, 18 bytes)
* The time-keeping variables (9 bytes).

And then, on top of that, there are the actual global variables of your
code, and the static locals which, for the purpose of memory allocation,
are the same as globals. An `int`, for example, takes 2 bytes on
AVR and 4 bytes on most other hardware platforms.

[F]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/#_the_f_macro
[vtable]: https://en.wikipedia.org/wiki/Virtual_method_table

------------------------------------------------------------------------

**Edit**: answering the questions in a comment

> every single time I call `Serial` it will increase the memory
> consumption of the code?

I don't quite understand what you mean by “every time”:

- Every time you add a reference to `Serial` to a sketch, the linker
  will add the `Serial` object to your compiled code, and the program's
  RAM consumption will grow by the size of this object.
- Within a single sketch, whether `Serial` is used once or many times
  makes no difference: the object will be instantiated only once.

> why does the IDE considers everything that uses RAM as a global
> variable?

When it says “global variables” it actually means “statically allocated
data”. It says “global variables” because it is targeted at beginners,
and the authors assume beginners would not understand what static
allocation means. Globals are the simplest form of static allocation.

> is there a difference in consumption between globals and locals?

Yes. Globals get allocated statically, i.e. at compile time. That's why
the IDE can report how much space they will consume. Locals (at least
non-static locals) get allocated and deallocated on the stack, at run
time. Short of running the program in an emulator, it is very hard to
predict how much stack space a program will consume, as this will
usually depend on run-time events.


message:
L298N DC Motor Driver Conundrum

I am trying to control a single DC motor using a L298N DC Motor Driver. I have a 12V motor plugged into Out1 and Out2, a 7.4 volt battery wired to the 12v in and common ground, a m/m common ground going from the arduino grnd to the L298N common ground, and I have IN1 and IN2 connected to digital pins 2 and 3. I am powering the Uno with USB. I am also running a m/m wire from the Uno 5v to the L298N (I shouldn't have to) in order to power the L298N[![enter image description here][1]][1]

[![enter image description here][2]][2]

I am using a basic code to test the motor

        int motor1pin1 = 2;
    int motor1pin2 = 3;

    void setup() {
      // put your setup code here, to run once:
      pinMode(motor1pin1, OUTPUT);
      pinMode(motor1pin2, OUTPUT);

    }

    void loop() {
      // put your main code here, to run repeatedly:
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);

      delay(1000);

      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);

      delay(1000);
    }

If I wire the 7.4v lipo battery directly to the L298N the red led doesn't go on. It only goes on when I run a 5V wire from the Uno to the L298N. Yet still I get no reaction out of the motor. However if I run a ground from the arduino directly to the out1 or out2, the motor turns in that one direction. Anyone have an idea what I am doing wrong?

  [1]: https://i.stack.imgur.com/XtgO7.jpg
  [2]: https://i.stack.imgur.com/Yb3yr.jpg

body:
I don't see any problem in your wiring and code. The only thing that's not exactly optimal is that the voltage provided by the battery is not just high enough. The L298N's supply voltage is supposed to be at least 2.5V above the logic supply voltage (the logic HIGH level to be precise). That would make 7.**5**V - you only have 7.**4**V.

That sounds like a tiny gap, but the battery voltage might drop further under load.

"*run a ground from the arduino directly to the out1 or out2*" - you should not do that as this can create a short circuit, depending on the state of the EN and IN pins.


body:
Assuming you have the ENABLE jumper in place to enable motor control, then you should be able to drive the motor full-speed forwards or backwards without the UNO code at all - just use the +5V and GND lines from the UNO as 'logic level probes'.

According to my logic table a LOW (GND) on L1 and a HIGH (+5v) ON L2 will cause a motor connected to OUT1/2 to rotate one way, and reversing the logic on L1/2 will cause it to rotate in the other - at full speed (full speed being whatever the battery supply voltage can provide).

Once you have the motor(s) turning properly, THEN you can add the complexity of trying to control the speed and direction programmatically.  The code you showed does exactly the same as just using the +5 & GND leads as probes - with a 1 second delay between reversals.

Hope this helps

Frank


message:
Achieving low power with Seeeduino Cortex-M0+ powered from 12V battery

I have Seeeduino Cortex-M0+, which is similar to Arduino Zero, both using Atmel SAMD21 MCU. It is powered from 12V battery directly to 12V PWRIN jack. Current draw for LED blink test is 18mA. I tried two low power libraries:
- https://github.com/rocketscream/Low-Power
- https://github.com/adafruit/Adafruit_SleepyDog

with:
- `LowPower.standby(); delay(5000);`
- `Watchdog.sleep(5000);`

In both cases, the current draw dropped only to 12.7mA, which is still huge. I checked the datasheet of MP1496DJ-LF-2 step-down, switch-mode converter used by this board and its quiescent current is below 1mA, so it doesn't look like the source of high current consumption. I've read posts about Arduino Zero running on 5mA from 12V input in low power. What else can I do in order to get the current closer to 5mA?

I cross-posted at https://electronics.stackexchange.com/questions/607000/achieving-low-power-with-seeeduino-cortex-m0-powered-from-12v-battery

----

I did a few experiments with external DC/DC converters feeding 5V pin on Seeeduino Cortex-M0+ from 12V battery, bypassing its MP1496DJ-LF-2 power stage. Here are the results:

| DC/DC model | sleep current [mA] | LED blink current [mA] |
|-----------------|-------------|--------------------|
|MP1496DJ built-in baseline|12.7|18.0|
|LM2596S generic|8.6|14.8|
|Pololu D24V22F5|5.0|11.2|
|Pololu D24V5F5|3.6|9.3|

body:
As [@devnull at Electronics Stack has answered][1], the quiescent current of 5~10 mA from the LDO could be enough to make up for the lost currents.

I don't have any specific suggestions on code or parts, but I can give you some tips regarding methodology. If you're working on the software side to reduce current consumption, you might be better off eliminating the possibility of hardware imperfections entirely. I'd power the board with 3.3V directly and preferably cut the traces to 5V or other unused circuits. Reduce the current consumption to the lowest possible on software side, and then work on the hardware side. You could be better off with an external LDO or a 12V to 3.3V converter with a low quiescent current to power your board.

From my experience, currents can leak from even the most unexpected circuits. There could be a faulty or crappy capacitor with higher than usual leakage current, resistors in voltage dividers with resistance not high enough drawing a couple of mA in total, or some random transistors we didn't think of drinking 1~ mA per chip. Or combinations of everything above being responsible for only a few hundred uA per part, but totals to a few mA in total. It's best to make a board with the most barebone parts or get one.

  [1]: https://electronics.stackexchange.com/a/607005/172770


message:
M5Stack - confused about I2C bus voltage

I've recently got one of these nice M5-Though devices (basically a water-proof M5-Core2). They have these 4-wire sockets to connect their sensors. The I2C socket has 4 pins for +5V, GND, SDA and SCL. According to the [schematics (bottom of page)][1], the SDA and SCL lines are directly connected to the GPIO pins of the ESP32. That means that most sensors connected to this socket will run the I2C bus at 5V. Even their own sensors [(example)][2] have pull-ups to 5V on the SDA and SCL lines.

Isn't this going to fry the ESP32? Different sources say that it's inputs are _not_ 5V tolerant. So far, I always used the 3.3V line to power external sensors from the ESP32 (or added a level shifter).

  [1]: https://docs.m5stack.com/en/core/tough
  [2]: https://docs.m5stack.com/en/unit/tof

body:
No, it's not going to "fry" the ESP32, and here's why:

Yes, there are pullups to 5V. Those are 4.7K in your example. The IO pins are connected to 3.3V through ESD diodes. That means that any voltage over and above 3.3V plus the forward voltage of those diodes will be "diverted" away from the IO pin through the diode. IO pins have these ESD diodes built in, but this board has extra external ones added to make it more rugged.

These ESD diodes can handle a finite amount of current flowing through them - the internal ones only a small amount, but the external ones much more.

The 5V will only be a low current because it is connected with a resistor. We can even do some maths here.

Assuming the ESD diodes have a 0.3V forward voltage (as is reasonably typical) we can say that the voltage across the diode will be 5V - 3.3V - 0.3V = 1.4V.

With a 4.7K resistor as a pullup the current through the diode will be 1.4V / 4700 = 298 microamps.

That's way below the limit you'd expect of a small internal ESD diode, let alone a larger external one.

The "frying" of an IO pin happens when too much current flows through the ESD diode and it blows, "failing short", causing the IO pin to be locked in either a HIGH or LOW state for the rest of eternity. Since the current is nowhere near the kind of levels needed for that it's not going to even remotely stress the diodes, and the inclusion of external diodes makes it even safer.


message:
Optimizing code for ATtiny10

I'm trying to squeeze code onto an [ATtiny10][1], but I'm just not getting there. I'm using 1060 bytes and only have space for 1024 bytes.

The code is simple enough; I need to read a button pin. If high it needs to pick a random value and that causes one of two random LEDs on the PCB to turn on for two seconds. Is there a way to optimize this code to work on this IC?

```
int buttonState = 0;

void setup() {
    pinMode(3, INPUT);
}

void loop() {
    buttonState = digitalRead(3);
    if (buttonState == HIGH) {
        bool ranNum=random(0,1);
        if(ranNum == 0) {
            digitalWrite(0, HIGH);
        }
        else {
            digitalWrite(1, HIGH);
        }
        delay(2000);
        digitalWrite(1, LOW);
        digitalWrite(2, LOW);
    }
}
```

  [1]: https://www.microchip.com/en-us/product/ATtiny10

body:
Are you sure the pins are correct?

Maybe use a smaller random number generator per https://arduino.stackexchange.com/a/18092/6628 ?

    static uint8_t lfsr = 0x01;
    const byte LFSR_MASK = 0x8e;

    void setup() {
      pinMode(0, OUTPUT);
      pinMode(1, OUTPUT);
      pinMode(3, INPUT);
    }
    void loop() {
      //      int buttonState = digitalRead(3);
      if (digitalRead(3)) {
        if (generateNoise()) {
          digitalWrite(0, HIGH);
        }
        else {
          digitalWrite(1, HIGH);
        }
        //delay(2000)
        //for (int i = 31; i; i--)_delay_us(64516);
        _delay_ms(2000);
        digitalWrite(0, LOW);
        digitalWrite(1, LOW);
      }
    }

    uint8_t generateNoise() {
      // Return 1 bit of noise using a Galois Linear Feedback Shift Register
      // See https://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs

      if (lfsr & 1) {
        lfsr =  (lfsr >> 1) ^ LFSR_MASK ;
        return (1);
      }
      else         {
        lfsr >>= 1;
        return (0);
      }
    }

The RNG didn't help as much as changing the much-disparaged delay.


body:
As I stated in a comment, this device would be too small for me to
consider programming it using an Arduino core. I would rather stick with
the avr-libc and direct port manipulation:

```c
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = _BV(PB0)   // PB0 as output
         | _BV(PB1);  // PB1 as output
    for (;;) {
        loop_until_bit_is_set(PINB, PB3);  // wait for PB3 high
        if (rand() & 1)
            PORTB |= _BV(PB1);  // PB1 high
        else
            PORTB |= _BV(PB0);  // PB0 high
        _delay_ms(2000);
        PORTB &= ~_BV(PB0);     // PB0 low
        PORTB &= ~_BV(PB1);     // PB1 low
    }
}
```

This is plain C, but I expect it to be accepted by the Arduino IDE as a
valid .ino file. I tried compiling it like this:

```shell
avr-gcc -mmcu=attiny10 -Os -Wall -Wextra -DF_CPU=8000000 prog.c -o prog.elf
```

And it resulted in a program that uses 660 bytes of flash. Most of that
is in the implementation of `rand()` and its dependencies
(multiplication and division routines).


body:
If the button is pressed by a human and your clock is high enough (MHz range), you can use a trick and get rid of the RNG.

You can replace it with a free running counter like this:

```c
unsigned char count = 0;

void loop() {

    count += 1;

    buttonState = digitalRead(3);

    if (buttonState == HIGH) {
        if( (count & 1) == 0) {
            digitalWrite(0, HIGH);
        }
        else {
            digitalWrite(1, HIGH);
        }
        delay(2000);
        digitalWrite(1, LOW);
        digitalWrite(2, LOW);
    }
}
```

You have `count` incremented every ⪝10 us (depending on your clock speed, attiny executes one instruction per cycle), so when the user pushes the button, the counter will be sampled.

Note: I assumed `loop()` is all what the microcontroller has to do, and it's constantly called.


body:
An 8-bit chip requires multiple instructions for processing 16 bit. Changing ints to either uint8_t or int8_t will save code.

Depending on compiler optimization, replacing

    if ( (count & 1) == 0) {
        digitalWrite(0, HIGH);
    }
    else {
        digitalWrite(1, HIGH);
    }

with

    digitalWrite((count & 1), HIGH);

could save bytes.


message:
Unexpected character added to char buffer array in serial monitor only when SD card initialized

I'm getting an unexpected extra character added to the serial monitor print line only when I initialize an SD card in the code.

Normal

The code below gives me this expected result in the serial monitor:

**Serial Monitor**
```
23:31:12.745 -> inputString: abc
```

**Code**
```
const int BUF_DIM = 3;
char inputString[BUF_DIM];

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

  inputString[0] = 'a';
  inputString[1] = 'b';
  inputString[2] = 'c';

  Serial.print("inputString: ");
  Serial.println(inputString);
}

void loop() {
}
```

Unexpected Character

However, the serial monitor prints an unexpected extra `M` at the end of `inputString`'s value `abc` when I add initialization of an SD card.

**Serial Monitor**
```
23:24:30.319 -> Initializing SD card...initialization done.
23:24:30.319 -> inputString: abcM
```

**Code**
```
#include <SPI.h>
#include <SD.h>

File myFile;

const int BUF_DIM = 3;

char inputString[BUF_DIM];

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

  //-------------Toggle this block to see the M dissapear-----------
  Serial.print("Initializing SD card...");
  if (!SD.begin(5)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  myFile = SD.open("DATA.TXT");
  //-------------Toggle this block------------

  inputString[0] = 'a';
  inputString[1] = 'b';
  inputString[2] = 'c';

  Serial.print("inputString: ");
  Serial.println(inputString);
}
```

Why is this happening and how can I get the serial monitor to behave as expected with the SD card.

body:
    const int BUF_DIM = 3;

    char inputString[BUF_DIM];
    ...

      inputString[0] = 'a';
      inputString[1] = 'b';
      inputString[2] = 'c';

    ...

      Serial.println(inputString);

You have allowed three characters in your array and indeed put three characters there, however you have not put a "null terminator" there at the end (nor is there room for one) so you will naturally get garbage at the end of the string until the processor happens to find a 0x00 byte.

Put it another way, how does the code know to print three characters and not 20 characters? The answer is that the underlying function (Serial.println in this case) looks for a null-terminator.

You need to read up on how null-terminated strings work.


message:
Is there a definitive reference for the Arduino DUE?

I am looking for a reference document or documentation system that concretely relates at minimum:

- Screen printed pin name/number
- SAM3X8E pin number
- Register number
- Channel number
- Port name

In my case I am looking to change the PWM characteristics of pins 2 and 3 (as named on the physical board). Various forum posts discuss setting registers, register pin mappings, but nothing seems to quite tie up.

On the Arduino as printed, Pins 2 to 13 are listed as PWM pins, 12 in total. By [this][1] page, pins 2 and 3 map to PB25 and PC28 respectively on the SAM3X8E chip. Presumably this suggests Pin 2 is on the 'B' port, and 3 is on the 'C' port. Referencing [this][2] page, the sample code goes through 'all 8' PWM ports and pins, which by the register naming scheme `PIO_ASBR_Pxx`, suggests the pins numbered 16 to 19 are on the B Port, and 21 to 24 are on the 'C' port. Later the PWM ports are again iterated over with the `PWM->PWM_CH_NUM[i]` where `i` runs from 0 to `PWMCH_NUM_NUMBER - 1`, which is suggested as 8 in total.

'Pin 2' on the board then seems to have a mapping to a named pin on the Atmel chip of PB25, somewhere between 21 and 24 on the register name and between 0 and 7 on the channel index. Surely there is a place that attempts to harmonise all of these disparate naming conventions.

**Further Information:**

For instance, PWM/Digital Pin 2 maps to PB25 on the chip, as per the schematic provided by Majenko. PB25 is not a member of the PWM pins as per the chip [datasheet][3]. How am I to understand this?

When referencing the name `PIO_ASBR_19`, this is the 20th bit in the PIO_ASBR register, but how does this bit map onto the port/pin mapping? Then while the datasheet discusses the 'PIO_ASBR' register, since that can relate to at most 32 pins, the datasheet does not expand on how to map the excess pins.

  [1]: https://docs.arduino.cc/hacking/hardware/PinMappingSAM3X
  [2]: https://forum.arduino.cc/t/due-pwm-frequency/435603/5
  [3]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf

body:
The [full pinout][1] is available on arduino.cc in Store and in the Getting started section.

>  For instance, PWM/Digital Pin 2 maps to PB25 on the chip. PB25 is not a member of the PWM pins as per the chip datasheet. How am I to understand this?

The Arduino core uses timers to do PWM on pins without native PWM support.

In [analogWrite source code][2] you can see sections for DAC, PWM and TIMER PWM pins.

The information about pins for Arduino core is in [variant.cpp][3].

  [1]: https://content.arduino.cc/assets/Pinout-Due_latest.pdf
  [2]: https://github.com/arduino/ArduinoCore-sam/blob/790ff2c852bf159787a9966bddee4d9f55352d15/cores/arduino/wiring_analog.c#L280
  [3]: https://github.com/arduino/ArduinoCore-sam/blob/master/variants/arduino_due_x/variant.cpp


message:
Using Arduino to allow continuous servo to go in the opposite direction

For my project I am using 6 continuous servos connected to an Adafruit Servo Shield. To run them I use
`pwm.setPWM(0, 0, 1000)`
and then set a delay to run them for how long i’d like to, then run
`pwm.setPWM(0, 0, 0)`
to stop it.

I would like to run the servo in the opposite direction. How would I do this?

body:
You probably already know that [continuous servos][1] are different to other hobbyist servos in that they rotate freely, and the [PWM signal][2] is used to control speed and direction of rotation.

The specific model of servo you're using is important and you'll need to refer to the datasheet to find out its details. Particulalry the servo's minimum (typically clockwise rotation); mid-point (neutral / no rotation); maximim (usually counter clockwise rotation) PWM pulsewidths. The mid-point is often set by a PWM pulsewidth of 1500 microseconds, but this can vary and it pays to check.

The [library][3] you referenced does implement a setPWM() function as you mentioned, however you'll note that it works in a range of *ticks* from 0 to 4095. The two parameter values set when to turn the PWM pulse on and off expressed as values from 0 to 4095. To use this function you'll need to map these parameters to produce the PWM signal the servo is expecting.

I recommend an alternative, using the **writeMicroseconds()** function of the same library, which accepts a value in microseconds for which the PWM signal will be high. You'll be able to obtain these directly from the datasheet.

In your question you mention using a PWM of approximately 25% duty cycle (1000/4095) for ON. This is likely much longer than the desired maximum for your servo which if it is 2000 microseconds, might need a value something like 430 (/4095). Similarly you mentioned a zero pulse to achieve a stop. I think this library uses zero as a special case for no PWM pulse. You said this generates a stop condition for your servos, but finding the neutral value may be better.

Rather than figuring out the maths for setPWM() to turn on and off the PWM pulse, the writeMicroseconds() function may be easier.

You'll need to check datasheets for your servos but a value of 1500 microseconds should be near neutral / no rotation. Decreasing values less than this should generate increasing speed clockwise. Increasing values greater than neutral should generate increasing speed counter clockwise.

  [1]: https://en.wikipedia.org/wiki/Servo_(radio_control)#Continuous-rotation_servos
  [2]: https://en.wikipedia.org/wiki/Servo_control
  [3]: https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/library-reference
  [4]: https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/using-the-adafruit-library
  [5]: https://en.wikipedia.org/wiki/Straw_man_proposal


message:
Trying to understand the bottleneck of sensor sampling rate

Lets say I have a sensor connected to Arduino Uno Rev3's I2C Bus. I am reading the sensor output and using Serial.print() to send the sensor reading back to a my laptop.

I am trying to understand the bottlenecks that limits the sensor sampling rate received at the laptop.

The sampling rate of the sensor depends on many factors. Lets assume sensors sampling rate is not limited. That would mean I am limited by how much data each intermedia bus can carry before it reaches the laptop. For example, I am limited by I2C bus atmega328p is using to read the sensor data. I am also limited by the UART bus atmega16u2 is using to send the data to my laptop. Am I correct so far? Also, on what bus atmega328p and atmega16u2 are connected over?

body:
> Also, on what bus atmega328p and atmega16u2 are connected over?

See:

<https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf>

They are connected by TxD and RxD.

Without seeing your code (hint) it is extremely difficult to say. Perhaps a faster baud rate would help.


body:
If there had been a specific scenario you were considering, it might help to share. There's quite a lot to think about with just theoretical assumptions.

> That would mean I am limited by how much data each intermedia bus can carry before it reaches the laptop

Yes, mostly yes. The bandwidth of the entire transmission interface which includes the I2C interface, ATMEGA328P, connection to ATMEGA16U2, and the USB interface would account for the theoretical max sampling rate of the sensor.

For some cases, you may need to consider the latency as well as the bandwidth of the transmission media, which would include the I2C interface, ATMEGA328P, ATMEGA16U2, and the USB interface. The sensor may require some calculations which may result in some delay. The I2C interface or the UART interface could introduce some delay too, especially if it's driven by bit-banging(although probably not with 328P).

Also from 328P's perspective here, it has to receive data from the sensor, make calculations from the incoming raw data if needed, and send over the UART interface to the 16U2. Most of these processes will happen step by step and if the combined processing time takes longer than the delay between each sample coming from the sensor, the 328P itself could theoretically be a bottleneck too.


message:
how accurate is the calculation in stm32?

I have a project plan in which there are calculations that require high precision, which later will have calculations with numbers after commas such as 245.5431657288. from some of the information that I read to make the project a success it must use 32 bytes, initially I wanted to use arduino due, but for some reasons I was more interested in using STM32 but my knowledge of STM32 is not much, especially in terms of the level of precision calculation, therefore I ask is STM32 suitable for my project? I hope my question can be understood, thank you.

body:
The hardware makes no difference to the accuracy of calculations. That is purely down to the software - whether you use single or double precision floats, whether the compiler flags disable double precision to save space (as some 8 bit configurations do), etc.

The choice of hardware only affects the efficiency of the processing at different precisions, such as if there is an FPU, or what precision the FPU can operate at (using precisions outside the range of the FPU will only affect speed not precision).

Both the stm32 and due are ARM based MCUs, so any differences will be down to what additions there are in any specific chip (such as FPU).


message:
How do I debounce multiple external interrupt buttons?

I have an Arduino sleeping most of the time to save power and there are two buttons attached to different interrupt pins that run different functions.  These functions are different from each other, but both have to run long blocking code.  I don't want the button bouncing (or even deliberately being pressed multiple times during the blocking code) to [queue][1] up multiple runnings of the interrupt function.  I also don't want the sleep period to be short because I'm trying to keep if off as much as possible to save power.  I don't want to have to wait 8 seconds after a button press before the button's action happens.  As such, I would think flags or polling the pins from the main loop are not the way to handle this because of power inefficiency and long latency between button press and action.  Should I have each ISR detached its own interrupt pin until its action is complete and then reattach?

    const int buttonA = 6;
    const int buttonB =  10;

    void setup() {
      pinMode(buttonA, INPUT_PULLUP);
      pinMode(buttonA, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
      attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
    }

    void loop() {
      sleep_function();  //takes 8 seconds
    }

    void actionA(){
      //some blocking code that takes 2 seconds, but that I want to run immediately upon button press
    }

    void actionB(){
      //some blocking code that takes 10 seconds, but that I want to run immediately upon button press
    }

  [1]: http://www.gammon.com.au/interrupts

body:
Just set a flag in the interrupt, and run your code in the loop

    const int buttonA = 6;
    const int buttonB =  10;
    volatile byte flagA = 0;
    volatile byte flagB = 0;

    void setup() {
      pinMode(buttonA, INPUT_PULLUP);
      pinMode(buttonA, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
      attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
    }

    void loop() {
      if(flagA){
        //some blocking code that takes 2 seconds, but that I want to run immediately upon button press
        flagA = 0;
      }
      if(flagB){
        //some blocking code that takes 10 seconds, but that I want to run immediately upon button press
        flagB = 0;
      }
      sleep_function();  //takes 8 seconds
    }

    void actionA(){
       flagA = 1;
    }

    void actionB(){
       flagB = 1;
    }


message:
Send batch info to com port?

I'm trying yo get a .bat file to send my cpu data to the com port my arduino is on. I've tried multiple google results (including one from this site) and everything I found will just... erase all the variable tied to the com port. The arduino is hooked up to an lcd (not really because arduino microview, but basically that) which displays the variables I want and works as expected when I put the data into the serial monitor manually, but when I run anything that's supposed to send the info they all go blank when I have nothing in my sketch that clears them.

The file is getting the data how it should. If I run this

`wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature`

then I get the temperature as normal. But If I try to send that to the com port...

`wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature > COM3`

The arduino reads whatever it's getting as literally nothing and blanks the variables.

body:
As Edgar has noted in the comments the Arduino resets every time you open the serial port.

Every time you perform a redirect the serial port is opened afresh, which resets the Arduino into the bootloader. There is then a brief delay while the bootloader looks for suitable communication for uploading new code, and then your existing program gets started afresh.

Coupled with that is the problem of baud rate: you need to ensure that the serial port is configured for the same baud rate as your program is expecting.

All together that means that a simple redirect like you are using is really not the best way of communicating with an Arduino. Instead you will need to write a proper program that opens the serial port, waits for the Arduino to reset, then starts periodically probing for and sending the information that you need it to.

Python and PySerial is a common choice for beginners as is easy to get started with and has plenty of examples.


message:
Failure to recognize the Arduino Mega2560 R2 board by the computer

I am using an Arduino mega2560 R3 My Arduino port is not recognized by the computer.led on is green,leds Tx and Rx are yellow and led L is blinking constantly(According to the figure).I used an Arduino Uno to upgrade the Arduino Mega bootloader(According to the figure)  but the problem with the Arduino Mega board was not resolved.What do you think is the solution? Is the mega board burnt?[![enter image description here][1]][1]m[![my mega2560][2]][2]

I tested the communication cable, there was no problem.I also tested a UNO board that had no problems and was programmed by computer.

[1]: https://i.stack.imgur.com/uuGTG.png
  [2]: https://i.stack.imgur.com/7Zv0b.png

body:
The "L" LED is controlled by the main MCU. This is blinking because the bootloader is running fine. There is nothing (superficially) wrong with the main MCU.

The TX ad RX LEDs are controlled by the ATMega16U2 (or 8U2 or 32U2 depending on the board version) chip which forms the USB interface bridge. These being solidly on are a bad sign. Normally they would be off until some form of communication between the PC and the main MCU (via the 16U2) takes place. This is not happening. If it were a faulty cable then the LEDs would be off. If the PC were not configuring the port the LEDs would be off. But they're on. Therefore the fault is most likely with the 16U2 itself.

Either the chip has been physically damaged (maybe through overvoltage or other misuse) or it has "forgotten" its firmware, either again through misuse or having the firmware overwritten with something else (which can only happen if you specifically perform such an action through the programming header for that chip).

The first step of diagnosis is to try and communicate with that chip through the 6 pin header adjacent to it. You can do this in the same way as you do for programming the bootloader on the main MCU, but instead of programming a bootloader you program the 16U2's firmware (IIRC it's included with the IDE or the AVR core somewhere).

If that is successful and the LEDs start working correctly and the board starts to function again then it's cured. If not, then chances are the chip is dead.

If the chip is dead does that mean the board is dead? Not necessarily, no. It depends on how the board died. If only the 16U2 is dead and the main MCU is fine you can still use it, just not through the USB connection.  You could either use the TX/RX pins and your own external USB to UART interface to replace the 16U2 or program it through the ICSP (SPI) header using another Arduino or a dedicated USB programming dongle. It's less convenient, but means you can still use the board.


message:
I can't get my Micro Pro to bootloader mode anymore

It's important to start by saying that this micro was working perfectly, and the keyboard I built with it was great. Then this happened:

While using the QMK Toolbox I tried to upload an oversized .hex file, and since it was taking too long, I hit the reset button. Clearly uploading an oversized hex file was the problem here.

Now the pro micro won't respond to anything. The green LDE lights up, but windows won't recognize it. I tried clicking the reset button and grounding the reset pin, and nothing works. I even tried the double tap on the reset key, or the tap and hold, nothing.

Have I totally broken the micro somehow? Can't I hard-reset it?

body:
Alright, just answering my own question in case someone comes along in the future:

The problem in my case, as @Majenko mentions in the comments, was the bootloader. In my case, there was no way around it, I had to re upload it with a ISP.
I got another Arduino Pro Micro and using the wiring from this answer: https://arduino.stackexchange.com/questions/21166/trying-to-verify-that-arduino-pro-micro-isp-is-working and following this tutorial: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP

I managed to get it working.

Notes:
1. I did not have to change anything on the code for the ISP sketch.
2. Careful with the picture from the first answer, the comments show an issue with the wiring you need to take into account.

After that, the "Burn bootloader" action worked like a charm.


message:
Why is the Adafruit splashscreen logo not displayed properly?

I'm working with a 128x64 Oled display. I have just installed the Adafruit library and I'm running some sample codes. I have not modified the sample code in anyway yet just testing if the oled display is working but I've noticed that the splashscreen logo only shows the top half of the image.

How can I fix this?

[![Splashscreen][1]][1]

  [1]: https://i.stack.imgur.com/jvUxk.jpg

body:
<s>I'm unable to test this now, but here goes:</s>
Turns out I *did* have the ability to test it (found an extra display module) and this does indeed explain the problem. The only other change I needed to make to your code in order to replicate the problem was change the display's I2C address to `0x3C`. Adafruit GFX Library v1.10.13 and Adafruit SSD1306 version v2.5.1.

---

From comments on the question:
> I added `#define SSD1306_LCDHEIGHT 64` before line #53 to remove the
> compilation error

Yeah, you can't do that. Under the old method of defining the screen dimensions, you are intended to modify the [header][1] itself:

```c++
// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).
```

You can see by default it is using a screen with dimensions 128x32. [Later in the header][2] this is used to set `SSD1306_LCDHEIGHT` to `32` in the header.
```c++
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
#endif
```

What you have done in your code is **re**define `SSD1306_LCDHEIGHT` to `64` from the point where you issued the `#define` downward, which *only affects the code compiled in your sketch*.

Meanwhile, [over in Adafruit_SSD1306.cpp][3], `SSD1306_LCDHEIGHT` is *still* `32`, because this file is compiled independently of your .ino and is unaware of your own re`#define`.  In other words, part of the code you've put into your Arduino thinks it has 32 lines and part of it thinks it has 64 lines.

---

So, the solution would be get rid of the `#define` that you inserted into the sketch and to modify header to read:

```c++
#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
//#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
```

Or to use the new method of supplying the dimensions by way of the constructor as is done in [newer examples][4]:

```c++
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
/// ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
```

The Adafruit SSD1306 version v2.5.1's ssd1306_128x64_i2c.ino example that uses this newer method of passing screen dimensions into the `Adafruit_SSD1306` constructor and compiled and ran without modification in testing here.

  [1]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.h#L27
  [2]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.h#L116
  [3]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.cpp#L330
  [4]: https://github.com/adafruit/Adafruit_SSD1306/blob/f8b3aeb/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino#L26


message:
Uploading to an external Atmega328P with a clone UNO R3 with soldered chip

As a complete newbie, after much looking for the best bargain, I ended up buying one of these UNO R3 clones, without realizing it had the chip soldered on the board. It looks like this:

[![enter image description here][1]][1]

It works OK for development, but after that I want to get rid of the Arduino board and just use the Atmega with the minimum set of components on the final project.

As far as I understand, two tasks need to be acomplished here:

 1. Program the bootloader on the spare Atmega328P
 2. Upload code to the spare Atmega328P

Acording to [this tutorial][2], I should be able to accomplish 1) with my "Arduino" board and a breadboard, but after that I couldn't upload any programs to that same Atme328P as the original microcontroller from the "UNO R3" should be removed and that can't be done on rip off.

Does anybody know of a method to accomplish 2) with my current setup? I also have one of those USB-to-serial converter (FTDI) boards. According to [this other tutorial][3] that can be done using it and some components, but I'd like to avoid that if, let's say, there's some trick like disabling the RX and TX line from the soldered chip by software so the external chip ones could be used instead...

  [1]: https://i.stack.imgur.com/IdzR0.jpg
  [2]: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoToBreadboard
  [3]: https://www.arduino.cc/en/Main/Standalone?_gl=1*1bzf759*_ga*MjAxODYzNDY3My4xNjQ0NDQ2MTEy*_ga_NEXN8H46L5*MTY0NDU4MzM3My4zLjEuMTY0NDU4MzU2OS4w

body:
Thanks anyone for the comments. Very clarifying! So, all in all, the replies to my question and other doubts are:

 1. There's no need to remove the existing MCU; it's enough to connect it's RESET pin to ground (GND), so it prevents from messing with the external Atmega, and
 2. There's no need to have a bootloader on the "final" product, as it's only a convenience when developing which allows to upload the program easily.


message:
Erratic behaviour using a DUE with the Microchip 24FC64 EEPROM chip?

I am attempting to read and write from/to an EEPROM chip, and have got access to [this][1] 64 kbit device.

It appears I can write to the device and read from it, but there appears to be some strangeness around addressing the written data for later writing.

I am using [this][2] page as a reference for my code, and getting some strange results. For starters, the 64 kbit is in fact 8k, and I was able to write to the 10000 the byte and read from it (though I suspect it rolled over on the memory address).

The strangeness was when I attempted to write two adjacent bytes to two adjacent addresses. The subsequent read of the two addresses read the second byte both times. It was as if the location pointer was stuck on the last read.

when I reset my code, I can read the previously written addresses, confirming they are not just stuck in memory.

Similarly when I write an array of bytes to an address, I can read back the bytes, but if I change the read pointer to read again, the bytes are returned all the same, until the pointer goes a significant distance away from the read address (over say 50 bytes). At this point the return data is all 255.

Finally if I read many bytes, requesting say 50, the most I get back is 32 bytes.

Say I write:

    [60, 61, 62, 63, 64, 65] to position 8000 in memory

if I attempt to read from the address or addresses near it or anywhere else, I either get the exact bytes I wrote at whatever position I request, or I get nothing (all 255).

I have managed to read old data from other locations from previous compiles, so the data is for sure in the chip, just accessing it seems uncertain.

Some read results:

    7000: [255, 255, ..., 255]
    7500: [255, 255, ..., 255]
    7980: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8040: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    7960: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8060: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    7940: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]
    8500: [255, 255, ..., 255]
    8150: [60, 61, 62, 63, 64, 65, 255, 255, ..., 255]

Code:

      const int memoryI2CAddress = 0x50;

      void Initialise() {
        Wire.begin();
        Test();
      }

      void Test() {
        unsigned int baseAddress = 8000;
        byte data[6] = {64, 65, 66, 66, 65, 61};
        Wire.beginTransmission(memoryI2CAddress);
        Wire.write((byte)(baseAddress >> 8));
        Wire.write((byte)(baseAddress && 0xFF));
        Wire.write(data, 6);
        Wire.endTransmission();
        delay(10);

        ReadTest(7000);
        ReadTest(7500);
        ReadTest(7980);
        ReadTest(8040);
        ReadTest(7960);
        ReadTest(8060);
        ReadTest(7940);
        ReadTest(8000);
        ReadTest(8500);
        ReadTest(8150);
      }

      void ReadTest(unsigned int baseAddress) {
        Serial.println(baseAddress);
        Wire.beginTransmission(memoryI2CAddress);
        Wire.write((byte)(baseAddress >> 8));
        Wire.write((byte)(baseAddress && 0xFF));
        Wire.endTransmission();

        int count = Wire.requestFrom(memoryI2CAddress, 50);
        Serial.print(count);
        while (Wire.available()) { Serial.println(Wire.read()); }
      }

**Update:**

The data addressing seems to be sensitive to the first address byte and not the second. When inverting the order of the most and least significant bytes and comparing to the MSB change with the address, I can reliably return the byte at the correct address. This appears to explain why I either get the same data for some addresses and not others, where the MSByte is or is not changing.

So why is the system insensitive to the least significant byte in the address?

  [1]: https://4donline.ihs.com/images/VipMasterIC/IC/MCHP/MCHPS04099/MCHPS04099-1.pdf?hkey=52A5661711E402568146F3353EA87419
  [2]: https://www.hobbytronics.co.uk/arduino-external-eeprom

body:
Sadly the simple answer is in how the least significant byte was being calculated, and the boolean operator generating it.

    Wire.write((byte)(baseAddress && 0xFF));

should have been

    Wire.write((byte)(baseAddress & 0xFF));

Tough lesson to check my assumptions!


message:
Arduino Uno R3 not recognized by Arduino IDE on Ubuntu 21.04

Now I've been pulling my hair for two days over this one. I've tried everything. I've turned every stone, looked at every search result, and every Arduino Forums thread.

The problem is that Arduino IDE does not recognize the Arduino when connected to the PC, thus I can't upload compiled sketches. As usual, the serial port dropdown menu is greyed-out.

Things I have tried so far:
 1. Tried a different USB cable. Same results.
 2. Tried it on a Mac. It works flawlessly with different sketches.
 3. Looked at dmesg logs for Arduino when connecting. It connects to the PC successfully.
 4. Created a custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyACMX.
 5. Modified the custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyUSBX (since for some reason IDE was looking for ttyUSB0 first).
 6. Tried Arduino IDE from snap, apt, and from arduino.cc. All of them work the same.
 7. Tried different versions of AVR board packages from the Boards Manager, none of them work at all.
 8. Tried a NodeMCU (ESP8266), it works flawlessly.
 9. Tried Arduino Due, it works flawlessly.
 10. Added myself to dialout, uucp, and tty groups. Nothing changed.
 11. Changed permissions to a+rwx for all possible Arduino device file nodes.
 12. Changed group ownership to dialout, uucp, and tty for all possible Arduino device file nodes.
 13. Tried running Arduino IDEs as root. Nothing changed.
 14. Installed different firmware and libraries for linux (ex. libserialport0)
 15. Patched the apt version of Aruino IDE with patchelf.
 16. Updated.
 17. Rebooted.

"But hey man, why don't you just use the Mac to compile and upload the sketch, or any other MCU for that matter?" - Because I need to get output from my main PC and delegate it via serial to the Arduino. And Arduino Due is too clunky. And NodeMCU has disputable support for FastLED.

If any of you crazy mfs has an idea on how to solve this, I owe you a beer.

body:
I have experienced that with several new installs of the Linux OS.  Try this:

Linux does not see board Run:

Type 'groups', is 'dialout' there ?

sudo usermod -a -G tty yourUserName

sudo usermod -a -G dialout yourUserName

Log off and log on again for the changes to take effect.
https://playground.arduino.cc/Linux/All/#Permission
sudo ln -s /usr/bin/python3 /usr/bin/python


body:
After upgrading to Ubuntu 22.04 from 20.10, I could no longer upload anything to Arduino UNO boards. Issue was, the correct port was not listed in the Arduino IDE. All I had available as a port was ttyS0. It won't work with USB boards. I am using Arduino IDE 1.8.19, but I believe this is irrelevant to the issue.

After checking the logs :

    sudo dmesg

I got this output:

    usb 4-2: Product: USB2.0-Serial
    ch341 4-2:1.0: ch341-uart converter detected
    usb 4-2: ch341-uart converter now attached to ttyUSB0
    input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input27
    usb 4-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
    ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
    ch341 4-2:1.0: device disconnected

So, my Arduino UNO boards all seem to be recognized as some braille tty device (!). Then braille support tries to establish dialog with the UNO board. This of course fails, resulting in a disconnection of the UNO board, causing removal of device /dev/ttyUSB0. This is the reason why it does not show up in the IDE.

The quick fix is to simply remove braille tty display devices support if you don't need it.

    sudo apt remove -y brltty

This worked for me. Hopefully it works for you too.

The issue might be related to some udev rule installed with the package brltty. If I am not mistaken, udev rules are processed in alphabetical order. So it could be that some braille udev rule matches in first, causing the above mentioned scenario.


message:
Connecting Common-Anode Seven Segment Display to Shift Register

I recently wired up the following ill-advised circuit: [![A common-anode display is wired with its cathodes connected directly to an LED connected to ground.][1]][1]

  [1]: https://i.stack.imgur.com/vvuUo.png

A common-anode display is wired with its cathodes connected directly to LEDs connected to ground. But the strange thing is that it worked exactly as intended: when an LED turned on, the corresponding segment turned off.

My first question is, why didn't it burn out all the LEDs (plus maybe my microprocessor)? 3.3V should be passing directly from the chip, through the 7-Segment and the LED, and into the ground rail. One page on the chip's website (https://www.pjrc.com/teensy/techspecs.html) says it emits a max of 9mA, but that's just a warning about their tolerances, and the pins don't actually throttle output, right? But if all that's true, why is nothing fried? (note that the real circuit is doubled up from what you see in the diagram, using daisy-chained shift registers. I realized after drawing it that that might make a difference, since the current would be split 14 ways instead of 7).

My other question is, I added a resistor at the input of the 7-Segment to limit current, and the circuit _still_ works as originally intended. How is that possible? If a segment is being lit up, that means there's current passing through it, but once on the other side, it should be going directly into the ground via the standalone LED, not "swimming upstream" through a resistor to reach ground via the shift register. Multimeter readings at the cathodes of the 7-Segment are emitting 2V and 0.3 mA. If 0.3mA are insufficient to light up the standalone LEDs, why do they suffice to light up the internal LEDs of the 7-Segment? (and as I recall, they weren't turning on when it was running with no resistance, either.)

Finally, all this has made me wonder, if the digitalWrite pins are capable of emitting 3.3V, what's the point of having a 3.3V pin?

body:
What you are experiencing here is the forward voltage of diodes. When a diode (here you have light emitting diodes, so LEDs) is places in the forward direction in a circuit, it will only conduct when a certain threshold voltage is reached. This voltage is called forward voltage and is dependent on the individual diode (you can find this info in the diodes datasheet) and on other factors like the temperature. To visualize this you can look at a diodes characteristics curve (plotting current against voltage):

[![diode characteristics curve][1]][1]

I got this image from the [German wikipedia article on diodes][2]. As you can see the current stays minimal until the voltage gets in the range of 0.7V. Then the current rises exponentially.

You yourself measured the forward voltage of the 7-Segment LED. You measured 2V between ground and the LED cathode. With 3.3V power you get a forward voltage of 1.3V.

**What's happening?** Your other LEDs likely have a higher forward voltage, so that the remaining 2V from the 7 Segment LEDs aren't enough to light them. There might be flowing a small current on the path through both types of LEDs, but it will be very small and cannot burn anything. So that path isn't as favorable for the current as you thought. Then taking into account that the shift register pulls its output to either ground or 3.3V it gets clear, that the shift register still provides the easiest current path.

---

> If 0.3mA are insufficient to light up the standalone LEDs, why do they suffice to light up the internal LEDs of the 7-Segment?

I'm not very sure about that value. Typical LEDs need current in the range of  maybe 5mA. For your LEDs we cannot definitely state it (since we don't know what LEDs you have), but 0.3mA seems to low for me. How did you measure it?

> One page on the chip's website (https://www.pjrc.com/teensy/techspecs.html) says it emits a max of 9mA, but that's just a warning about their tolerances, and the pins don't actually throttle output, right?

That's only the current range for the digital outputs of the Teensy. Each digital pin has a driver hardware incorporated in the microcontroller. This hardware can only withstand a certain amount of current, until it fails. And it might fail short (shorting to either 3.3V or ground) or disconnected. When you drive the pin near and over its max ratings the voltage will dip on it, since some of the voltage gets lost on the driver components, which are loaded with more current than they were made for. The internal driver can then be killed by the power dissipation in it (voltage lost on the driver multiplied by the current gives you the waste power, which is dissipated as heat there, until something gets fried).

> if the digitalWrite pins are capable of emitting 3.3V, what's the point of having a 3.3V pin?

As mentioned the digital output pins can only provide low current. They are meant for doing digital signaling, not for powering devices. The current is enough to drive a single small LED, but not enough to power a motor or other current hungry devices.

The 3.3V pin is not controlled by anything. It is directly connected to the power supply of the whole board. When you power the Teensy via USB it gets 5V from it. A voltage converter regulates that down to 3.3V and feeds it to the Teensys microcontroller to power it and also to the 3.3V pin. In fact you can also use it to connect your own regulated 3.3V power supply and thus power the Teensy through the 3.3V pin.

  [1]: https://i.stack.imgur.com/U3mK6.png
  [2]: https://de.wikipedia.org/wiki/Diode


message:
Where am I going wrong in modifying Timer0 and the ISR interrupts in this example?

(Arduino) Hello I don't know where I am going wrong here, please advise.

In the end I want to step a bipolar motor, HIGH/LOW, using Timer0 with OCR0A and OCR0B interrupts to adjust the motors step interval and duty cycle. Eventually I would like to do the same thing with a second motor and Timer2.

The idea is that the interrupt at OCR0A triggers step LOW and the interrupt at OCR0B triggers step HIGH. This breaks down into the TCNT count from 0 to OCR0B is the LOW phase and TCNT count from OCR0B to OCR0A is the HIGH phase. Both phases together make up the motor step interval which would be between TCNT0=0 and OCR0A ISR Clear. The duty cycle is determined by value between OCR0B and OCR0A, the duration of the HIGH phase.

My first test was to use Serial.println() to return "LOW" or "HIGH" from the corresponding ISRs to the computer to see if the step sequence is in the correct AB-AB pattern. It is not. The step sequence starts out correctly but after 7(seven) OCR0B ISR interrupts in sequence the OCR0B ISR ceases to repeat while the ISR for OCR0A prints repeatedly. The following is the code:

     ISR(TIMER0_COMPA_vect) { Serial.println("HIGH");} //end ISR COMPA//

     ISR(TIMER0_COMPB_vect) { Serial.println("LOW"); } //end ISR COMPB//

     int long  SPEED_A  = 200; // OCR0B->OCR0A is HIGH PHASE // trigger LOW  // clear to 0 //

     int long  SPEED_B  = 150; // 0->OCR0B is LOW PHASE      // trigger HIGH

       void setup()
       {
          noInterrupts();             // disable interrupts

          OCR0A   = SPEED_A;          // interrupt A compare to TCNT0 value each tick // 0-255

          OCR0B   = SPEED_B;          // interrupt B compare to TCNT0 value each tick // 0-255

          TCCR0A  |= ( 1 << COM0A1);  // clear counter on match // OCR0A

          TIMSK0  |= ( 1 << OCIE0A);  // enable timer compare interrupt A

          TIMSK0  |= ( 1 << OCIE0B);  // enable timer compare interrupt B

          interrupts();               // enable interrupts

          Serial.begin(9600);         // serial

       }  //END setup///

     void loop() { } //END loop//

The Serial return is as follows:

LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
LOW
HIGH
HIGH
HIGH
HIGH
...

Why does the ISR for OCR0B stop executing?

body:
Don't do serial prints inside an ISR. Ever. They require interrupts to work, and inside the ISR interrupts are off. For a while the attempts to print will fill up a buffer which is emptied by another ISR, however when that buffer fills the Serial.print will block. And if it blocks inside an ISR waiting for an interrupt it will block forever. Thus it stops printing.

As Jstola suggested in a comment under the question, turn an LED on and off, or something like that.

I can't explain your 7 prints perfectly, but printing HIGH and LOW repeatedly, with their corresponding carriage-return/linefeeds, would, after 7 turns (7 x 11 = 77), pretty-much fill up the serial buffer which is 64 bytes.

So, you are sending around 77 bytes, some would have "escaped" before the buffer filled up, and when you filled it with 64 bytes, it stops.

Your results would change slightly if you made the baud rate higher, say 115200 baud, which I always use, but still, you should not print inside an ISR.


message:
failed log in attempts on softAP

I would like to setup an access point using the esp32 that logs any/failed access attempts

i have looked through some source files, and came across esp_event.h, which seems to allow registering an event handler, i wonder if this could be used to do the logging.

    #include <WiFi.h>

    const char* ssid     = "tmp-AP";
    const char* password = "123456789";

    static void all_event_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data){

        Serial.println("all_event_handler");

    }

    void setup() {

      delay(3000);
      Serial.begin(9600);
      Serial.println("test started...");

      auto result = esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, all_event_handler,NULL);

      Serial.print("result : ");
      Serial.printf("result : %d - 0xx\n",result,result);

      Serial.println("Setting up AP ...");
      WiFi.softAP(ssid, password);

      IPAddress IP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(IP);

    }

    void loop(){
    }

the code compiles

 esp_event_handler_register returns 259 for me, the handler is never called

i have cobbled together this code from :

[Event Loop Library][1]

[arduino-esp32/libraries/WiFi/src/][2]

[default_event_loop][3]

i guess i would like to hook into at least NOT_AUTHED,  802_1X_AUTH_FAILED  from

 [WiFi Driver][4]

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_event.html
  [2]: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/src
  [3]: https://github.com/espressif/esp-idf/blob/20847eeb96c486629a678d6ffbe73670013fb771/examples/system/esp_event/default_event_loop/main/main.c
  [4]: https://demo-dijiudu.readthedocs.io/en/latest/api-guides/wifi.html#esp32-wi-fi-soft-ap-general-scenario

body:
259 == `ESP_ERR_INVALID_STATE` according to [this][1]. Your error likely came from here:

    esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
                                                    int32_t event_id,
                                                    esp_event_handler_instance_t context)
    {
        if (s_default_loop == NULL) {
            return ESP_ERR_INVALID_STATE;
        }
    ...

You're perhaps calling the function too early, before a default event loop even exists. I'm guessing that usually this event loop gets created by the WiFi libs when you start WiFi-related calls -- such as [here][2]:

    static bool _start_network_event_task(){
    ...
    esp_err_t err = esp_event_loop_create_default();

If you try moving your registration to after the `softAP()` call, you risk missing events, depending on how synchronous that call is. So you can try creating the event loop yourself explicitly:

    // Create the default event loop
    ESP_ERROR_CHECK(esp_event_loop_create_default());

...before you register the handler. That should be harmless -- anything else that tries to create this same loop later *should* cleanly handle the returned error that indicates the loop already exists.

**EDIT**

So I tried out your sketch and met the same issue. After spending more time than should've been needed, the issue boils down to one of compatibility.

My ESP32-Arduino core 1.0.6 (and likely yours as well) is based on the ESP-IDF/SDK 3.3.5 release -- a release that contains some pretty old code, despite being the latest that the Arduino Boards Manager has to offer. So, `esp_event_loop_init()` looked like [this][3]:

    esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
    {
        if (s_event_init_flag) {
            return ESP_FAIL;
        }
        s_event_handler_cb = cb;
        s_event_ctx = ctx;
        s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));

        xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask",
                ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);

        s_event_init_flag = true;
        return ESP_OK;
    }

and WiFiGeneric.cpp looked like [this][4]:

    static bool _start_network_event_task(){
    ...
        return esp_event_loop_init(&_network_event_cb, NULL) == ESP_OK;

As you can see, there's no mention of the default loop being created, which is why you get *INVALID_STATE for any registrations.

Even if you went and created the default loop yourself, you'd receive no events in your handler because the system events, as of this IDF version, aren't passing through the official `esp_event` loop pipeline -- `esp_event_loop_init()` just creates a Task and this task receives events from some external caller as they happen, forwarding them to one application task alone.

If you still want to receive events through this way, you'd need to download/install the very latest ESP32 Arduino core from Github, rather than through the Boards Manager. This core should have a more recent version of the SDK, along with a compatible Arduino HAL.

Alternatively, you can just use the more public API, `WiFi.onEvent()`. It should cover all the events you're interested in, as well as include any relevant reason codes.

**EDIT 2**

Yeah, it turns out the `SYSTEM_EVENT_AP_STADISCONNECTED` reason codes you're looking for, just aren't exposed by the Espressif API, at any layer of the stack. Nor is there any other event which would give you this info AFAICT. You can try raising an issue on the ESP-IDF Github page to see if they can help you there, but chances aren't looking great.

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/error-codes.html
  [2]: https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.cpp
  [3]: https://github.com/espressif/esp-idf/blob/85c43024cb133cd81d3e3a95c1da49d51291d306/components/esp32/event_loop.c#L111
  [4]: https://github.com/espressif/arduino-esp32/blob/46d5afb17fb91965632dc5fef237117e1fe947fc/libraries/WiFi/src/WiFiGeneric.cpp#L96


message:
How fast are IR sensors with Arduino

For an industrial project which requires detecting whether some text is printed on the cable at regular intervals or not, I was wondering if Arduino with IR sensor could work? The cable would be typically black with white text printed at each metre and will be unwounding from a cylindrical drum (To give you an idea of text length, it will contain cable type, metre mark, etc., I'll update the question with the linear velocity of the cable soon).

My approach was to raise an interrupt if the colour change is not recognized in the predetermined time. For this, I think I need to check if I can measure light changes, let's say 4 or 6 times in a time it takes to unwind a metre of the wire. I however don't know how fast IR sensors are to judge whether this approach is feasible.

Also, let me know if this is unfeasible and I should instead move to Raspberry Pi with a camera.

body:
https://www.instructables.com/IR-Transmitter-and-Receiver-Using-Arduino/

As demonstrated in the project linked above an IR sensor connected to an Arduino is capable of reading and decoding the signal from a typical IR remote sending at about 38 KHz. In the ones I've tried the signal is a burst of 10 or 11 digits.  Given that, sensing the presence or absence of a contrasting color sounds quite a bit less challenging.

I built the decoder in the linked Instructable with a Nano (author used a Mega) and it worked well.

I believe what you're proposing is feasible.


message:
Interval timer on Arduino: Doubt about TimerOne library

I want to synchronize a timer interrupt from a button is pressed. I want to read a button state 3 seconds later from the first pulse moment (to identify long pressed button, 3 seconds for this example). I'm trying to do with this code:

    #include <TimerOne.h>
    #define pinButton 3
    #define POWER_ON_TIME 3 //Long press in seconds

    volatile unsigned long pressed_Time = 0;
    volatile unsigned long myTime_button = 0;
    volatile unsigned long myTimeOn_button = 0;
    volatile unsigned long myTime_pressed = 0;

    unsigned long holdTime = 0;
    bool button_state = false;

    void setup() {
      // put your setup code here, to run once:
      pinMode(pinButton, INPUT_PULLUP);
      pinMode(LED_BUILTIN, OUTPUT);

      Timer1.initialize();
      Timer1.attachInterrupt(pressed_check);
      attachInterrupt(digitalPinToInterrupt(pinButton), button_act, CHANGE);
      Serial.begin(9600);
    }

    void loop() {

      Serial.println("myTime_pressed");
      Serial.println(myTime_pressed);

      if (!digitalRead(pinButton)){Timer1.attachInterrupt(pressed_check,POWER_ON_TIME*1000000 );}
        else {Timer1.detachInterrupt();}

    }

    void button_act(){
      if (!digitalRead(pinButton)){myTime_button = micros(); //Flanco de bajada
      }
      else{myTimeOn_button = micros(); } //Flanco de subida
    }

    void pressed_check(){
      myTime_pressed = micros();

    }

This way I can start the timer interrupt when the button is pressed, but the problem is the time is not the time from the function is attached but from the beginning. Any advice to change this?

body:
Don't know if I understand what you want to do.
IMHO TimerOne is a good library for repetitive tasks, not for one shot events.

You should use Timer1.stop and Timer1.resume() to start the 3 seconds count whenever you press the button.
But TimerOne has a known issue: when you use restart or start the ISR is fired immediatly

Here is my version of your code. It waits for button press and then starts timer. After 3 seconds pressed_check is fired and the longPressDetected flas is set.
I hope I have correctly interpreted your question

```
#include <TimerOne.h>
#define pinButton 3
#define POWER_ON_TIME 3UL //Long press in seconds

volatile unsigned long pressed_Time = 0;
volatile unsigned long myTime_button = 0;
volatile unsigned long myTimeOn_button = 0;
volatile unsigned long myTime_pressed = 0;

volatile bool firstISR_Call = true;
volatile bool longPressDetected = false;

unsigned long holdTime = 0;
bool button_state = false;

void setup() {
    // put your setup code here, to run once:
    pinMode(pinButton, INPUT_PULLUP);
    pinMode(LED_BUILTIN, OUTPUT);

    Timer1.initialize();
    // Create an ISR that is called every POWER_ON_TIME seconds
    Timer1.attachInterrupt(pressed_check, POWER_ON_TIME * 1000000UL);
    // Stop Timer1 now
    Timer1.stop();

    //Timer1.attachInterrupt(pressed_check);

    attachInterrupt(digitalPinToInterrupt(pinButton), button_act, CHANGE);
    Serial.begin(9600);
}

void loop() {
    if (longPressDetected) {
        longPressDetected = false;
        Serial.println("Long press detected");
    }
    delay(100);
}

void button_act() {
    if (!digitalRead(pinButton)) {
        myTime_button = micros(); //Flanco de bajada
        firstISR_Call = true;       // Set to true toprevent "phantom" interrupt
        longPressDetected = false;  // Clear long press detection flag
        Timer1.restart();           // Restart timer from 0 - ISSUE: this fires immediatly an interrupt
                                    // causing a so called "phantom" interrupt
    }
    else {
      myTimeOn_button = micros() - myTime_button;
      Timer1.stop();
    } //Flanco de subida
}

void pressed_check() {
    // Detect "phantom" interrupt
    if (firstISR_Call) {
        firstISR_Call = false;
        return;
    }
    longPressDetected = true;
    myTime_pressed = micros() - myTime_button;
    Timer1.stop();
}
```


message:
Using ESP8266 to program Arduino by serial comm

Since ESP8266 can self program on wifi, can we use it to program arduino too with the binary sent via wifi? my arduino is connected with reset+RX+TX pins and shared power.
Has this been already done?

body:
If you use Linux, you can use a simple [Telnet to Serial sketch][1] in esp8266 to upload with avrdude to Uno over esp8266. Only on Linux can avrdude use telnet to do a serial upload.

For upload from IDE on any OS there is [JeeLabs ESP Link firmware][2] for the esp8266.

  [1]: https://github.com/jandrassy/lab/blob/master/AvrDudeTelnet/AvrDudeTelnet.ino
  [2]: https://github.com/jeelabs/esp-link


message:
How do I instruct the L293D to operate a motor at full speed when using 3.3V GPIO pins?

If the L293D enable and input pins expect [up to] 5V inputs; what is the best way to deliver full power to the output pins when using an ESP32 or any other microcontroller which uses 3.3V GPIO pins?

I've seen several projects which combine the L293D with the ESP32, but none of them seem to mention whether or not this is even an issue.  Am I missing something?  Or should one always use level shifting when using 3.3V logic and the L293D

body:
The voltage level on the control pins does not have any relation to the power provided to the motor.

The inputs are all digital. Above a threshold they are on, and below a threshold they are off.  Those thresholds are compatible with both 3.3V and 5V logic.

What controls the power delivered to the motor is the duty cycle of the PWM signal provided to the EN pin.


message:
What is the difference between Bluetooth module HC-05 and HC-42 for Arduino?

I am looking for differences between HC-05 and HC-42 Bluetooth modules for Arduino. I could not find an answer by searching google.

Both products have 6 pins and accept master and slave but I could not find further details on the differences.

body:
It's different technology. the HC-05 uses the old Bluetooth 2.0 standard. The HC-42 in contrast uses BLE (Bluetooth Low Energy) in version 5.0.

So you have to decide what technology you want to use, either classic Bluetooth 2.0 or Bluetooth Low Energy 5.0.


message:
How to build an arduino project with multiple source files?

I'm building an arduino program on linux, using the following `Makefile`:

    ARDUINO_DIR = /usr/share/arduino
    BOARD_TAG = uno
    ARDUINO_PORT = /dev/ttyAMA0
    ARDUINO_LIBS = Wire
    include /usr/share/arduino/Arduino.mk

Currently all of my code is spread among a dozen header files and a single `.ino` file - it gets compiled and it runs properly when flashed. I know that's not correct though and I'm trying to split my code into the proper structure of source and header files but when I do and try to build it I get the following output:

    In file included from gear.c:1:0:
    gear.h:19:1: error: unknown type name ‘byte’
     byte GEAR = 3;
     ^

Which leads me to believe that the source file is getting compiled separately and does not know what a `byte` is, which is supposedly defined somewhere within the arduino library.

What's the proper way to build my project with source files?

body:
First of all, I recommend you write in C++ (file extension .cpp) rather
than in plain C (files in .c). The reason is that the Arduino
programming environment is based on C++, some of the libraries are
C++-only, and your main .ino file will be compiled as C++ source. Mixing
this with C is possible, using some `extern "C"` declarations, but it is
probably more hassle that it's worth.

Now, to answer your actual question, just add thsi near the top of your
source files:

```c++
#include <Arduino.h>
```

This includes the type definitions specific to the Arduino environment,
together with the core API. This include is added automatically to any
file ending in .ino, but you have to add it explicitly to your .cpp
files.


message:
Cubecell AB01 with nRF24L01

I have been trying to connect a nRF24L01 to a Cubecell AB01 without much luck. Most of the time, the radio.available() function always returns true resulting in a bunch of garbage. I have figured out that the nRF24L01 doesn't want to configure properly. With printPrettyDetails() I can confirm that the settings are not stored.

However, with the example sketch contained within the RF24 library, everything works fine (confirming that the AB01 and nRF24L01 are working fine). But as soon as I change the datatype of the receiver payload to uint8_t, the radio.available() is always true, resulting in a bunch of received messages with garbage. PrintPrettyDetails() also shows the wrong settings.

Does anyone have experience with this? I have also tried the example sketch from Robin2. This results in a lot of garbage as described before.

I am using:

 - nRF24L01 with pcb antenna. I am periodicially using an esp32 to test that the nRF24L01 is still functioning okay
 - a heltec AB01. The nRF24L01 is connected to the spi interface and CE -> GPIO3 and CSN -> GPIO2
 - To program I'm using platformio. But in desperation I am also able to use the Arduino IDE (exactly the same behaviour)

RX code:
        /**
        * See documentation at https://nRF24.github.io/RF24
        * See License information at root directory of this library
         * Author: Brendan Doherty (2bndy5)
         */

        /**
         * A simple example of sending data from 1 nRF24L01 transceiver to another.
         *
         * This example was written to be used on 2 devices acting as "nodes".
         * Use the Serial Monitor to change each node's behavior.
         */
        #include <SPI.h>
        #include "printf.h"
        #include "RF24.h"

        // instantiate an object for the nRF24L01 transceiver
        RF24 radio(GPIO3, GPIO2); // using pin 7 for the CE pin, and pin 8 for the CSN pin

        // Let these addresses be used for the pair
        uint8_t address[][6] = {"1Node", "2Node"};
        // It is very helpful to think of an address as a path instead of as
        // an identifying device destination

        // to use different addresses on a pair of radios, we need a variable to
        // uniquely identify which address this radio will use to transmit
        bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to                                 transmit

        // Used to control whether this node is sending or receiving
        bool role = false;  // true = TX role, false = RX role

        // For this example, we'll be using a payload containing
        // a single float number that will be incremented
        // on every successful transmission
        float payload = 0;

        void setup() {

          Serial.begin(115200);
          while (!Serial) {
            // some boards need to wait to ensure access to serial over USB
          }
          pinMode(Vext, OUTPUT);
          digitalWrite(Vext, LOW);
          delay(10);
          // initialize the transceiver on the SPI bus
          if (!radio.begin()) {
            Serial.println(F("radio hardware is not responding!!"));
            while (1) {} // hold in infinite loop
          }

          // print example's introductory prompt
          Serial.println(F("RF24/examples/GettingStarted"));

          radioNumber = 1;
          Serial.print(F("radioNumber = "));
          Serial.println((int)radioNumber);

          // Set the PA Level low to try preventing power supply related problems
          // because these examples are likely run with nodes in close proximity to
          // each other.
          radio.setPALevel(RF24_PA_LOW);  // RF24_PA_MAX is default.

          // save on transmission time by setting the radio to only transmit the
          // number of bytes we need to transmit a float
          radio.setPayloadSize(sizeof(float)); // float datatype occupies 4 bytes

          // set the TX address of the RX node into the TX pipe
          radio.openWritingPipe(address[radioNumber]);     // always uses pipe 0

          // set the RX address of the TX node into a RX pipe
          radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1

          // additional setup specific to the node's role
          if (role) {
            radio.stopListening();  // put radio in TX mode
          } else {
            radio.startListening(); // put radio in RX mode
          }

          // For debugging info
          // printf_begin();             // needed only once for printing details
          // radio.printDetails();       // (smaller) function that prints raw register values
           radio.printPrettyDetails(); // (larger) function that prints human readable data

        } // setup

        void loop() {

            // This device is a RX node

            uint8_t pipe;
            if (radio.available(&pipe)) {             // is there a payload? get the pipe         number that recieved it
              uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
              radio.read(&payload, bytes);            // fetch payload from FIFO
              Serial.print(F("Received "));
              Serial.print(bytes);                    // print the size of the payload
              Serial.print(F(" bytes on pipe "));
              Serial.print(pipe);                     // print the pipe number
              Serial.print(F(": "));
              Serial.println(payload);                // print the payload's value
            }

        } // loop

I have tried anything I could think of, without success. Any help would be appreciated!

body: Turned out to be a corrupt library and an SPI speed mismatch


message:
Different time betweenTiny RTC and IDE

I have time late in my Tiny RTC when i try to set time at sketch downloading.
Library: RTClib.h

Setup line:

    if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

The problem is that my computer displays 15:45 and Serial.print displays 15:12.
How can i fix that ?

body:
I just removed "if" condition and keep `rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));`
Solved!


message:
I2C missing last byte during transmission- solution isn't clear

I am using a Nodemcu-32S to communicate with an I2C device (touchpads). I noticed while uploading the configuration, the CRC (checksum) always comes back incorrect. After doing a little digging with a logic analyzer, I realized that it never transmits the final byte from my configuration array, which *is* the checksum value. The function I use for writing to the I2C bus is as follows:

``` cpp
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
    byte err;
    uint8_t dataPos = 0;
    Wire.beginTransmission(address);
    Wire.write(command);
    for (dataPos; dataPos < dataLen; dataPos++)
    {
        Wire.write(data[dataPos]);
    }
    delay(70);
    err = Wire.endTransmission();
    if (err > 0)
    {
        Serial.printf("writeI2C Error Code: 0x0%d\n", err);
        return false;
    }
    else
        return true;
}
```
With the following function call:
``` cpp
uint8_t config[128] = {0}; <- (the array is filled with values before the function call)

if (!writeI2C(SLAVE_ADDR, command, config, 128))
        {
            Serial.println("Failed to update config.");
            continue; // try again
        }
```
According to the logic in my function, it should transmit the address, then the register (`command` in this case) followed by 128 bytes of data (130 bytes total). With my logic analyzer, however, I get only 129 'chunks' of data. So I figured I'd add dummy writes if `dataLen` met a condition:

```cpp
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
    byte err;
    uint8_t dataPos = 0;
    Wire.beginTransmission(address);
    Wire.write(command);
    for (dataPos; dataPos < dataLen; dataPos++)
    {
        Wire.write(data[dataPos]);
    }
    if (dataLen > 100)
    {
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
        Wire.write(0x00);
    }
    err = Wire.endTransmission();
    delay(70);
    if (err > 0)
    {
        Serial.printf("writeI2C Error Code: 0x0%d\n", err);
        return false;
    }
    else
        return true;
}
```

None of the dummy writes are outputting and the behavior is the same. The final two bytes should be: `config[126] = 0x45` and `config[127] = 0xC9`, but my logic analyzer is shows that the transmission stops at `0x45 + ACK`.

body:
Within `Wire.h.`:

```
#define I2C_BUFFER_LENGTH 128
```

Changed the buffer length to 140 and it's working just fine.


message:
Using IN1/ IN2 pins for PWM instead of ENA in L298N

So basically i tried providing PWM directly to the IN1/IN2 Of L298n motor driver instead of using ENA pin i got more or less the same result
Im using ESP32 with 30000Hz freq for my PWM
My question is if both ways it can be used why aren't people using this method? Or am i missing something?
I would love to know the reason if someone has any idea about it.

body: When using only IN1/2 to control **speed** and **direction**, you must apply PWM to IN1 for one direction and to IN2 for the other direction, while the other pin will be connected to ground. This method is easy to implement with a MCU but uses two PWM channels.<br>I think the EN pin is used for applications without MCUs or where there is only one PWM channel. In these situations, pins IN1/2 are used for STOP/CW/CCW selection and EN for speed from a single PWM source.


message:
external power supply for servo motor attached to redboard arduino

I'm new to this page but I was hoping to get some advice on a servo motor arduino project I'm currently working on.

I have a HS-815BB servo motor (4.8~6V, max stall current draw 6,000mA) and a Spark Fun Redboard. I know I should hook up an external power supply to my servo motor to avoid frying my board. I've seen x4 AAA battery packs that can output 6V, as well as breadboard power supply modules with 3.3V/5V output. However, the breadboard power supply module has a max output current of 700mA and I'm not sure about the battery pack.

Where can I find a power supply that is arduino compatible and outputs ~6V while having a max current draw of 6A or over? Am I looking for the right thing?

Thanks in advance

body:
With 6A you are at a very high current.

First about the batteries: I wouldn't trust in 4 AAA batteries in supporting that high of a current. You may get away with it, if you only have very short bursts of 6A, but I guess the voltage will take a significant dip here. I would look into LiIon or LiPo battery packs, like the ones used for drones (which also can have high current spikes). But please take care to also use a fitting charging circuit. You can find many resources about that on the web.

Now about the breadboard: **Just don't pull 6A through a breadboard!** Breadboards are not made for currents this high. The contacts have a resistance that is significant in this situation and the metal strips used in there are also not meant for carrying that much. Going over 1A is probably no good for a breadboard. Instead you should connect the power supply outside of the breadboard by soldering or using proper connectors, which can handle the current. You can hook up your breadboard power regulator to the same battery if you want to provide it from the same source.

> Where can I find a power supply that is arduino compatible and outputs ~6V while having a max current draw of 6A or over?

There is no "Arduino compatibility" with power supplys. For the Arduino its just about having the correct voltage and being able to provide the needed current to the Arduino (excluding the servo, since it shouldn't be plugged into the breadboard in the first place). When you use a battery and also want to charge it in your circuit, then you need to find a charger board compatible with your chosen battery. Often these boards also have a voltage regulator from which you can get the 5V that you need to power an Arduino. Otherwise you can buy voltage regulator boards, which can take a full range of input voltages and output a regulated voltage of your liking (controlled via a small potentiometer on the board). These can also be used if you want to use a power supply connected to mains (like the often seen 12V power supplies for LED strips).

So called "breadboard power supply modules" are often not more than a board with pins in positions fitting for a breadboard. They are a pure convenience product. You can also solder pin to the cable of power source and put these into the breadboard. Sometimes these boards also have a voltage regulator, which you can also get without the breadboard connector part.