# Question
Title: Unable to read data with 16 serial clock cycles
I am trying to read data from an AD7314 Temperature Sensor that is connected to an Arduino Uno and output that value onto 6 LEDs also connected to the Arduino Uno board. From the image below, the sensor is showing only an output of `0011111111111111` during the streams of 16 clock cycles even after the chip enable goes from low to high before conversion to initiate a new one (it seems that the conversion is stuck). The datasheet says:

> A leading zero and 10 bits of data are transferred during a read operation. Read operations occur during streams of 16 clock pulses. Output data is updated on the rising edge of SCLK. The serial data is accessed in a number of bytes if 10 bits of data are being read. At the end of the read operation, the SDO line remains in the state of the last bit of data clocked out of the AD7314 until CE returns low

I am not sure where exactly I am going wrong during the read operation:

Note: for the Waveform image (Top to bottom):

* waveform 1: Chip Enable
* waveform 2: Serial Clock
* waveform 3: MISO Line
* waveform 4: MOSI Line

My code is below:

```
#include <SPI.h>

const int MOSI_PIN = 11;
const int MISO_PIN = 12;
const int SCK_PIN = 13;
const int Slave_PIN = A0;

// module data
uint16_t myValFromTempSensor = 0;

void setup () {
  SPI.begin ();
  SPI.beginTransaction(SPISettings(125000, MSBFIRST, SPI_MODE0));
  pinMode(5, OUTPUT); //LED 3
  pinMode(6, OUTPUT); //LED 4
  pinMode(7, OUTPUT); //LED 5
  pinMode(8, OUTPUT); //LED 6
  pinMode(9, OUTPUT); //LED 7
  pinMode(10, OUTPUT);//LED 8
  pinMode(MOSI_PIN, OUTPUT); // MOSI to SDI
  pinMode(MISO_PIN, INPUT); //MISO to SDO
  pinMode(SCK_PIN, OUTPUT); //CLOCK PIN to SCK
  pinMode(Slave_PIN,OUTPUT); //Slave pin

  digitalWrite(Slave_PIN, LOW);//Set slave low before communication
  for (int i = 5; i < 11; i++) {
    digitalWrite(i, LOW);
  }
  delay(100);
} // end of setup

void loop () {
  digitalWrite(Slave_PIN, HIGH);  //Set slave high to read data
  myValFromTempSensor = SPI.transfer(0x00); // Read Data from the device
  myValFromTempSensor |= (uint8_t)SPI.transfer(0x00) << 8;// Bitshift to read next 8 bits
  digitalWrite(Slave_PIN, LOW);
  if(( myValFromTempSensor>=0) && ( myValFromTempSensor<=196)) {
    //Range 0C to 60C is  0 to 196
    digitalWrite(5, bitRead(myValFromTempSensor,0));
    digitalWrite(6, bitRead(myValFromTempSensor,1));
    digitalWrite(7, bitRead(myValFromTempSensor,2));
    digitalWrite(8, bitRead( myValFromTempSensor,3));
    digitalWrite(9, bitRead( myValFromTempSensor,4));
    digitalWrite(10, bitRead( myValFromTempSensor,5));
  } else {
    digitalWrite(5, 0);
    digitalWrite(6, 0);
    digitalWrite(7, 0);
    digitalWrite(8, 0);
    digitalWrite(9, 0);
    digitalWrite(10, 0);
  }
}

```

# Answer
> 1 votes
I see several issues here.

## Sensor output

According to the waveforms shown by your logical analyzer, the sensor is outputting 0b0011111111111111. We have to discard the first (a padding zero) and the last five bits (copies of DB0). We then end up with the actual data bits being 0111111111. This has to be interpreted as a signed fixed-point number in s.7.2 format, which gives 127.75 °C: the maximum possible value the sensor can output, and well above its maximum operating temperature.

I cannot tell what is going wrong here. It looks like the sensor is either burning alive, or trying to tell you it's extremely unhappy.

## SPI mode

You wrote:

> `SPISettings(125000, MSBFIRST, SPI_MODE0)`

SPI mode 0 seems to be pretty common. In this mode, the data lines are updated on the falling edge of the clock, and they are read on the rising edge. However, according to your sensor's datasheet, it appears this sensor works the other way around: it uses SPI mode 1. Your setting should reflect this.

## Decoding the data

You wrote:

> `myValFromTempSensor = SPI.transfer(0x00);`
> `myValFromTempSensor |= (uint8_t)SPI.transfer(0x00) << 8;`

Here you are assuming the least significant byte is transmitted first. This is not the case: you get a stream of 16 bits with the most significant first. Thus, in terms of bytes, it's also MSB first.

Then, 6 of these 16 bits have to be discarded in order to get the actual 10 data bits. Since the Arduino has no 10-bit data type, and the number is signed, it has to be sign-extended to 16-bits. All this can be done in C/C++ by:

* left-shifting one bit to the left (discarding the zero padding bit)
* casting to a *signed* 16-bit integer
* right-shifting (which gcc implements using sign extension) six bits to the right

Or, in code:

```
digitalWrite(Slave_PIN, HIGH);
uint16_t raw_data = SPI.transfer16(0);
digitalWrite(Slave_PIN, LOW);
int temperature_reading = (int16_t)(raw_data << 1) >> 6;

```

---

**Edit**: Here are more details about the data representation, and about the conversion to 16-bits done by the expression `(int16_t)(raw_data << 1) >> 6`.

According to the datasheet, the sensor gives the temperature as a 10-bit *signed* number in two's complement notation. If you fail to acknowledge the fact that the result is signed, and you interpret the 10 bits as an unsigned number, then a temperature of −1 °C will be interpreted as +255 °C, which is obviously *very* wrong.

Since it's a signed number, increasing the bit width of the temperature to 16 bits has to be done using sign extension, i.e. the missing bit positions have to be filled with copies of the leftmost bit (the “sign bit”).

The datasheet also shows that the sensor sends a stream of 16-bits as follows:

```
0 db9 db8 db7 db6 db5 db4 db3 db2 db1 db0 db0 db0 db0 db0 db0

```

where the first bit is a padding zero, then come the ten data bits db9 – db0, and then five extra copies of the last data bit. These extra copies can be seen in figure 3 (serial interface digram), and can also be inferred from the sentence “the SDO line remains in the state of the last bit of data clocked out of the AD7314”.

The line

```
uint16_t raw_data = SPI.transfer16(0);

```

puts this bit pattern into the variable `raw_data`, which is a 16-bit unsigned integer. Then, the operation `raw_data << 1` shifts this pattern one bit position to the left, discarding the leftmost zero and padding with another zero on the right, which gives:

```
db9 db8 db7 db6 db5 db4 db3 db2 db1 db0 db0 db0 db0 db0 db0 0

```

This is then cast to a signed number, which doesn't change the bit pattern, but only the interpretation of the leftmost bit, which is now a sign bit. Then, the number is shifted by 6 bit positions to the right. Since this is an arithmetic shift, which does sign extension, the leftmost bit (the “sign bit”) is replicated during the shift, which yields:

```
db9 db9 db9 db9 db9 db9 db9 db8 db7 db6 db5 db4 db3 db2 db1 db0

```

And this is the expected result: the *same numeric value* that was originally stored in the “temperature value register” of the sensor, only represented as a 16-bit number.

# Answer
> 1 votes
This is not an answer to your question but I cannot add it as a remark since it involves code.

You can greatly reduce your code by using for loops, e.g.:

```
   pinMode(5, OUTPUT); //LED 3
   pinMode(6, OUTPUT); //LED 4
   pinMode(7, OUTPUT); //LED 5
   pinMode(8, OUTPUT); //LED 6
   pinMode(9, OUTPUT); //LED 7
   pinMode(10, OUTPUT);//LED 8

```

to

```
   int n;
   for (n = 5; n < 11; n++)
   {
      pinMode(n, OUTPUT);
   }

```

And

```
digitalWrite(5,bitRead( myValFromTempSensor,0));
digitalWrite(6,bitRead( myValFromTempSensor,1));
digitalWrite(7,bitRead( myValFromTempSensor,2));
digitalWrite(8,bitRead( myValFromTempSensor,3));
digitalWrite(9,bitRead( myValFromTempSensor,4));
digitalWrite(10,bitRead( myValFromTempSensor,5));

```

to

```
int n = 0;
for (n = 0; n < 6; n++)
{
    digitalWrite(n + 5,bitRead( myValFromTempSensor, n));
}

```

And

```
  digitalWrite(5,0);
  digitalWrite(6,0);
  digitalWrite(7,0);
  digitalWrite(8,0);
  digitalWrite(9,0);
  digitalWrite(10,0);

```

to

```
int n;
for (n = 5; n < 11; n++)
{
    digitalWrite(n, 0);
}

```

Instead of hardcoded values 5 and 11 you can use defines, e.g.

```
#define LED_MIN 5
#define LED_MAX 11

```

and change

```
for (n = 5; n < 11; n++)

```

to

```
for (n = LED_MIN; n < LED_MAX; n++)

```

# Answer
> 1 votes
If anyone stumbled on this thread later like I did, it may be helpful to understand that the binary response is a decimal number, specifically with 0.25c resolution. Meaning that the integer value that Edgar Bonet's (excellent) response will give you needs to be multiplied by 0.25 to get the actual temperature in Celsius.

I suggest multiplying by 0.25 because it will give the same result as dividing by 4 but without the risk of a divide by zero error. Also division is extremely slow on Arduino since the underlying instruction set does not have a divide instruction.

I hope this helpful to someone at some point; if not sorry for the annoyance.

---
Tags: arduino-uno, c, spi, electronics
---


# Question
Title: 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.

# Answer
```
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.
> 2 votes

---
Tags: serial, arduino-ide, sd-card, array, buffer
---


# Question
Title: 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:

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 |

# Answer
As @devnull at Electronics Stack has answered, 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.
> 3 votes

---
Tags: power, arduino-zero, samd21g
---


# Question
Title: 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?

# Answer
You probably already know that continuous servos are different to other hobbyist servos in that they rotate freely, and the PWM signal 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 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 votes

---
Tags: servo, adafruit, software, continuous-servo
---


# Question
Title: 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?

# Answer
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.
> 3 votes

# Answer
> 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.
> 2 votes

---
Tags: arduino-uno, i2c, atmega328, uart, atmega16u2
---


# Question
Title: 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 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 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. 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.

# Answer
The full pinout 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 you can see sections for DAC, PWM and TIMER PWM pins.

The information about pins for Arduino core is in variant.cpp.
> 1 votes

---
Tags: arduino-due, port-mapping, registers
---


title: Optimizing code for ATtiny10

text:
# Question
Title: Optimizing code for ATtiny10
I'm trying to squeeze code onto an ATtiny10, 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);
    }
}

```

# Answer
> 12 votes
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:

```
#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:

```
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).

# Answer
> 7 votes
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:

```
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.

# Answer
> 3 votes
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.

# Answer
> 1 votes
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.

---
Tags: c++, attiny, code-optimization, sketch-size
---


# Question
Title: How to prevent an alarm which checks minutes from going off many times within one minute?
### How do I prevent an alarm, which checks if the current time matches an alarm time in hours and minutes, from going more than once within one minute?

I am using the DS3231 RTC module and RTClib from adafruit. I want to check if the current time equals to the alarm time, then set the `alarmFlag` variable. I want to clear `alarmFlag` when a button on pin D5 is pressed.

The code below works fine as long as I don't press the button within about a minute from the start of the alarm. If I press the button within about a minute from the start of the alarm, the alarmFlag will be 0 for one `loop()` cycle, but then (almost immediately, I don't have much in `loop()`) will be back to 1. I want for the button to stop the alarm completely, so it fires again only on the next day.

```
uint8_t alarm[2] = {19, 30}; // hour (24), minute

// other code ...

void loop() {

  currTime = rtc.now();

  // check if current time matches alarm time
  // if it matches, it matches for a whole minute, which is the problem here
  if (!alarmFlag && alarm[0] == currTime.hour() && alarm[1] == currTime.minute()) {
    alarmFlag = true;
  }

  // clear alarmFlag on button press (this is a shortened version, excuse the lack of debouncing/other stuff)
  if (digitalRead(5) == HIGH) {
    alarmFlag = false;
  }

}

```

Notes:

1. I can not use the RTC's built-in alarms because I need them elsewhere.
2. I don't want to just add `currTime.seconds() == 0` to the first `if` statement, because that would skip the alarm if the `loop()` cycle takes more than a second.
3. I know that the way I detect a button press in the example code is suboptimal, I wrote a better way to deal with this in my main code, but I don't want to clutter up this question.

# Answer
> 1 votes
As suggested by the busybee, this is a textbook application of the concept of finite state machine. Below is a state diagram that hopefully captures the desired behavior. Its meaning is hopefully obvious at first sight.

Here your `alarmFlag` is replaced by the `TRIGGERED` state. Please note that, with this state machine, the only way to turn the alarm off is to press the button. If nobody is there to press it, is goes on forever. This kind of issue is quite obvious when looking at the state diagram, less so when looking at the code. This is why it is advisable to draw a state diagram before you start coding. If this behavior is a not desirable, you may add an extra transition out of the `TRIGGERED` state, which would happen on a timeout.

It is also worth noting that, with this state machine, pressing the button multiple times in quick succession has the same effect as pressing it once. In other words, there is no point in debouncing the button.

For implementing this in C++, I suggest you follow the steps of this tutorial on finite state machines.

# Answer
> -1 votes
If you add a `delay(60*1000)` to your button press function, then you will essentially have a cool off period before the alarm is checked again. The alarm cannot go off again during that `delay;`

For non-blocking code, you could store the time you pushed the button, and then check that time before checking it's the alarm time.

```
    //code to add to your button press
    lastbuttonpress = millis();

    //code to add before your alarm check
    if (lastbuttonpress - millis() > 60*1000) {
        //do your alarm check
    }

```

---
Tags: rtc
---


# Question
Title: Using CD74HC4067 16-Channel Analog Multiplexer Demultiplexer is not working as expected
I am working on a project that needs multiple digital signals and I am considering the CD74HC4067 (on a break-board) to work as a multiplexer. More specifically i am trying to build a keypad with multiple ttp123 break-boards. Each ttp123 signal is connected to one of the 0-15 pins of the CD74HC4067. The S0-S3 pins are connected to digital Pins D6 to D9 on a pro mini. Signal is on A0 and EN is on A1. A1 and EN have a 4K7 resistor to ground. I power the setup with a separate 5v and the arduino is connected on a pc usb port.

I expect when a ttp123 is pressed to trigger a HIGH and this event to be passed to SIG pin. Here is my code:

```
//Using CD74HC4067 16-Channel Analog Multiplexer
//Mux control pins

int s0 = 6;
int s1 = 7;
int s2 = 8;
int s3 = 9;

//Mux in "SIG" pin
int SIG_pin = A0;
int EN_pin  = A1;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(EN_pin, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  digitalWrite(EN_pin, LOW);

  Serial.begin(9600);
  Serial.println("keypad interfacing_CD74HC4067 starting...");
}

void loop(){
  String a;
  //digitalWrite(EN_pin, HIGH);
  Serial.println(" press any key to continue ...");
  //digitalWrite(EN_pin, LOW);
  while (!Serial.available());
  while(Serial.available()) {

  //Loop through and read all 16 values
  for(int i = 0; i < 16; i ++){
    //Serial.print("Value at channel ");
    //Serial.print(i);
    //Serial.print("is : ");
    //Serial.println(readMux(i));

      float volts = readMux(i);

      Serial.print("Value at channel ");
      Serial.print(i);
      Serial.print(" is : ");
      Serial.print(volts);
      Serial.println();

    //delay(1000);
  }
  a= Serial.readString();// read the incoming data as string
}
}
float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig

  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[j], muxChannel[channel][j]);
  }
  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  float voltage = (val * 5) / 1024.0;
  return voltage;
}

```

Just for simplicity, I have connected only one ttp123 on the system, ttp123 signal to channel12 on 74HC4067. With ttp123 touched, I would expect to get a high on SIG when I write {0,0,1,1}, to S0-S3. All other channels should be LOW. However here is what I get:

On my first run after a boot:

```
press any key to continue ...
Value at channel 0 is : 2.53
Value at channel 1 is : 2.58
Value at channel 2 is : 2.53
Value at channel 3 is : 2.60
Value at channel 4 is : 2.51
Value at channel 5 is : 2.55
Value at channel 6 is : 2.50
Value at channel 7 is : 2.52
Value at channel 8 is : 2.42
Value at channel 9 is : 2.47
Value at channel 10 is : 2.43
Value at channel 11 is : 2.50
Value at channel 12 is : 2.40
Value at channel 13 is : 2.43
Value at channel 14 is : 2.38
Value at channel 15 is : 2.44

```

and then after each sample run all channels seem to get lower values...

```
press any key to continue ...
Value at channel 0 is : 1.70
Value at channel 1 is : 1.76
Value at channel 2 is : 1.71
Value at channel 3 is : 1.78
Value at channel 4 is : 1.70
Value at channel 5 is : 1.76
Value at channel 6 is : 1.72
Value at channel 7 is : 1.77
Value at channel 8 is : 1.67
Value at channel 9 is : 1.72
Value at channel 10 is : 1.69
Value at channel 11 is : 1.76
Value at channel 12 is : 1.69
Value at channel 13 is : 1.73
Value at channel 14 is : 1.67
Value at channel 15 is : 1.74

```

and I get no HIGH on channel 12 as I should.

Is there a need for a pullup or pulldown resistors in this setup? Should I connect a resistor to each S0-S3 with ground? Why is this not working?

Edit:

When the system is resting I measure 4.93V at the ttp's Vs to GND and 0V TTP\_SIGNAL to GND. When ttp's are touched TTP\_SIGNAL to GND i measure a 3.94-3.88v. But the strange thing is that when i touch the ttp's I measure 2.xx Volts at all the mux channels. I think that there must be some kind of short circuit somewhere but it is not visible. The problem is that I can't test another CD74HC4067 since i have only one right now. Unless there is another suggestion I will look for a couple of these (CD74HC4067) as soon as possible.

Edit2:

I got hold of a new CD74HC4067 and connected just one capacitive touch pad. When nothing is touched/pressed, i get the following:

```
press any key to continue ...
Value at channel 0 is : 1.01
Value at channel 1 is : 0.90
Value at channel 2 is : 0.81
Value at channel 3 is : 0.62
Value at channel 4 is : 0.44
Value at channel 5 is : 0.42
Value at channel 6 is : 0.43
Value at channel 7 is : 0.43
Value at channel 8 is : 0.31
Value at channel 9 is : 0.28
Value at channel 10 is : 0.24
Value at channel 11 is : 0.18
Value at channel 12 is : 0.15
Value at channel 13 is : 0.23
Value at channel 14 is : 0.22
Value at channel 15 is : 0.13

```

When i touch the pad (connected to c0) i get:

```
press any key to continue ...
Value at channel 0 is : 4.15
Value at channel 1 is : 3.74
Value at channel 2 is : 3.75
Value at channel 3 is : 3.54
Value at channel 4 is : 3.76
Value at channel 5 is : 3.33
Value at channel 6 is : 2.88
Value at channel 7 is : 2.64
Value at channel 8 is : 3.77
Value at channel 9 is : 3.52
Value at channel 10 is : 3.07
Value at channel 11 is : 2.76
Value at channel 12 is : 2.04
Value at channel 13 is : 1.83
Value at channel 14 is : 1.67
Value at channel 15 is : 1.51

```

I measure volts between signal and ground at the capacitive touch pad, when touched i get 3.9v

# Answer
> 2 votes
I finally managed to get a solution to my problem. There was a cabling and a software issue as well. Firstly, I pulled down the Signal with a 10K resistor. In this way I stopped having those random volt measurements.

Secondly, in the code, I had an elementary failure to initialize the A0 analog pin as: pinMode(SIG\_pin, INPUT);

Here is the final code:

```
// interfacing mux with tp223

//Mux control pins

const int s0 = 6;
const int s1 = 7;
const int s2 = 8;
const int s3 = 9;

//Mux in "SIG" pin
int SIG_pin = A0;
int EN_pin  = 10;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(SIG_pin, INPUT);
  pinMode(EN_pin, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  digitalWrite(EN_pin, LOW);

  Serial.begin(115200);
  Serial.println("keypad interfacing_CD74HC4067 starting...");
}

void loop(){

  //Loop through and read all 16 values
  for(int i = 0; i < 16; i ++){
      int val = readMux(i);

      if (val > 0) {
        Serial.print(i);
        Serial.print(" pressed ");
        Serial.print(val);
        Serial.println();
      }
  }

}
float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig
  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[j], muxChannel[channel][j]);
  }
  //read the value at the SIG pin
  int val = digitalRead(SIG_pin);
  //return the value
  return val;
}

```

---
Tags: arduino-nano, multiplexer, keypad
---


# Question
Title: 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.

# Answer
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).
> 5 votes

---
Tags: calculation
---


title: atTiny85 5V and servo usage

text:
# Question
Title: atTiny85 5V and servo usage
I have an AtTiny85 that I would like to move a servo on I/O "4" for this project.

I can't seem to get it to work, no matter what I do. I had tons of issues getting it to program, but I've gotten it to a place where it will program a blink, and it will also blink the LED in the circuit diagram in the link provided. I have the servo wired, and I'm pretty darn sure the wiring is correct (when are we 100% sure?). I've tried these programs to no success:

```
// Trinket Servo Monster sketch
// Hardware: Adafruit Trinket (3V or 5V), micro servo, LED + resistor
// Libraries: uses Adafruit_TiCoServo library to manage servo pulses,
// even though NeoPixels are NOT being used here.

#if !defined(__AVR_ATtiny85__)
 #error "This code is for ATtiny boards"
#endif
//#include <Adafruit_TiCoServo.h>
#include <ServoManager.h>
#include <avr/power.h>

// Servo parameters.  Pin MUST be 1 or 4 on a Trinket.  Servo position
// is specified in raw timer/counter ticks (1 tick = 0.128 milliseconds).
// Servo pulse timing is typically 1-2 ms, but can vary slightly among
// servos, so you may need to tweak these limits to match your reality.
#define SERVO_PIN  4 // Pins 1 or 4 are supported on Trinket
#define SERVO_MIN  4 // ~1 ms pulse
#define SERVO_MAX 26 // ~2 ms pulse

#define LED_PIN    0 // "Eye" LED is connected here

PrecisionServo* servo;

void setup(void) {
  ServoManager::setup(1);
  servo = ServoManager::createServo(4);
  //servo->setSetting(SERVO_MEDIUM_ENDPOINT);

//#if (F_CPU == 16000000L)
  // 16 MHz Trinket requires setting prescale for correct timing.
  // This MUST be done BEFORE servo.attach()!
//  clock_prescale_set(clock_div_1);
//#endif
  //servo.attach(SERVO_PIN);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
}

uint32_t lastLookTime = 0; // Time of last head-turn

void loop(void) {

  //unsigned long t = millis(); // Current time

  // If more than 1/2 second has passed since last head turn...
  servo->setTarget(0);
  ServoManager::waitUntilFinished();

  servo->setTarget(180);
  ServoManager::waitUntilFinished();

  // Unrelated to head-turn check,
  if(random(10) == 0) { // there's a 1-in-10 chance...
    // ...of an "eye blink":
    digitalWrite(LED_PIN, LOW);  // The LED turns OFF
    delay(random(50, 250));      // for just a short random moment
    digitalWrite(LED_PIN, HIGH); // then back ON
  }

  //delay(1000); // Repeat loop() about 10 times/second
}

```

SO I scaled back and just tried to write a high out as follows:

```
void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  digitalWrite(4, HIGH);
  delayMicroseconds(1000);
  // 1 millisecond determines the servo going forwards
  digitalWrite(4, LOW);
  delay(19);
}

```

But this didn't work either.

Shouldn't the servo move with just a write to 'high' and 'low'?

# Answer
> 2 votes
The servo requires a PWM signal to the control lead to move.

This datasheet kind of bears that out...

http://www.datasheetcafe.com/sg90-datasheet-pdf-9-g-micro-servo/

---
Tags: servo, attiny
---


# Question
Title: 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 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
}

```

# Answer
> 3 votes
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;
}

```

---
Tags: interrupt
---


title: Send batch info to com port?

text:
# Question
Title: 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.

# Answer
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.
> 0 votes

---
Tags: serial
---


# Question
Title: Why a servo doesn`t move to angles properly
I've got to do a project which uses a servo to drive a turntable. How much I adjusted the angle, the servo seemed to shift every time it spinned. For instance, the 0 degree angle was getting a bit bigger. I think it is caused by the imprecise PWM control of the Arduino or the bad translation using, I think, the `map()` function.

Could you fix this issue in code, or the servo doesn't work properly. I observed that every servo (that I've tried) creates a buzzing noice for angles bigger than 170 degrees.

By the way, my code is:

```
#include

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

#define pos0 0
#define pos1 23
#define pos2 48
#define pos3 164

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  Serial.begin(9600);
}

void loop() {
  for (pos = pos0; pos  pos0; pos -= 1) {
    myservo.write(pos);
    delay(30);
  }
  Serial.print("pos: ");
  Serial.println(pos);
  delay(5000);
}

```

Edit: Should I try with a more powerful Arduino, like the Mega, which I think will be the perfect option having more GPIO than the UNO.

# Answer
Try to use `myservo.writeMicroseconds(x)` function. For standard servos the value of parameter x is between 1000 to 2000 for 0 degree to 180 degree rotation. But you know all servos are not manufactured perfectly. Thats why servos can response to 700 to 2300. At first you have to verify the minimum and maximum responding values then use it. You can use `map()` for easy coding.
> 1 votes

# Answer
Every servo is different, they can have varying specifications:

* Angular speed
* Rotation range
* Stall Torque
* Size
* Gear material/quality

Servos will vary based on brand; in addition each servo is going to have some individual variance. So one has to characterize the servo, and discover what the proper control values are. Once the control values are established these are used to initialize the library so angular control will be accurate.

> For instance, the 0 degree angle was getting a bit bigger

I have found that errors in repeatability, like this, are usually found in the mechanism the servo is driving, especially the connection between the servo and the driven mechanisms. Check the connection for slop, see if everything is tightened properly.

> I observed that every servo (that I've tried) creates a buzzing noice for angles bigger than 170 degrees.

The typical maximum range of a servo is 160-190 degrees of rotation. The noise you are hearing is the servo trying to drive the motor to set the angle, but it is stalled as it can't turn that far.

> Should I try with a more powerful Arduino, like the Mega, which I think will be the perfect option having more GPIO than the UNO.

IIRC the servo library can control 12 servos with a basic Arduino, and 48 with the MEGA. This difference is more than just pin count, the MEGA has 4x the hardware timers of the 328p; 12 x 4 = 48

If you need more features you can move to the MEGA, i.e. you need more PWM channels, and the servo library reduces PWM pins from 6 to 4 on the 328p. Another example could needing more timers.

Read the Arduino Servo examples for more information on usage of the servo library and control of servos, etc.
> 1 votes

# Answer
Not all Servos are perfectly built. One can get rid of the library itself; there is a way to make a servo turn by manually writing out the code.

```
for(x=0; x<150; x=x+1)
{
  digitalWrite(Servomotor, HIGH);
  delayMicroseconds(1500);          //Edit this delay to adjust the position
  digitalWrite(Servomotor, LOW);
  delayMicroseconds(18550);         //Don't touch this delay
}

```

By trying out different delays for the first `delayMicroseconds()`, you can test out which delay you need for what position.

To make your code more clean, you could safe different angles in another void function, and when you need them just type out the name

Have a nice day ;)
> 0 votes

# Answer
An inexpensive servo tester, e.g....

https://www.amazon.com/DIYmall-Digital-Consistency-Controler-Checker/dp/B012LZKTDO/ref=sr\_1\_12?crid=3BLBBVDUPTN53&keywords=servo+tester&qid=1644245707&sprefix=servo+tester%2Caps%2C93&sr=8-12

...is useful for determining the exact mechanical limits of a specific servo quickly and easily. If the servo will only physically move 170 degrees and the connected mechanism requires 180 degrees, a different servo is needed.

It should be possible to use an oscilloscope connected to the servo control lead to determine a) what the tester output duty cycle is at specific angular positions, and b) what the actual Arduino output duty cycle is when running a program.

Use the servo tester to assure that the range of motion of your servo is adequate to correctly operate the mechanism.

Note the tester output at desired positions.

Adjust your program to produce the duty cycle(s) necessary to replicate the tester output at the desired positions.
> 0 votes

---
Tags: arduino-uno, servo
---


# Question
Title: Connecting a FireBeetle ESP32 to Arduino
I have a very basic question, because I struggle to upload files to my FireBeetle ESP32 Board.

When I try to upload to the board I get an

```
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

```

On other boards you have to press & hold the flash button, but this specific board just has a reset button. What can I do?

# Answer
The flash button is virtual and controlled by the RTS signal from the computer through the USB port (why are you trying to connect through an Arduino?). It should automatically enter bootloader mode when you go to program it. There should be nothing you need to do.

However, if you *do* want to manually enter bootloader mode, just connect IO0 (*note: not D0*) to GND and press the reset button.
> 2 votes

# Answer
I suspect you do not have the right drivers installed. That's the issue I just solved for myself. And it can be easy to think you installed the right driver, when in fact you didn't.

Have you followed the instructions on DFRobot's product wiki?

I'm not sure if you have the ESP32-E or the earlier ESP32-IOT Firebeetle, but here's the link to the drivers mentioned for the Firebeetle ESP32E and here for the prior version, the Firebeetle ESP32 IOT

But I would suggest double checking which board you have an very meticulously ensuring you have the right driver installed.
> 2 votes

---
Tags: arduino-ide, esp32
---


# Question
Title: Would an Arduino Uno be suitable for a simple time-based locking circuit?
Background: I'm looking to start on my first real electronics project and I have an Arduino Uno I bought a while back. I've only done a few of the starter Arduino tutorials and that was a while back as well. Starting from very little electronics knowledge, I'm trying to get a bit of advice on how to tackle my first project. **TL;DR:** I have an Arduino Uno but very little experience with it or electronics.

Project: I want an object that locks, I want the duration of the time it stays locked for to increase by ~1-3% every time it locks. I want to put my nicotine products in there to gradually pull myself off nicotine. I have designed a rough 3D model of the box, which I can 3D print so now I'm looking at the electronics. **TL;DR:** A box which stays locked for longer, every time it locks.

Electronics: A microcontroller/Arduino/Pi to increase the locking duration; a locking circuit and some form of power supply.

My 2 questions are

1. Would the Arduino Uno be suited to this type of project?
2. What sort of components should I be looking for for the locking circuit and power supply (I'm thinking some sort of solenoid actuator and a battery pack)?

# Answer
> 0 votes
It is a great occasion to use the Arduino!

There are many tutorials for the Arduino out there, so thats a good place to start. This forum is a good place to ask any Arduino related question if you need to do so.

---

***The following contains MY OPINION***

In my opinion, an Arduino Nano would be great for this project. It is really user friendly and can pretty much accomplish many things. A Pro Mini would be better, but seeing sa you're a beginner, stick with the Nano.

A good long lasting batteRY would be a simple USB power bank. It outputs 5V and has a lot of juice. For a locking circuit, a simple servo would work **IF THE THINGS THAT IS IN THAT "SAFE" ISN'T 1M $$**. A servo does a decent job as a lock.

---

Good luck!

# Answer
> 0 votes
Regarding your second question about what components to use, there are a couple arguments for a servo over a solenoid.

A solenoid in the energized state is relatively power hungry compared to a servo, which only requires any appreciable power while actually moving. Also, on power loss or interruption a servo fails as-is; a solenoid goes to the off position, which could cause an unwanted change of state for the lock.

---
Tags: arduino-uno, power, electronics, components
---


title: L298N DC Motor Driver Conundrum

text:
# Question
Title: 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

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?

# Answer
> 1 votes
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.

# Answer
> 0 votes
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

---
Tags: arduino-uno
---


# Question
Title: Converting three-axis magnetometer values to degrees
I have a 9-DOF sensor (MPU-9150) and I want to use its magnetometer to retrieve the rotation angle, from 0 to 359. However, its library returns three values: x, y and z.

I do not know how to transform this into a single value. Is there any way to do this?

# Answer
> 20 votes
The answer given by Dave X, namely

```
az=90-atan(y/x)*180/pi

```

is on the right track. However, it cannot work as is for two reasons:

1. The formula fails badly whenever x = 0,
2. It gives the same azimuth for x = y = 1 and for x = y = −1. In other words, it cannot differentiate between north-east and south-west.

The formula could be fixed by replacing `atan(y/x)` by a function that returns:

* atan(y/x) if x \> 0
* π/2 if x = 0 and y \> 0
* −π/2 if x = 0 and y \< 0
* atan(y/x) + π if x \< 0 and y ≥ 0
* atan(y/x) − π if x \< 0 and y \< 0

That would be essentially a two-argument, “quadrant-aware” version of the arctangent, yielding results in (-π, π\] instead of (−π/2, π/2).

Fortunately, such function already exists. It is a very standard function of the C library and is called `atan2()`. Thus, the correct formula is

```
az = 90 - atan2(y, x) * 180 / M_PI;

```

Now, since atan(y/x) = π/2 − atan(x/y), the formula above can be simplified into

```
az = atan2(x, y) * 180 / M_PI;

```

This formula gives the direction of the (x, y) vector counted clockwise from the y axis. It is likely that the OP wants instead to know the heading of some kind of vehicle. The correct formula depends then on how the magnetometer has been mounted relative to the vehicle. If we assume that the x axis of the magnetometer points forward and the y axis points to the left, then:

* the vehicle is heading north (0° magnetic heading) when the horizontal component of the magnetic field is along +x
* the vehicle is heading east (90° magnetic heading) when the horizontal component of the magnetic field is along +y

From here, it follows that the vehicle heading is

```
heading = atan2(y, x) * 180 / M_PI;

```

Obviously, the magnetic declination has to be added if one is interested in the *true* (rather than *magnetic*) heading.

---

**Edit**: All this assumes the XY plane is horizontal. If it is not (due to the vehicle's pitch and roll), see Tails86's answer for a way to cope with that.

# Answer
> 5 votes
You first need calibration (either using the device calibration method, or, by rotating it in a complete circle to ascertain the full field strengths).

You can then use the X, Y, and Z readings to compute the location of "north" relative to whichever way you're pointing (keeping in mind that "north" changes as much as 30 degrees depending where on earth you are (called declination - see http://www.magnetic-declination.com/), and that it's not horizontal to the ground either (confusingly, called "inclination" - see https://physics.stackexchange.com/questions/283761/if-you-hold-a-compass-needle-vertical-does-it-point-down-or-up-differently-on-wh/283782 )

If you picture the X, Y, and Z readings as meaning "where on an imaginary circle is the direction of magnetism - where those 3 circles are on 3 different planes, you can compute the logical position of a vector pointing towards magnetic north in 3 dimensions.

The bad news - there's no simple way to do what you want accurately, and definitely not one that's going to work without trig math on all 3 readings (you can't just use X and/or Y alone).

The good news - you probably don't really need to know an actual "heading" - most applications just need some local relative direction as compared with something you already know.

Beware that strong magnets (such as ones in all modern motors) seriously mess with readings from a long way away (10 or more foot even) - grab an app from your phone store that shows your phone magnetometer readings, and wave a magnet around to see this easily!

# Answer
> 4 votes
I wanted to expand upon what Anon is getting at and provide some math as I've just gone through this process for a similar 9-axis device.

First, it's good to know what the magnetic field vector means. I like this source because it provides an image showing where magnetic vectors point as you move up and down earth. It points downward on the northern hemisphere and upward in the southern hemisphere. The text is otherwise not relevant as it more or less just explains how you can approximate laitudinal position from that data - the angle of the horizontal component is all that we need to be concerned with in order to obtain a heading.

The problem with Edgar's answer is that it assumes that your reference plane is flat against earth. As soon as you add any pitch or roll, that answer won't be right. To correct, you need to project the magnetic field vector onto your horizontal plane. Luckily, that sensor also provides you with an accelerometer which provides a way to tell you which way is down due to the force of gravity as long as you're not moving around too quickly.

What I did was project the magnetic field vector onto the acceleration vector then subtracted that from the magnetic field vector to get the horizontal component vector. Then I could retrieve the vector angle on the X/Y plane just as described by others.

First, a partial definition of a vector so I'm not depending on external libraries:

```
    class Vector3D
    {
    public:
        Vector3D() : mArr{} {}

        Vector3D(double x, double y, double z)
        {
            mArr[0] = x;
            mArr[1] = y;
            mArr[2] = z;
        }

        double dot(const Vector3D& rhs) const
        {
            double out = 0;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out = out + mArr[i] * rhs.mArr[i];
            }
            return out;
        }

        Vector3D operator* (double x) const
        {
            Vector3D out;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out.mArr[i] = mArr[i] * x;
            }
            return out;
        }

        Vector3D operator- (const Vector3D& x) const
        {
            Vector3D out;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out.mArr[i] = mArr[i] - x.mArr[i];
            }
            return out;
        }

        double getX() const {return mArr[0];}
        double getY() const {return mArr[1];}
        double getZ() const {return mArr[2];}

    private:
        static const int NUM_DIMENSIONS = 3;
        double mArr[NUM_DIMENSIONS];
    };

    Vector3D operator* (double x, const Vector3D& y)
    {
        return (y * x);
    }

```

Here is how the compass angle can be computed:

```
    // mag: magnetic vector
    // accel: acceleration vector (due to gravity)
    double computeYaw(double mag_x, double mag_y, double mag_z, double accel_x, double accel_y, double accel_z)
    {
        const Vector3D vector_mag(mag_x, mag_y, mag_z);
        const Vector3D vector_down(accel_x, accel_y, accel_z);
        const Vector3D vector_north = vector_mag - ((vector_mag.dot(vector_down) / vector_down.dot(vector_down)) * vector_down);
        return atan2(vector_north.getX(), vector_north.getY()) * 180 / M_PI;
    }

```

EDIT: I changed the code so needed elements of a Vector are defined here so there is no confusion.

EDIT2: Here is a good resource on this subject if you need a more accurate solution. As stated in this resource, the above is only really useful if you're not moving around too much and your magnetic environment is clean.

# Answer
> 3 votes
This is a basic math problem.

```
az=90-atan(y/x)*180/pi

```

"atan()" is arctangent and converts from coordinate variables to angle in radians, \*180/pi converts from radians to degrees, and 90- converts from degrees math angles (degrees CCW from the x axis) to azimuth (degrees CW from north).

Calibrating the sensor is a trickier problem.

---
Tags: magnetometer
---


# Question
Title: 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?m

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

# Answer
> 2 votes
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.

---
Tags: breadboard, bootloader, isp
---


# Question
Title: 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?

# Answer
~~I'm unable to test this now, but here goes:~~
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 itself:

```
// 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 this is used to set `SSD1306_LCDHEIGHT` to `32` in the header.

```
#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, `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:

```
#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:

```
#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.
> 3 votes

---
Tags: adafruit, oled
---


# Question
Title: 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?

# Answer
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: 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.
> 2 votes

---
Tags: arduino-pro-micro
---


# Question
Title: 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 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 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?

# Answer
> 2 votes
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!

---
Tags: i2c, arduino-due, eeprom, wire-library
---


# Question
Title: 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?

# Answer
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.
> 5 votes

---
Tags: arduino-uno, interrupt, timers, stepper
---


# Question
Title: 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:

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, 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 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...

# Answer
> 1 votes
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.

---
Tags: programming, atmega328, bootloader, uploading
---


# Question
Title: Whats common practice when using more components than there are pins?
I have a project where I want to use several motors (servo and stepper) which are activated with an RFID and show info on a display.

What’s common practice or a smart way to get past such limitations?

# Answer
> 7 votes
Basically there are 4 ways to go if you run out of pins:

* Change to a microcontroller board with more pins
* Arrange the parts in a smart way to save pins (like if you have many buttons or LEDs you could arrange them as a matrix)
* Use extra peripherals like shift registers, port expanders, PWM chips, ... which need less pins to be controlled
* Use extra microcontrollers to offload some function to them and just communicate over a data bus of your choice (like I2C or Serial) with less pins.

Which of the above is best for you depends on your project and your requirements. Here are some notes about the options:

* Choosing a bigger microcontroller is often the easiest solution, though you need to invest in buying it and rewrite and/or rewire your project. If you change to a different kind of microcontroller it might also involve searching for alternative libraries (since often libraries are not compatible across microcontroller types)
* Arranging buttons or LEDs in a matrix will save you pins, but you also create extra complexity for the software driving them since they need to be actively scanned through all the time. That will take new considerations regarding your program flow (keeping the program responsive using `millis()` and a non-blocking coding style like in the `BlinkWithoutDelay` example)
* With shift registers you need to buy the actual shift registers and with that commit to a data direction (since shift registers come as shift-in and shift-out registers) (as @Mat stated in the comments there are shift registers which support both ways, but they are more complex to use than the standard ones). If you drive something with them you also need to make sure to stay without the specific limitations of that shift register. You need 3 pins for them, but you can daisy chain them. So to drive 4 shift registers you just chain them and still use the 3 pins on your microcontroller. The Arduino Framework provides the `shiftIn()` and `shiftOut()` functions to control them.
* Port expanders usually come with either I2C or SPI interface and are more flexible than shift registers (like different data directions for the pins), but also cost a bit more and are a bit more difficult to control. The Arduino Framework doesn't have direct functions to control them. You can either use the `Wire` or `SPI` library directly (after reading and understanding the communication protocol in the datasheet of the port expander) or you might find a fitting third party library for your specific port expander.
* For driving extra motors or servos a PWM chip can be helpful. These are usually connected via I2C or SPI and can create PWM/servo signals on their outputs. For example the 16 Channel PWM Driver from Adafruit. There are lots of similar products out there, this is just the one, that comes to my mind.
* Using an extra microcontroller might sound a bit wasteful. But it can make things easier, especially if you have multiple things to control which overload the computation capabilities of your microcontroller (with an Uno you can easily get in that terrain). If you pursue this hobby for a while you will often have some microcontrollers lying around. You can get Arduino Nano clones from China for about 1€ per piece. Other microcontrollers are also not expensive. The advantage over the other methods is that you can offload a part of the code to the other microcontroller. While for peripherals like port expanders the logic still happens on your main controller, here you could write more complex logic into the second microcontroller. I used this one time for creating a user interface on a TFT display so that the main microcontroller was free to do its actual job. An additional advantage with extra microcontrollers is (like @Majenko wrote in the comments), that your code gets more modular. For example lets imagine you write code for the extra microcontroller to control the speed of a fan. Then you decide to add more fans to the project. With the modular design you can just add more fans and always take the same code. Or you might wanna add a fan to another project. Just take the existing code and integrate the interface to the second microcontroller in that project.

I hope this helps as an orientation. More definitive answers can only be given here, when you describe your exact situation.

# Answer
> 1 votes
There are several ways, but I recommend these:

1. MUXs/DEMUXs for I/O pins
2. Extra peripherals for special function like SPI, USART, ADC, and so on.

1: MUX and DEMUX can make you use more pins with little pins. For example, you can control extra 2^n pins with n pins. The advantage of MUX and DEMUX is that it respond immediately. However you have to use more pins if you want to control lots of pins and it can only control one pin at a time.

2: You can use additional peripherals to use specific functions like PWM, SPI, ADC and so on. The advantage of this method is that you can use more functions and, in some cases, you control lots of peripherals with less pins. Because of these good features, the peripheral devices are relatively expensive.

---
Tags: arduino-uno, breadboard, components
---


# Question
Title: 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 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?

# Answer
> 1 votes
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):

I got this image from the German wikipedia article on diodes. 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.

---
Tags: arduino-uno, teensy, shift-register, 7-segment
---


title: failed log in attempts on softAP

text:
# Question
Title: 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 - 0x%04x\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

arduino-esp32/libraries/WiFi/src/

default\_event\_loop

i guess i would like to hook into at least NOT\_AUTHED, 802\_1X\_AUTH\_FAILED from

WiFi Driver

# Answer
259 == `ESP_ERR_INVALID_STATE` according to this. 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:

```
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:

```
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:

```
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 votes

---
Tags: esp32, wifi, softap
---