# Question
Title: Mains And Battery Monitor Using Delay on And Delay off
I am very new to Arduino. In fact I am entirely new to embedded system. I have been using other platforms for my experiments specifically PICs.

I just moved to Arduino for more easier coding but I am hooked somewhere.

Here is the constraints:

In the code I will post below;

1. When MAINS is present and is within usable range, both MAINS\_OK & ENABLE Pins will go HIGH after 3sec delay(non-blocking).
2. When MAINS is BAD, MAINS\_OK Pin will go LOW immediately while ENABLE Pin will wait for 3sec before going LOW.
3. If MAINS is recovered and is within usable range again, the sequence described in "1." must be followed an so on.

I have tried in so many ways, it is not working as expected. Only the blinking of the SYSTEM LED is working fine.

```
// constants won't change. Used here to
// set pin numbers:
const int enablePin     = 7;      // the number of the Function Pins
const int lvdPin        = 6;
const int sysledPin    = 5;
const int mainsokPin   = 4;

// Variables will change:
int mainsPin = A0;
int batteryPin = A2;
int MAINS;
int BATT;
int ENABLE = LOW;
int LVD = LOW;
int SYS_LED = LOW;
int MAINS_OK = LOW; // State used to set the Function Pins

long previousMillis1 = 0;
long previousMillis2 = 0;// will store last time PIN was updated
long previousMillis3 = 0;
long previousMillis4 = 0;
long previousMillis5 = 0;

long ENABLE_ON        = 3000;
long ENABLE_OFF       = 3000;
long LVD_ON           = 3000;
long LVD_OFF          = 3000;
long MAINS_DELAY_ON   = 3000;
long MAINS_DELAY_OFF  = 0;
long SYS_LED_ON       = 1000;
long SYS_LED_OFF      = 1000; //Duration of the delay time (milliseconds)

void setup()
{
  pinMode(ENABLE, OUTPUT);  // set the digital pin as output:
  pinMode(LVD, OUTPUT);     // set the digital pin as output:
  pinMode(SYS_LED, OUTPUT); // set the digital pin as output:
  pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:
  pinMode(A0, INPUT); //set pin as Analog nput
  pinMode(A1, INPUT); //set pin as Analog nput
}
void loop()
{
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillis4 = millis();

  if ((SYS_LED == LOW) && (currentMillis1 - previousMillis1 >= SYS_LED_OFF))
  {
    SYS_LED = HIGH;  // Turn it off
    previousMillis1 = currentMillis1;  // Remember the time
    digitalWrite(sysledPin, SYS_LED);  // Update the actual SYS_LED
  }
  if ((SYS_LED == HIGH) && (currentMillis1 - previousMillis1 >= SYS_LED_ON))
  {
    SYS_LED = LOW;  // turn it on
    previousMillis1 = currentMillis1;   // Remember the time
    digitalWrite(sysledPin, SYS_LED);    // Update the actual SYS_LED
  }

  MAINS = analogRead(mainsPin);

  //========================= MAINS OK =======================================
  /* If MAINS supply is ok, the MAINS_OK and ENABLE Pins will wait for 3sec
      before going high. Both Pins will go high at the same time.
  */

  if (MAINS >= 84 && MAINS <= 177) // >=0.410V && <=0.864V >=140V && <=250V
    if ((MAINS_OK == LOW) && (currentMillis2 - previousMillis2 >= MAINS_DELAY_ON))
    {
      MAINS_OK = HIGH;  // Turn MAINS_OK on with 3sec delay
      previousMillis2 = currentMillis2;  // Remember the time
      digitalWrite(mainsokPin, MAINS_OK);  // Update the actual MAINS_OK
    }
  if (MAINS >= 84 && MAINS <= 177) // >=0.410V && <=0.864V >=140V && <=250V
    if ((ENABLE == LOW) && (currentMillis3 - previousMillis3 >= ENABLE_ON))
    {
      ENABLE = HIGH;    //Turn ENABLE ON with 3sec delay
      previousMillis3 = currentMillis3;  // Remember the time
      digitalWrite(enablePin, ENABLE);  // Update the actual MAINS_OK
    }

  //=================== MAINS NOT PRESENT or IT IS LOW/HIGH VOLTAGE ====================
  /* As soon as MAINS is lost, whether it enters low voltage or high voltage,
     the PINs MAINS_OK will go LOW imedatly without delay while ENABLE will wait for
     3sec before going LOW. Then If MAINS is restored OK, the initial delay sequence
     must be followed.
  */
  if (MAINS <= 53 || MAINS >= 258) // <= 0.260V || >=1.26V// Below <= 120V and >= 276V
    if ((MAINS_OK == HIGH) && (currentMillis2 - previousMillis2 >= MAINS_DELAY_OFF))
    {
      MAINS_OK = LOW;  // Turn MAINS_OK off after 0sec delay
      previousMillis2 = currentMillis2;  // Remember the time
      digitalWrite(mainsokPin, MAINS_OK);  // Update the actual MAINS_OK
    }
  if (MAINS <= 53 || MAINS >= 258) // <= 0.260V || >=1.26V// Below <= 120V and >= 276V
    if ((ENABLE == HIGH) && (currentMillis3 - previousMillis3 >= ENABLE_OFF))
    {
      ENABLE = LOW;    //Turn ENABLE off aftar 3sec delay
      previousMillis3 = currentMillis3;  // Remember the time
      digitalWrite(enablePin, ENABLE);  // Update the actual ENABLE
    }

  BATT = analogRead(batteryPin);

  //============================ BATTERYERY SETTINGS ==============================
  /* If Battery is below 21V LVD Pin go HIGH with 3sec delay
      When it goes high, it remains high the Batter goes up to 27.6V
      LVD will then go LOW ahter 3sec delay
  */
  if (BATT <= 391) //(1.91V) 21V         // BATTERY Low
    if ((LVD == LOW) && (currentMillis4 - previousMillis4 >= LVD_ON))
    {
      LVD = HIGH; //Turn LVD on with 3sec delay
      previousMillis4 = currentMillis4;  // Remember the time
      digitalWrite(lvdPin, LVD);  // Update the actual LVD
    }

  if (BATT >= 512) // (2.50V)  27.6V         // BATTERY low Recovery
    if ((LVD == HIGH) && (currentMillis4 - previousMillis4 >= LVD_OFF))
    {
      LVD = LOW; // turn LVD off after 3sec delay
      previousMillis4 = currentMillis4;  // Remember the time
      digitalWrite(lvdPin, LVD);  // Update the actual LVD
    }
}

```

Please What can I add or remove from this code for it to work properly?

Thanks.

# Answer
> 2 votes
There are lots of problems with your code. To start, most/all of this code is wrong:

```
  pinMode(ENABLE, OUTPUT);  // set the digital pin as output:
  pinMode(LVD, OUTPUT);     // set the digital pin as output:
  pinMode(SYS_LED, OUTPUT); // set the digital pin as output:
  pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:
  pinMode(A0, INPUT); //set pin as Analog nput
  pinMode(A1, INPUT); //set pin as Analog nput

```

Those lines should be setting various pins to their desired input/output state. However, you are using the variables you declared to hold their bool status, not their pin numbers.

The variables you are using are declared like this:

```
int ENABLE = LOW;
int LVD = LOW;
int SYS_LED = LOW;
int MAINS_OK = LOW; // State used to set the Function Pins

```

Those are not pin numbers, those are variables that hold boolean values.

This line, for example:

```
pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:

```

Should almost certainly read

```
pinMode(mainsokPin, OUTPUT); // set the digital pin as output:

```

Instead.

Same goes for `enablePin`, `lvdPin`, and `sysledPin`

The two lines

```
pinMode(A0, INPUT); //set pin as Analog nput
pinMode(A1, INPUT); //set pin as Analog nput

```

Should probably read

```
pinMode(mainsPin, INPUT); //set pin as Analog nput
pinMode(batteryPin, INPUT); //set pin as Analog nput

```

Since you define the variables `mainsPin` and `batteryPin`.

---
Tags: arduino-uno
---


# Question
Title: Which Arduino microcontrollers are able to drive a parallel 8-bit ILI9341 display at 320x240@60fps with DMA or extra CPU core or both and how?
I've always wanted to make my own game console. I don't know why the existing Arduino game consoles have this issue with framerate when a 2006's Sony handheld PC had 1GB of RAM and an Intel CPU running Windows XP. Why haven't normal DIY open-sourcing copyright-libertarian hobbyists been able to make something at that magnitude? Don't say money because money is the reason I'm in gamedev scene; wanting to make a game console or anything that has a screen, characters, multimedia and nerdiness to make money.

So the issue has always been how do I find a microcontroller that's enough fast to run a 320x240 display like ILI9341 at 60FPS without stuttering or having to do lots of precalculations for partial screen updates. What about the NES/SNES consoles which didn't even have a framebuffer but which used discrete logic?

* My scheme was to use ATXMEGA128A1U with a parallel bus and DMA, but it was hard to find a board containing all the stuff I needed and the External Bus Interface.
* Then I tried to use ESP32 with SPI, but SPI would go max to 80MHz while the screen could only handle 40MHz.
* Then I tried ESP32 again with 8-bit IO pin permutation which didn't work; it was too slow; maybe it would be faster if I used Xtensa assembly to take advantage of the CPU pipeline in case the dumb C++ compiler compiled machine code that waited 7 cycles for every next operation.
* But now I'd like to use ESP32 with an I2S bus and DMA which was used for a camera demo and it was really really fast, but I'd like to use it for I2S output for that ILI9341 display. According to my calculations, it should take 10MHz to write out all of the bytes if the bus is 16-bit wide (8 bits for data and 1 bit for Data/Command register) + Read/Write/Select strobes controlled by the bus interface. However, Bitluni has been able to drive it to out of spec values of 580MHz for his VGA library that's superfast, but that month he had nothing to pay his rent with so he licensed the code under a copyleft license (ShareAlike). You know what they say, "The love of money and the lack of money are the roots of all evil.". Money is important, but really... this just makes money an even worse enemy than it was before.

So I guess I'm out of options. There have been many attempts and they have failed. Yes, there's Teensy and stuff, but I need something in the EU which I won't have to pay for more in shipping than the actual product.

So, what are the solutions?

P.S. if I get one of those "off-topic" or "too-broad" or dislikes to my question, I'm deleting it and moving to Reddit and screenshooting how yet again StackExchange is just too formalistic and banhammersome to open conversations.

# Answer
The problem is the whole concept of running an ILI9341 TFT screen at 60FPS from a microcontroller. You can't. It's just not fast enough.

To get those kind of speeds you need to directly interface the TFT panel with the microcontroller. And that takes a special microcontroller with a TFT interface built in. As well as that you need the memory to store the image that you are displaying on the screen.

There are microcontrollers available that can do it quite happily. But they aren't in the "maker scene". Simply because they aren't a common thing to do.

For many years now there has been the PIC24 "DA" range of microcontrollers with a built in GPU and TFT interface - but there is no free C++ compiler, so no Arduino support - so no easy route to using them for beginners.

There are now, though, the PIC32MZ "DA" rage which are more accessible - though still very hard to use. These are much more viable for the kind of thing you want, with 32MB of built in DDR, a TFT panel interface, and available in a 144 pin TQFP chip that is possible for an experienced maker to hand solder.

But the barrier is still software. While chipKIT has full support for the PIC32MZ "EF" range of chips the "DA" range is not yet supported. That's not to say you can't work with them, just not with the Arduino API and IDE.

The more common way to make a games console like device is to take an ARM SoC and interface it with a TFT panel directly. The simplest way for a maker to do that is to put a TFT on a Pi and install Retropie.

And we're not against open discussion as people. It's the site. It's not a site for open discussion. It's a *question and answer site*. You ask a technical question that you need assistance with, and we tell you the answer. It's not a forum for general discussion. As such, this question will be closed as either "top broad" or "primarily opinion based". However your question does deserve an answer anyway.
> 1 votes

---
Tags: esp32, display
---


# Question
Title: Do we have an alternative for millis() function?
This is actually a follow up question to this question, so basically I'm using DS18B20 temperature sensor which requires Onewire.h library that interrupts millis() function.

Luckily i have a DS3231 RTC module which I'm using it with RTClib library, is there any way to use that module as a timer instead of millis() function?

# Answer
You can use the SQW output of the module to indicate the passage of precisely 1 second. Every time it transitions from LOW to HIGH one second will have passed.

RTCs cannot give you times of higher resolution than 1 second, but they can give you that 1 second granularity to a high accuracy.
> 1 votes

---
Tags: programming
---


# Question
Title: Is DS18B20 temperature sensor makes Arduino processing slow?
I recently run into a problem that causing my whole code processing slow down, for example i had a millis timer set for one minute but it took 1:30m to finish, pressing buttons was laggy etc.

After hours of digging and commenting out codes piece by piece i finally found out what is causing the slow down!

my DS18B20 temperature sensor DATA pin is connected to pin A0 when i remove the library and related codes to the sensor processing became MUCH faster more snappier/responsive...

After googling a bit i realized that everyone connected the sensor to pin 2 of Arduino!

So is the processing slow because DS18B20 is on pin A0 instead of pin 2 **or** there's something wrong with the sensor itself **or** it is because of This library?

# Answer
Indirectly it's the library.

That library uses the OneWire.h library. The OneWire protocol requires some reasonably precise timing, and because of the the OneWire.h library turns off interrupts while it communicates.

While interrupts are disabled nothing else can happen. That means that the timer interrupt that drives `millis()` can't "tick" - so the millis count doesn't increase while you communicate with the temperature sensor.
> 2 votes

# Answer
The **software function** managing the 1-wire protocol generally has several non-interruptable sections in order to ensure the bus timings. This can make your processor unavailable for long periods of time.

Worse, some implementations do not allow any interrupt at all.

And even if your implemenation would allow being interrupted, it is generally blocking the main loop as it is not executed in an interrupt itself.

Using a **hardware implementation** for the 1-wire control instead of a full software would release the CPU from managing the timing and waiting for the 1-wire to complete. But such hardware implementation are not commonly available in microcontrollers.

There is however a middle way. An open source implementation using **the microprocessor's or controller's UART** to ensure the timings is available ( https://github.com/MaJerle/onewire\_uart ) - MAXIM also has an application note for it ( https://www.maximintegrated.com/en/app-notes/index.mvp/id/214 ). This also offloads the processor and it can be interrupt driven.

**Is the processing slow because DS18B20 is on pin A0 instead of pin 2 ?** That might have an influence if the processor that is on your Arduino board would have a (partially) 1-wire compatible source on another pin, in which case the libary would have to take advantage of that.

**Is there something wrong with the sensor itself?** That would not be generally the case, but in case you have two sensors on the same bus, the 1-wire protocol is slower as it needs to find all peripherals and the master has to indicate which one it is addressing.

**Is it because of "This library"?** It is not because of that library, but there are other implementations (see the link above) that use hardware resources to improve performance at the cost of using a hardware resource (some MCU's have only 1 HW UART so you'ld not have a second one if you also need RS232 communication for instance on other signal lines).
> 1 votes

---
Tags: temperature-sensor
---


# Question
Title: How to control 220V RGB Led Strip with Arduino/ESP32
I need to control 220V RGB Led strip with Arduino/ESP32-wroom over internet. Single color led is easy (just with a relay), 12V RGB can be done with PWM and maybe external power source. But how can I control 220V RGB via MCU? I couldn't find any answer yet.

# Answer
Try looking at a relay or a triac.

Also, you can not simply "use PWM to control a 12V circuit from your MCU" which is most likely running at 5V. You need to use a component such as a MOSFET. The MCU controls the MOSFET via the Gate. The MOSFET switches the 12 V circuit off or on based upon the signal at the gate.

Alternatively, like the AC solution, you can use a Relay to control the 12V circuit.
> 0 votes

---
Tags: arduino-mega, esp32, rgb-led
---


# Question
Title: I want to code a depth sensor for arduino
I want to code a depth sensor for a little sub that i am working on. I want it to submerge to a any certain depth for example 2ft. The speed of the motor is to increase by 5 until it reaches the set point given. The problem that I am facing is: **whenever it reaches the set example point of 2ft the motor turns off and the sub resurfaces to the top and doesn't hold the depth .** What I want is that for whatever speed the motor is at for 2ft depth, to maintain its speed and keep the sub submerge at 2ft.

```
#include <MS5837.h>
#include <Wire.h>
#include "MS5837.h"
#include <Servo.h>
MS5837 sensor;
Servo vertical_thruster;

float x;
float error;
int pwm = 1525;
float currentdepth = sensor.depth();
float recquireddepth = -0.4;  //  set depth u wish to maintain in meters

void setup() {
      Serial.begin(9600);
     vertical_thruster.attach(6);
     vertical_thruster.writeMicroseconds(1500);
 /////////////////////////////////////////////Bar 30 Configuration ////////////////////////////////////////
  Serial.println("Starting");
  Wire.begin();
 while (!sensor.init()) {
    Serial.println("Init failed!");
    Serial.println("Are SDA/SCL connected correctly?");
    Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
    Serial.println("\n\n");
    delay(2000);
  }
  sensor.setModel(MS5837::MS5837_30BA);
  sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}

void loop() {

  sensor.read();
  Serial.print("Depth: ");
  Serial.print(currentdepth);
  Serial.println("m");
error = (currentdepth) - (recquireddepth) ;

if ( error!=0)
  { pwm +=5;
    vertical_thruster.writeMicroseconds(pwm+=5);
    Serial.println( pwm+=5);
    Serial.print ( " Submerging ");
  }
if ( error=0){
  vertical_thruster.writeMicroseconds(pwm);
  Serial.print ( "  At Depth");
}
else if ( error >-0){
  vertical_thruster.writeMicroseconds(1400);
  Serial.print ( "resurfacing");
  delay(1000);
}
}

```

# Answer
```
#include <MS5837.h>
#include <Wire.h>
#include <Servo.h>

MS5837 sensor;
Servo vertical_thruster;

// Variables

float current_depth ;
float set_depth = 0.30 ; //  depth u wish to go in meters
float PID_error = 0;
float previous_error = 0;
float elapsedTime,  Time , timePrev;
float pwmvertical_thruster;
int PID_value = 0;
int PID_p = 0;
int PID_i = 0;
int PID_d = 0;

//PID constants
float kp = 4.1;
float ki = 0.03;
float kd = 1.8;

void setup() {
  Serial.begin(9600);
 vertical_thruster.attach(6);
 Time = millis ();
 vertical_thruster.writeMicroseconds(1500);

///Bar 30 Configuration

 Serial.println("Starting");
 Wire.begin();
while (!sensor.init()) {
Serial.println("Init failed!");
Serial.println("Are SDA/SCL connected correctly?");
Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
Serial.println("\n\n\n");
delay(2000);
 }
 sensor.setModel(MS5837::MS5837_30BA);
 sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}

void loop() {

// First read the current value of the depth sensor
sensor.read();
current_depth = sensor.depth();

timePrev = Time;
Time= millis();
elapsedTime = ( Time - timePrev) / 1000;

// calculate the error between the set depth and current depth
PID_error =  set_depth - current_depth ;

// Calculate the P Value
 PID_p = kp * PID_error;

// Calculate the i value in a range on +-0.3

 if (-0.3 < PID_error < 0.3 )
  {
  PID_i = PID_i + (ki * PID_error);
  }

// Calculate the d value
PID_d = kd*((PID_error - previous_error)/elapsedTime);
// The total PID value
PID_value = PID_p + PID_i + PID_d;

// range for the blue robotics esc

 if ( PID_value < -400)
 {
 PID_value = -400;
  }
  if( PID_value >400)
  {
 PID_value = 400;
  }
// calcualte the pwm
 pwmvertical_thruster = (1500 + PID_value) || ( 1500 - PID_value);
if(pwmvertical_thruster < 1500)
 {
  pwmvertical_thruster= 1500;
  }
 if(pwmvertical_thruster > 1900)
  {
   pwmvertical_thruster=1900;
   }
    Serial.print("Depth: ");
    Serial.print(sensor.depth());
    Serial.println(" m");
    vertical_thruster.writeMicroseconds(pwmvertical_thruster);
    Serial. println ( "t\t");
    Serial. println ( pwmvertical_thruster);
     previous_error = PID_error;

   }`

```
> 0 votes

# Answer
Your code has several problems:

* You are including the MS5837 library twice. That just doesn't pose a problem, because the library has include guards, that make sure it is only included once.
* At global scope you use `float currentdepth = sensor.depth();`, which calls the function `sensor.depth()`. This will be done before the `setup()` function, so at that time the sensor library does not have any valid depth data. So it's useless. You can just set it to zero.
* In your `loop()` you are doing `sensor.read()`, but then you are never actually getting the new depth value from the library. You are just again using `currentdepth` without changing it ever. You should set the variable to the new value by using `currentdepth = sensor.depth();` after the `sensor.read()`.
* You are using the statement `if ( error=0)`. Using only a single `=` means an assigment. So here the variable `error` get's set to zero and the if statement will not compare it so zero. You have to use a double `=`: `if(error == 0)`.
* `if( error >-0)`: Why are you checking for error being greater than MINUS ZERO. Sure, -0 is a valid integer, but mostly senseless. Also it is questionable, if the logic is correct here, since first you check for error being different than zero. Then you check for it being zero and then (if it is not equal zero) you check for it being greater than zero. If `error` really happens to be greater than zero, you will first write `pwm` to the servo and then directly 1400, which is submerging and resurfacing directly after another in only one loop.
* The whole if structure seems quite off. You should rethink the logic of the program.

---

That said, for reaching a set point of whatever kind it is good to use a PID controller, that will get you to the setpoint rather fast and will keep you there. A PID controller can be done in hardware or software. For implementing a software PID controller on Arduino you can use one of the various PID libraries, for example this one. Most libraries also contain examples, that show how to use them.
> 2 votes

---
Tags: arduino-mega
---


title: Custom sleep function for Nextion

text:
# Question
Title: Custom sleep function for Nextion
I have a Nextion 7 inch enhance type display. I have enabled sleep using `thsp = 120` and `thup = 1` line of code. Now display become sleep mode after 2min, if there is no any touch event.

But, this sleeping is completely turn off the display.

I have several pages and I want to reset to a specific page, if there is no any touch event in any page instead of sleep function.

Greatly appreciate if someone can give a solution for this.

# Answer
I solved the problem using a Nextion timer. (tm0)

I got a timer and change `tim` value. ( unfortunately Nexion allow to maximum to 65535mS). `vscope` should be `globle`, otherwise you cant use timer in every page.

I reset the timer in page touch event. In timer event I put this code.

```
if(tm0.tim==60000) //reset time in mS
{
   page 0 //specific page to load
}

```
> 2 votes

# Answer
The Nextion screen has a command for this. It is called wup and defines the id of page that the screen should go to on wake from sleep. The default is set to 255, which means that the display wakes up on the page it was on before the sleep event.

```
16 wup Wake Up
 Page wup=2, n0.val=wup
Sets which page Nextion loads when exiting sleep mode
 min is 0, max is # of last page in HMI, or default 255
 When wup=255 (not set to any existing page)
– Nextion wakes up to current page, refreshing components only
 wup can be set even when Nextion is in sleep mode

```
> 2 votes

---
Tags: arduino-uno, display, sleep
---


# Question
Title: How do I properly trigger the ATMega328 reset pin via software so that the bootloader runs and the firmware can be updated via RX/TX pins?
I am programming my Atmega328P chip via a USB to TTL converter (https://www.amazon.com/gp/product/B075N82CDL/ref=ppx\_yo\_dt\_b\_asin\_title\_o01\_s00?ie=UTF8&psc=1)

I am able to upload hex files via the command line and the Arduino IDE when I have the RTS pin of the adapter and a capacitor attached to the !RESET pin of the Atmega. (http://www.electronics-lab.com/wp-content/uploads/2018/09/programming-Uno-on-breadboard.png)

I am also able to upload via the command line when I have a push button attached to the !RESET pin and manually pull it low then begin uploading the firmware within a few moments. (https://cdn.instructables.com/F0L/2F6U/J7AQSHD1/F0L2F6UJ7AQSHD1.LARGE.jpg)

My problem is that for my application I will only have the TX/RX/Vcc/GND pins available (no RTS or push button) and need to reset the micro controller so the bootloader runs and listens to be programmed with updated firmware.

So far I have written a batch file that sends a command to restart the Arduino, and then calls avrdude to upload a hex file. I have tried two methods of restarting the micro controller. I have told it to go to memory location zero, and I have attached an IO pin to the reset and dropped it low (although it stays low until reset, so the reset doesn't really work until I manually remove the wire between the IO pin and the !RESET pin)

My sequence is as follows:

1. Have Arduino running code:

```
    int recvByte;
    int delayS = 400;
    int resetPin = 9; //bttom right pin of uC

    void setup() {
      // put your setup code here, to run once:
    pinMode(txPin, OUTPUT);
    pinMode(rxPin, INPUT);
    pinMode(resetPin, OUTPUT);
    digitalWrite(resetPin, HIGH);
    Serial.begin(57600);
    Serial.write("Booted/reset");
    Serial.write("This setup was uploaded with batch");
    }

    void(* resetFunc) (void) = 0;

    void loop() {

    if (Serial.available() )
    {    // get incoming byte:
        recvByte = Serial.read();
        if (recvByte==int('r'))
        {
        Serial.write("resetting");
        delay(10); //wait for last message to send
        //digitalWrite(resetPin, LOW); //commented out because this method stays low until wire is removed
        resetFunc();
        Serial.write("should not see if reset properly");
        }

    }

    delay(100);
    }

```

2.I then run my batch file.

```
echo Running upload bat, sending reset command then calling avrdude
cd "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\"
python "path\sendR.py"
.\avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i

```

The python sendR.py is to send the "r" character, which the Arduino views as the reset command.

```
import serial
ser = serial.Serial("COM6", baudrate=57600)  # open serial port
bytes = "r".encode()
ser.write(bytes)
ser.close()
print("End python script")

```

When I send "r" via Tera Term or python the setup code runs again, but I have not been able to upload with the `.\avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i` command inside the batch file. If I use the pushbutton to do a hardware reset, this command works without issue.

How can I upload new firmware via the RX and TX pins using software to reset the microcontroller and listen for new code as the bootloader runs?

New ideas tried: Use a uniform baud rate of 57600 in python and atmega serial setup. I chose this value because the Arduino IDE output this baudrate in `avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i`

# Answer
You wrote:

> `void(* resetFunc) (void) = 0;`

This seems to me like an approach worth trying, except that the function address is wrong. At address zero of the flash you have the start of the user's code. The bootloader, if you do use one, lives at the end of the flash. The start address of the bootloader depends on its size, and is configured by setting some fuses on the chip. If you are using the popular optiboot (the bootloader of the Uno), you have to jump to exactly 512 bytes before the end of the flash, i.e.:

```
void (*resetFunc)(void) = 0x7e00;

```

Oh, wait... the flash is organized as 16-bit words, so you may have to use the wordwise address instead:

```
void (*resetFunc)(void) = 0x3f00;

```

But do note that, unlike a real hardware reset, this approach does not reset the peripherals to their normal initial state. You may want to do it before jumping to the bootloader.

---

**Edit**: I have disassembled a test program that does this kind of call-by-pointer, then double checked the documentation of the `icall` instruction. It appears that the function address you provide is indeed interpreted as a word-wise address, so you should write half the byte-wise address. If you write anything larger than the size of the flash (`0x4000` = 16 kilowords), the most significant bits get lost, and the address gets reduced to the correct range modulo the flash size.

That is, if `0x7800` worked for you, then presumably the correct address is `0x3800`, i.e. 2 kilowords (4 KB) before the end of the flash. This is quite a large bootloader, and the largest size supported by the ATmega328P. Are you sure it is righ? Aren't you sliding through some uninitialized flash before hitting the bootloader? Here is a table that gives the bootloader's start address as a function of the amount of memory reserved for it:

```
reserved size  start address
    512 B         0x3f00
     1 KB         0x3e00
     2 KB         0x3c00
     4 KB         0x3800

```

Note that the Arduino Uno uses optiboot, which fits into the smallest size that can be allocated to a bootloader (512 bytes).
> 0 votes

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


# Question
Title: Why is Serial.write() slower than memcpy()?
I use `Serial.write()` to transmit 53 bytes to PC. For the time measurement I use `micros()` (before and after the write function). There is a delay of 1s after each transmission.

The time of the `Serial.write()` function is 532 us with 1000000 baud rate, and 360 us with 9600 baud rate.

The `Serial.write()` function is clearly asynchronous because the transmission of 53 bytes with 9600 baud rate is 53\*8/9600\*1e6 = 44167 us. (By the way, in the case of 1000000 baud rate, it is not so obvious that the function is asynchronous.)

I use `Serial.availableForWrite()` before `Serial.write()` to confirm that there is enough space in the buffer (this returns 63 each time, the buffer size is default 64).

I don't understand these numbers. Using `memcpy()` to copy the 53 bytes only takes 32 us. Is copying to the serial buffer not the same as the `memcpy()` function? And why is there a difference in the copy times when the baud rate is different? Serial.write() is even slower with higher baud rates according to the results. Why does `Serial.availableForWrite()` return 63 while the buffer size is 64 (according to SERIAL\_TX\_BUFFER\_SIZE)?

Update: Thanks for all of your answers.

I have tried another library for serial communication: https://github.com/greiman/SerialPort

It seems to be faster than the original one. I use 2 time measurements and a delay in the code, these 3 deltaTimes represents the whole step as follows:

writeTime + memcpyTime + delaymicros = computedTime != realTime

The first 2 times are measured, the delaymicros is the theoretical delay (900 us), I can compute the step time from these. This computed step time is different from realTime (the measured step time, I measure the whole step too). It seems that the additional time can be found in the delay.

SerialPort library: 100 + 30 + 900 = 1030 != 1350

writeReal = 100 + 1350 - 1030 = 430

Arduino Serial: 570 + 30 + 900 = 1500 != 1520

writeReal = 570 + 1520 - 1500 = 590

Then I measured the delaymicros time (which is 900 us in theory), the missing time can be found there. I programmed 900 us delay, but the real delay was around 1200 in the first, and 920 in the second test.

These measurements can prove the existence of the interrupts, because measuring only the write functions doesn't give all of the writing time (especially with the downloaded serial library). The downloaded library can work faster, but requires bigger tx buffer because of errors (256 works properly instead of 64).

Here is the code: I use a checkSum in the sendig function (which is 570-532 = 38 us). I use Simulink to receive and process the data.

```
struct sendMsg1 {
  byte errorCheck;//1

  unsigned long dT1;//4
  unsigned long dT2;//4
  unsigned long t;//4
  unsigned long plus[10];//40
};//53

sendMsg1 msg1;
byte copyMsg1[53];

unsigned long time1;
unsigned long time2;
unsigned long time3;
unsigned long time4;

void setup() {
  Serial.begin(1000000);
}

void loop() {
  sensorRead();
  sendMsg1_f();

  //time3 = micros();
  delayMicroseconds(900);
  //time4 = micros();
}

void sensorRead() {
  time3 = micros();

  msg1.t = micros();
  for (unsigned long i = 0; i < 1; i++) {
    memcpy((void*)&(copyMsg1[i*sizeof(sendMsg1)]), (void*)&msg1, sizeof(sendMsg1));
  }

  time4 = micros();
  msg1.dT2 = time4 - time3;
}

void sendMsg1_f() {
  time1 = micros();

  msg1.errorCheck = 0;
  for (int i = 0; i < sizeof(sendMsg1) - 1; i++) {
    msg1.errorCheck += ((byte*)&msg1)[i];
  }
  Serial.write((byte*)&msg1,sizeof(sendMsg1));

  time2 = micros();
  msg1.dT1 = time2 - time1;
}

```

# Answer
> 2 votes
If you take a look into the implementation:

```
size_t HardwareSerial::write(uint8_t c)
{
  _written = true;
  // If the buffer and the data register is empty, just write the byte
  // to the data register and be done. This shortcut helps
  // significantly improve the effective datarate at high (>
  // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
  if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
    // If TXC is cleared before writing UDR and the previous byte
    // completes before writing to UDR, TXC will be set but a byte
    // is still being transmitted causing flush() to return too soon.
    // So writing UDR must happen first.
    // Writing UDR and clearing TC must be done atomically, otherwise
    // interrupts might delay the TXC clear so the byte written to UDR
    // is transmitted (setting TXC) before clearing TXC. Then TXC will
    // be cleared when no bytes are left, causing flush() to hang
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      *_udr = c;
#ifdef MPCM0
      *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
#else
      *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
#endif
    }
    return 1;
  }
  tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;

  // If the output buffer is full, there's nothing for it other than to
  // wait for the interrupt handler to empty it a bit
  while (i == _tx_buffer_tail) {
    if (bit_is_clear(SREG, SREG_I)) {
      // Interrupts are disabled, so we'll have to poll the data
      // register empty flag ourselves. If it is set, pretend an
      // interrupt has happened and call the handler to free up
      // space for us.
      if(bit_is_set(*_ucsra, UDRE0))
    _tx_udr_empty_irq();
    } else {
      // nop, the interrupt handler will free up space for us
    }
  }

  _tx_buffer[_tx_buffer_head] = c;

  // make atomic to prevent execution of ISR between setting the
  // head pointer and setting the interrupt flag resulting in buffer
  // retransmission
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    _tx_buffer_head = i;
    sbi(*_ucsrb, UDRIE0);
  }

  return 1;
}

```

It basically answers all the questions.

If the buffer is empty and it's not sending anything, it'll send the character directly so it's synchronous (but sending the character will be much faster than overhead of function callbacks and so)

No, you cannot use memcpy, as it just replaces buffer, but it does nothing else, like actually start the data register ready interrupt nor proper setting of head/tail counters (it's round buffer, so there can be scenario you'll overwrite something outside of buffer)

And write function is called for each character separately (all other specialisation of write are using this one)

Also if the buffer is full, it'll wait until there is a space for another character.

# Answer
> 1 votes
Copying to the serial buffer is not the same as `memcpy()`, no.

The serial buffer is a circular buffer. Because of that there are lots of calculations involved in working out exactly where in the buffer to place the next character. That takes time. `memcpy()` just copies one block of memory directly over another. It makes no checks, and it can't wrap around like a circular buffer.

The reason why higher baud rates seem slower is because each character is taken from the buffer by an interrupt. The higher the baud rate the more often that interrupt is triggered, and so the more time is spent by the CPU in processing that interrupt to send the next character. And equally, the less time is available to the CPU to process the placing of data into to the serial buffer.

# Answer
> 1 votes
The function you were testing is presumably `Serial.write(const uint8_t *buffer, size_t size)`. If you search for it in HardwareSerial.h, you will see

```
    using Print::write; // pull in write(str) and write(buf, size) from Print

```

and the implementation is in Print.cpp:

```
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
  size_t n = 0;
  while (size--) {
    if (write(*buffer++)) n++;
    else break;
  }
  return n;
}

```

This is writing the bytes one by one, and for every byte, the whole code of `HardwareSerial::write(uint8_t c)` is being run. This includes the tests for full or empty buffer, and the arithmetic for updating `_tx_buffer_head`.

As stated in the comment above the code, it would have been possible to override this with a specialized implementation. In principle, you could copy the linear buffer into the ring buffer using at most two calls to `memcpy()`, and updating `_tx_buffer_head` only once. That would likely be more efficient than the current implementation, at least for buffer sizes in the range you are using (close to, but less than the ring buffer capacity).

Would it be worth it? Maybe for your use case it would. But it could also make the code more complex and require more flash. And the benefit is likely to be really small for people who write small buffers. I am not sure a pull request implementing this sort of optimization may be accepted. You may try if you feel like so.

---
Tags: serial, arduino-nano
---


# Question
Title: My stepper motor connected to a driver and an Arduino is not working
I'm using a 28BYJ-48 stepper motor with a ULN2003 driver board. I'm trying to control the motor using an Arduino MEGA. I initially connected the pins on the driver: IN1,2,3,4 to pins of the Arduino: 8,9,10,11 respectively; as was given in a youtube video I referred to(https://www.youtube.com/watch?v=HdqCtAJxhrs). The power for the motor was given from the 5V and GND ports in the Arduino. What happens is that it rotates 180 degrees,and then stops and then goes at random angles and stops. This was the code:

```
#include <Stepper.h>

Stepper stepper1(64,8,9,10,11);
int a=1;

void setup() {
  stepper1.setSpeed(50);
}

void loop() {
  while(a<10){
    stepper1.step(2048);
    delay(1000);
    a++;
  }
}

```

# Answer
For those who missed the comments, what I made a mistake in, as @JRobert pointed is that I was suppose to have connected the stepper motor to a separate power supply as the Arduino was not capable of so much resources. I also altered the code as I think I had gotten the steps-per-revolution wrong which is needed in the Stepper function in the Arduino Code. One needs to check this with the datasheet or somewhere online for the respective stepper motor model. The final code that got it working is here. All thanks to @JRobert for helping me figure out the solution :)
> 2 votes

---
Tags: arduino-mega, stepper-motor
---


# Question
Title: Writing to sd card with a sampling rate 50ms or less? I have a sketch that writes to sd every 1s but jams at faster sampling rates. Please help?
My code below reads data from an ADC and 3 digital pins via a Mega and prints to an SD Shield (Deek Robot). I want to be able to read the data every 50ms (20ms ideally). I can't get below 250ms.

I've read countless forum posts regarding the same issue and understand that I need to create 2x 512 byte buffer, store data to one while the other is being written to the SD card. A forum post mentioned using the Adafruit GPS library for an example of double-buffering but I can't seem to find it. Another suggests changing the internal buffer from 64bytes to 256bytes in hardwareserial.cpp but I can't even navigate to it on my w\***ows laptop.

I've run dataString.Length and the max length is 38 for the 8 columns of data, plus a long (for recording ms) another byte for the "\t" and 3 bytes of headroom = 46bytes in all, round it up to 50bytes/sample at a 50ms sampling rate is 1000bytes/second. Darn it, I forgot to add the separating-commas between the columns = plus another 7 bytes; call it 55 in total = 1100bytes/second. I know it can be done but I can't do it; not at my current knowledge/skill level.

Thank you in advance for your help.

```
//include relevant libraries
#include <EnableInterrupt.h>
#include <SPI.h>
#include <SD.h>

//globally define pins
#define BUSY 3    //purple*
#define RD 4      //yellow* RD+CS tied together
#define RESET 5   //grey*
#define CONVST 6  //green* CONVSTA+CONVSTB soldered together on the board
#define RANGE 7   //blue*   *not permanent - double check!!!*

#define DB0 22
#define DB1 23
#define DB2 24
#define DB3 25
#define DB4 26
#define DB5 27
#define DB6 28
#define DB7 29
#define DB8 30
#define DB9 31
#define DB10 32
#define DB11 33
#define DB12 34
#define DB13 35
#define DB14 36
#define DB15 37

//byte statusLed       = 13;
byte sensorPin1       = 38;
byte sensorPin2       = 40;
byte sensorPin3       = 42;

int sensorValue[8];
int rawData[16];
//change the size  of these arrays to match the amount of channels being read by the ADC
int adcChannel[5];
int adcData[5];
int channelCount=5;

volatile byte pulseCount1;
volatile byte pulseCount2;
volatile byte pulseCount3;

int pulses[3];

// cs pin for sd-shield *NB 53 for Mega
const int chipSelect = 53;
// SCK 52
// MISO 50
// MOSI 11

unsigned long oldTime;

void setup() {             //set up the hardware

  Serial.begin(9600);
  //sd card.....
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  enableInterrupt(BUSY, bitBang, FALLING);

  oldTime            = 0;

  pinMode(DB0, INPUT_PULLUP);
  pinMode(DB1, INPUT_PULLUP);
  pinMode(DB2, INPUT_PULLUP);
  pinMode(DB3, INPUT_PULLUP);
  pinMode(DB4, INPUT_PULLUP);
  pinMode(DB5, INPUT_PULLUP);
  pinMode(DB6, INPUT_PULLUP);
  pinMode(DB7, INPUT_PULLUP);
  pinMode(DB8, INPUT_PULLUP);
  pinMode(DB9, INPUT_PULLUP);
  pinMode(DB10, INPUT_PULLUP);
  pinMode(DB11, INPUT_PULLUP);
  pinMode(DB12, INPUT_PULLUP);
  pinMode(DB13, INPUT_PULLUP);
  pinMode(DB14, INPUT_PULLUP);
  pinMode(DB15, INPUT_PULLUP);

  pinMode(RESET, OUTPUT);
  pinMode(CONVST, OUTPUT);
  pinMode(RD, OUTPUT);
  pinMode(RANGE, OUTPUT);
  pinMode(BUSY, INPUT);

  //reset ADC to begin conversion
  digitalWrite(RESET, HIGH);
  delayMicroseconds(10);
  digitalWrite(RESET, LOW);

  digitalWrite(CONVST, LOW);
  digitalWrite(RD, HIGH);
  digitalWrite(RANGE, LOW);
  digitalWrite(BUSY, LOW);

  delayMicroseconds(100);

  // Set up the status LED line as an output
//  pinMode(statusLed, OUTPUT);
//  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached

  pinMode(sensorPin1, INPUT);
  digitalWrite(sensorPin1, HIGH);

  pinMode(sensorPin2, INPUT_PULLUP);
  digitalWrite(sensorPin2, HIGH);

  pinMode(sensorPin3, INPUT_PULLUP);
  digitalWrite(sensorPin3, HIGH);

  pulseCount1        = 0;
  pulseCount2        = 0;
  pulseCount3        = 0;

  oldTime            = 0;

  // the hall effect sensors are configured to trigger on a FALLING state change
  // (transition from HIGH state to LOW state)
  enableInterrupt(sensorPin1, pulseCounter1, FALLING);
  enableInterrupt(sensorPin2, pulseCounter2, FALLING);
  enableInterrupt(sensorPin3, pulseCounter3, FALLING);

}

void loop() {

  //change this value to preffered sampling rate
  if ((millis() - oldTime) == 50) {

    oldTime = millis();

    //Serial.print(millis());
    //Serial.print("\t");

    //tell ADC to start read (converting analogue input to digital output)
    delayMicroseconds(10);
    digitalWrite(CONVST, LOW);
    delayMicroseconds(10);
    digitalWrite(CONVST, HIGH);
    //when read-conversion is complete ADC sends the BUSY pin low triggering the bitBang ISR

    //print ADC data from array within the bitBang ISR to a string
    String adcString = "";
    for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
      adcString += String(adcData[thisChannel]);
      adcString += ",";
    }

    //disable interrupt to access current pulse count
    disableInterrupt(sensorPin1);
    disableInterrupt(sensorPin2);
    disableInterrupt(sensorPin3);
    //grab current pulse count and store in a variable
    pulses[0] = pulseCount1;
    pulses[1] = pulseCount2;
    pulses[2] = pulseCount3;
    //reset pulse count
    pulseCount1 = 0;
    pulseCount2 = 0;
    pulseCount3 = 0;
    //enable interrupt and start incrementing pulse count again
    enableInterrupt(sensorPin1, pulseCounter1, FALLING);
    enableInterrupt(sensorPin2, pulseCounter2, FALLING);
    enableInterrupt(sensorPin3, pulseCounter3, FALLING);

    String pulseString = "";
    for(int i=0; i<3; i++){
      pulseString += String(pulses[i]);
      if (i<2) {
        pulseString += ",";
      }
    }

   String dataString = String(adcString + pulseString);
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("dataLog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.print(millis());
    dataFile.print(",");
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    //Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening dataLog.txt");
  }

 //Serial.println(dataString);

  }
//start again
}

//grabbing ADC data ISR (for n channel)
void bitBang ()  {
  //a for loop to bitbang the values fom the analogue (ADC) channels (maximum 8) sequentially storing them in a variable array (equal to the channels of the ADC)
  for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
  //send ADC read pin low to bitbang the first channel
  digitalWrite(RD, LOW);
  //read the state of the 16 pins and store in a variable
  rawData[0] = digitalRead(DB15);
  rawData[1] = digitalRead(DB14);
  rawData[2] = digitalRead(DB13);
  rawData[3] = digitalRead(DB12);
  rawData[4] = digitalRead(DB11);
  rawData[5] = digitalRead(DB10);
  rawData[6] = digitalRead(DB9);
  rawData[7] = digitalRead(DB8);
  rawData[8] = digitalRead(DB7);
  rawData[9] = digitalRead(DB6);
  rawData[10] = digitalRead(DB5);
  rawData[11] = digitalRead(DB4);
  rawData[12] = digitalRead(DB3);
  rawData[13] = digitalRead(DB2);
  rawData[14] = digitalRead(DB1);
  rawData[15] = digitalRead(DB0);
  //convert into 16bit 2s compliment and store in a variable array
  adcData[thisChannel] = rawData[0] | (rawData[1] << 1) | (rawData[2] << 2) | (rawData[3] << 3) | (rawData[4] << 4) | (rawData[5] << 5) | (rawData[6] << 6) | (rawData[7] << 7) |  (rawData[8] << 8) | (rawData[9] << 9) | (rawData[10] << 10) | (rawData[11] << 11) | (rawData[12] << 12) | (rawData[13] << 13) | (rawData[14] << 14) | (rawData[15] << 15);
  //send ADC pin high to say we have read the first channel
  digitalWrite(RD, HIGH);
  //repeat for n channels
  }
}

//counting pulses ISRs
void pulseCounter1(){
  // Increment the pulse counter
  pulseCount1++;
}
void pulseCounter2(){
  // Increment the pulse counter
  pulseCount2++;
}
void pulseCounter3(){
  // Increment the pulse counter
  pulseCount3++;
}

```

# Answer
> 2 votes
So it turns out the actual problem was this line of code `if ((millis() - oldTime) == 50) {` it needed to be changed to `if ((millis() - oldTime >= 50) {`

I really appreciate all the help everyone gave me to get to the bottom of it and especially thankful to @Michel for handing some solid advice to someone who isn't in the know. Hopefully I will be able to repay in kind to another learner one day. :D

# Answer
> 4 votes
Some tips:

* Do not open the open and close the file in every loop sequence (I think you can use the `flush` command to save/update the file.
* Do not save strings, but save the raw data and pulse string. This will take 16 * 2 (raw data + 3 bytes for the pulse data = 35 bytes per 16 samples, meaning 35 bytes/samples * 20 samples/s = 700 bytes (I think your calculation of 1100 bytes is incorrect).
* Try to avoid string, and even more string concatenation. I don't know if this will be the bottleneck, but in any case String operations are expensive and for concatenation there is a chance (or is always the case) that memory needs to be allocated dynamically. Use a string buffer instead.

---
Tags: arduino-mega, interrupt, spi, sd-card, datalogging
---


title: Remove Function at Preprocessor Time

text:
# Question
Title: Remove Function at Preprocessor Time
I have a single function for debugging messages, used through all the project. When `KEYDEBUG` is defined as `1` or `0`, the function is enabled or disabled as required.

```
#define KEYDEBUG 0

void debugging(int var){
   #if KEYDEBUG
   //Assert
   #endif
}

```

When checking the compiler, the variable `var` raises a warning `-Wunused-parameter`. How should remove this warning just at this part of the project? Or which other alternative for using debugging code and removing it from memory for production release?

# Answer
> 2 votes
In your case you do not use the entire body, so you can use a macro.

This way the code when KEYDEBUG is 0, will be like the complete function would not exist (except for the void cast, see below).

```
#include "assert.h"

#define KEYDEBUG 0

#ifndef KEYDEBUG
#define debugging(x) void(x);
#endif

void debugging(int var){
   assert(var);
}

void setup() {
  // put your setup code here, to run once:
  debugging(1);
}

```

---

The information below is for not using the function parameter, but keep the function (in case you have code in your function that also does something when KEYDEBUG is 0.

**Unused attribute**

The cleanest way I could find is using the unused attribute:

```
#if KEYDEBUG
   void debugging(__attribute__((unused)) int var){
      //Assert
#else
   void debugging(int var){
      //Assert
#endif
   }

```

or if you prefer better readability:

```
#if KEYDEBUG
   void debugging(__attribute__((unused)) int var){
      //Assert
   }
#else
   void debugging(int var){
      //Assert
   }
#endif

```

**Cast to void**

Less clean but does the job:

```
void debugging(int var){
   #if KEYDEBUG
      //Assert
   #else
      (void) var; // prevent unused parameter warning
   #endif
}

```

**Macros/Parameter**

It's not easy to remove the variable since it's used in a function and will be called from many places probably. You could maybe you use a macro but that gets messy soon.

This solution works, and afaik the compiler will optimize the code out (if not , it will cost very less anyway).

---
Tags: compilation-errors, functions, c-preprocessor
---


title: DS18B20 with only OneWire library

text:
# Question
Title: DS18B20 with only OneWire library
Peter Scargill found a way to use a DS18B20 temperature sensor only using the OneWire library, and it's amazing how blazing fast it is! *(It's an old article from 2013.)*

```
#include <OneWire.h>

int16_t dallas(int x,byte start) {
  OneWire ds(x);
  byte i;
  byte data[2];
  int16_t result;
  do {
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    for (int i = 0; i < 2; i++)
      data[i] = ds.read();
    result = (data[1] << 8) |data[0];
    result >>= 4;
    if (data[1]&128)
      result |= 61440;
    if (data[0]&8)
      ++result;
    ds.reset();
    ds.write(0xCC);
    ds.write(0x44, 1);
    if (start)
      delay(1000);
  } while (start--);
  return result;
}

void setup () {
  dallas(A0,1);
}

void loop () {
  float currentTemp = dallas(A0, 0);
}

```

The problem is the accuracy; he converts float to int to get an accuracy of 1°C and it's working just fine.

How can I get an accuracy of 0.5°C (or 0.2°C) using this semi library?

# Answer
Actually he isn't really converting `float` to `int`. He never uses `float` since he doesn't need it. The datasheet of the DS18B20 shows at page 6 how the data is formatted:

1. The 4 highest bits just resemble the sign bit 11.
2. The first digit with full degrees is bit 4. Every bit below that has values below 1°C

So the data bytes `0b1111100001010000` will represent a temperature of -123°C and `0b1111100001011000` -122.5°C.

The author from the link then shifts this data 4 bits to the right, so that all bits representing values under 1 vanish. You can convert the received value per hand to `float` by also using this.

```
int16_t whole_degree = (result & 0x07FF) >> 4;
float temperature =
whole_degree +
0.5 * ((data[0]&0x8)>>3) +
0.25 * ((data[0]&0x4)>>2) +
0.125 * ((data[0]&0x2)>>1) +
0.0625 * (data[0]&0x1);
if (data[1]&128)
  temperature *= -1;

```

As float does not have the same structure as the data, we need to convert it. So I first calculate the number of whole degrees analog to your code. Then I add this up with the values of the lowest 4 bits. `((data[0]&0x8)>>3)` and its siblings will be 1, when the corresponding bit is set, and 0, if not.

So you get the full precision of the sensor (12 bits). Please note that for this to work, you should not configure the sensor to less resolution. In that case you would have to ignore the corresponding lowest bits. But the sensor is in 12 bit mode at power up anyway and your code does not configure it otherwise.

Note: I'm unsure about the line `result |= 61440;` in the original code. This sets the 4 highest bits of a 16 bit value to 1. I don't see why this should be correct here, since a normal 16-bit integer does only have 1 sign bit. In my understanding the original code would lead to false readings (way off), when reading temperatures below zero. I instead simply multiplied the resulting temperature with `-1`.

The whole code would look like this (I also added the statement for printing out the pure received data as binary, as I requested it in my comment. These statements are currently commented out):

```
#include <OneWire.h>

float dallas(int x,byte start) {
  OneWire ds(x);
  byte i;
  byte data[2];
  int16_t result;
  float temperature;

  do {
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    for (int i = 0; i < 2; i++)
      data[i] = ds.read();
    result = (data[1]<<8) |data[0];
    // Here you could print out the received bytes as binary, as requested in my comment:
    // Serial.println(result, BIN);
    int16_t whole_degree = (result & 0x07FF) >> 4; // cut out sign bits and shift
    temperature = whole_degree +
    0.5 * ((data[0]&0x8)>>3) +   // 0.5    = 2^-1
    0.25 * ((data[0]&0x4)>>2) +  // 0.25   = 2^-2
    0.125 * ((data[0]&0x2)>>1) + // 0.125  = 2^-3
    0.0625 * (data[0]&0x1);      // 0.0625 = 2^-4
    if (data[1]&128)
      temperature *= -1;
    ds.reset();
    ds.write(0xCC);
    ds.write(0x44, 1);
    if (start)
      delay(1000);
  } while (start--);
  return temperature;
}

void setup {
  // Adding Serial.begin(9600); for printing the received bytes here
  //Serial.begin(9600);
  dallas(A0,1);
}

void loop {
  float currentTemp = dallas(A0, 0);
}

```
> 4 votes

# Answer
Why not rewrite the dallas() function so that it returns a float?

```
#include <OneWire.h>

OneWire ds(A0);

float dallas(OneWire& ds, byte start = false) {
    int16_t temp;
    do {
        ds.reset();
        ds.write(0xCC);
        ds.write(0xBE);
        ds.read_bytes((uint8_t*) &temp, sizeof(temp));
        ds.reset();
        ds.write(0xCC);
        ds.write(0x44, 1);
        if (start) delay(1000);
    } while (start--);
    return (temp * 0.0625);
}

void setup {
  dallas(ds, true);
}

void loop {
  float currentTemp = dallas(ds);
}

```
> 1 votes

---
Tags: programming, sensors
---


title: HardwareSerial Indexing Array

text:
# Question
Title: HardwareSerial Indexing Array
How should I index HardwareSerial ports into a single array?.

This compiles, but do not work.

```
HardwareSerial Serials[]={Serial,Serial1,Serial2,Serial3};

void setup(){
    for (int i=0;i<=3;i++){
        Serials[i].begin(38400);
        while (!Serials[i]);
    }
}

char s;
void loop(){
    for (int i=0;i<=3;i++){
        if (Serials[i].available()){
            s=Serials[i].read();
            Serials[i].write(s);
        }
    }
}

```

# Answer
> 5 votes
your code makes copies of Serials into items in the array of HardwareSerials. To use the original Serial objects, store and use pointers.

```
HardwareSerial* Serials[]={&Serial,&Serial1,&Serial2,&Serial3};

void setup(){
    for (int i=0;i<=3;i++){
        Serials[i]->begin(38400);
        while (!*Serials[i]);
    }
}

void loop(){
    for (int i=0;i<=3;i++){
        if (Serials[i]->available()){
            char s=Serials[i]->read();
            Serials[i]->write(s);
        }
    }
}

```

---
Tags: serial, array
---


# Question
Title: Float to String Convert in Udp.write() in esp8266
I want to convert float value to String for send **Udp.Write()** method and receive another side (esp) with **Udp.read()** and Copy in the one Variable for use ..

**please** help me **Thanks for every answer ^\__^**

code :

```
void loop () {
    int signal = analogRead (A0) ;
    float Adc = (signal * 3.3) / 4096 ;
    Udp.beginPacket ({192,168,4,1} , 1234) ;
    Udp.write ( " please help me fill this section ") ;
    Udp.endPacket () ;
}

```

---

*i have one more problom . . .*

*and in the other side:*

i want take the**Adc** value from **esp1** and **convert char to float** for **Dac**

(*digital analog converter*) with *MCP4725* ..

\** i just need put in float value of Adc in a variable for convertation use ..\**

*code*:

**void loop ( ) {**

```
int noBytes = Udp.parsePacket();

String received_command = "";

if ( noBytes ) {

  Udp.read(packetBuffer,noBytes);

  for (int i=1;i<=noBytes;i++){

  received_command += char(packetBuffer[i - 1]);
}

Serial.print("packaet receive: ");

Serial.println(received_command);

float Adc_value_received = float(received_command); //*helpppp please char-to-float convert*

```

**}**

*thanks from everyone* ^\__^

# Answer
The Arduino String class can be used to convert to a character string.

```
void loop () {
    int signal = analogRead (A0) ;
    float Adc = (signal * 3.3) / 4096 ;
    String msg = String(Adc, 3);

    Udp.beginPacket ({192,168,4,1}, 1234) ;
    Udp.write(msg.c_str());
    Udp.endPacket () ;
}

```
> 0 votes

---
Tags: esp8266
---


# Question
Title: Code that worked in Uno is not working in Mega 2560
I send data with Android and read it from the Arduino serial screen. When I use UNO, I can read the data smoothly. When I use MEGA, it uploads the code without error, but does not transfer data on the serial screen. Can you tell me why?

```
#include <SoftwareSerial.h>

SoftwareSerial bluetooth(2,3);    // TX,RX
int bar_analog=0;
int head_analog=0;
int bar_anim=0;
int strip_anim=0;
int motor_speed=1;
int direct=0;
int level=0;
boolean debug = true;

void setup() {
  Serial.begin(9600);
  bluetooth.begin(9600);
  Serial.println("Program is starting...");
  Serial.println("by Berke Ogulcan Parlak");
}

void loop() {
  if (bluetooth.available()) {
    while (bluetooth.available())
    {
      bar_analog = bluetooth.parseInt();
      head_analog = bluetooth.parseInt();
      bar_anim = bluetooth.parseInt();
      strip_anim = bluetooth.parseInt();
      motor_speed = bluetooth.parseInt();
      direct = bluetooth.parseInt();
      level = bluetooth.parseInt();
      if (debug) {
        Serial.print("Bar Brightness: ");
        Serial.println(bar_analog);
        Serial.print("Bar Animation Type: ");
        Serial.println(bar_anim);
        Serial.print("Headlight Brightness: ");
        Serial.println(head_analog);
        Serial.print("Strip Animation Type: ");
        Serial.println(strip_anim);
        Serial.print("Motor Speed Level: ");
        Serial.println(motor_speed);
        Serial.print("Direction: ");
        Serial.println(direct);
        Serial.print("Mast Goes: ");
        Serial.println(level);
        Serial.println("--------------------------------");
      }
      if (bluetooth.read() == '\n') {
        azdırma işlemleri bu satırda yapılacak..

      }
    }
  }

}

```

# Answer
SoftwareSerial relies on the Pin Change interrupt. Not all pins on the Mega have pin change interrupts.

But that is all a moot point really, because when you're using a microcontroller that has lots of *real hardware UARTs* there is no call to be using SoftwareSerial in any case.
> 3 votes

---
Tags: arduino-mega
---


title: Arduino Communication with Sim 900

text:
# Question
Title: Arduino Communication with Sim 900
Im using an arduino uno and a sim 900, the simcard is setup and working as I can make a phone call to it and it rings.

The sim 900 is powered via the power jack and the uno is currently powered using USB.

I am trying to print out incoming text messages however with serial monitor open I only see "Initialising...".

```
    #include <SoftwareSerial.h>

//Create software serial object to communicate with SIM900
SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM900
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Handshaking with SIM900
  updateSerial();

  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

```

I cant for the life of me figure out why its not printing anything else out? Can anyone give me any guidance or what to check?

# Answer
The 'Initializing' printout happens because that is sent directly to the UNO's hardware serial port. The rest doesn't happen because it is directed to the SIM card via SoftwareSerial pins 7 & 8, and the SIM card apparently isn't responding.

Cut the problem in half: Connect pins 7 & 8 together, and run your program again. If you get "AT" and the rest, then you know the 'MySerial' port is active and working correctly, and the problem is in the SIM 'half'. Maybe you have an incorrect wire connection there, or maybe the SIM card's default serial rate isn't 9600, or something like that. YMMV ;-).

As a test, I ran your program on a UNO, with a jumper wire between pins 7 & 8. Unfortunately this did not work, but now I knew that the problem had nothing to do with the SIM shield. The result wasn't what I expected, but now I had 'cut the problem in half'.

Now that I had determined that the SIM card wasn't a factor (so far, anyway), I could concentrate on the 'UNO half'. After some web research I found that 'Software Serial' doesn't support 'loopback' (looping the transmit line back into the receive line) because it cannot simultaneously transmit and receive. Fortunately, the 'AltSoftSerial' library by Paul Stoffregen **does** support simultaneous transmit & receive, and so will support loopback.

So, I installed the library on my Arduino setup, and compiled and uploaded the example shown below.

```
#include <AltSoftSerial.h>

// AltSoftSerial always uses these pins:
//
// Board          Transmit  Receive   PWM Unusable
// -----          --------  -------   ------------
// Teensy 3.0 & 3.1  21        20         22
// Teensy 2.0         9        10       (none)
// Teensy++ 2.0      25         4       26, 27
// Arduino Uno        9         8         10
// Arduino Leonardo   5        13       (none)
// Arduino Mega      46        48       44, 45
// Wiring-S           5         6          4
// Sanguino          13        14         12

AltSoftSerial altSerial;

void setup() {
    Serial.begin(9600);
    //while (!Serial); // wait for Arduino Serial Monitor to open
    Serial.println("AltSoftSerial Test Begin");
    altSerial.begin(9600);
    altSerial.println("Hello World");
}

void loop() {
    char c;

    if (Serial.available()) {
        c = Serial.read();
        altSerial.print(c);
    }
    if (altSerial.available()) {
        c = altSerial.read();
        Serial.print(c);
    }
}

```

After uploading the code, I 'looped' pin 9 back to pin 8, and found that when I sent characters to the UNO via the hardware USB port, they showed up again 'echoed' to the serial output after having traversed the AltSoftSerial port 8/9.

So at this point I have solved the UNO 'half' of the problem; the rest is up to you! ;-)
> 1 votes

---
Tags: arduino-uno, gsm
---


# Question
Title: Making a PID Controller for BAR 30 pressure sensor
I am having issues with my PID controller for a BAR 30 depth sensor. The issue that I have is my ESC have two initial start up { 1500 - 1900} is min - max respectively clockwise and { 1500-1900} is max respectively counter clockwise. What I want is for me to set a depth and I can submerge to a certain depth and lock in at that certain depth.

```
#include <PID_v1.h>
#include <MS5837.h>
#include <Wire.h>
#include <Servo.h>
MS5837 sensor;
Servo vertical_thruster1;

// Variables

float current_depth ;
float set_depth = 0.50 ; //  depth u wish to go in meters
float PID_error = 0;
float previous_error = 0;
float elapsedTime,  Time , timePrev;
double pwmvertical_thruster1 = 1440;

int s;

float PID_value = 0;
float PID_p = 0;
float PID_d = 0;
float PID_i = 0;
//PID constants
float kp = 100;
float ki = 0.003;
float kd = 5.2;

void setup() {
  Serial.begin(9600);
 vertical_thruster1.attach(4);
   vertical_thruster1.writeMicroseconds(1500);

 Time = millis ();

 ///Bar 30 Configuration

  Serial.println("Starting");
  Wire.begin();
 while (!sensor.init()) {
Serial.println("Init failed!");
Serial.println("Are SDA/SCL connected correctly?");
Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
Serial.println("\n\n\n");
delay(2000);
  }
  sensor.setModel(MS5837::MS5837_30BA);
  sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}

void loop() {

///*
// First read the current value of the depth sensor
sensor.read();
current_depth = sensor.depth();

timePrev = Time;
Time= millis();
elapsedTime = ( Time - timePrev) / 1000;

// calculate the error between the set depth and current depth
 PID_error =  set_depth - current_depth ;

 // Calculate the P Value
 PID_p = kp * PID_error;
   Serial.print("PID_p: ");
    Serial.print(PID_p);
    Serial. println ( "\t\t");
// Calculate the i value in a range on +-0.3

 if (-0.2 < PID_error < 0.2)
 {
  PID_i = PID_i + (ki * PID_error);
 }
Serial.print("PID_i: ");
Serial.print(PID_i);
Serial. println ( "\t\t");
// Calculate the d value
 PID_d = kd*((PID_error - previous_error)/elapsedTime);
Serial.print("PID_d: ");
Serial.print(PID_d);
Serial. println ( "\t\t");
// The total PID value
PID_value = (PID_p + PID_i + PID_d) ;

// range for the blue robotics esc

if ( PID_value < -150)
 {
 PID_value = -150;
  }
  if( PID_value >150)
  {
  PID_value = 150;

  }
  Serial.print("PID_value: ");
  Serial.print(PID_value);
  Serial. println ( "\t\t");
 // calcualte the pwm

 s =  (pwmvertical_thruster1 + PID_value  );
 if(s < 1350)
{
 s= 1450;

}
else if(s> 1650)
{
  s=1550;

}
  Serial.print("Depth: ");
  Serial.print(sensor.depth());
  Serial.println(" m");
  Serial.print ( "Speed s  ");
  vertical_thruster1.writeMicroseconds(s);
  Serial.print( s) ;
  Serial. println ( "\t\t");
  previous_error = PID_error;
  //  */
  delay(300);
 }

```

# Answer
A PID controller should be a good match for your application, but it appears that your code doesn't take advantage of the PID\_v1 library at all; a PID\_v1 object is never declared, and it appears you are attempting to manually compute what the PID library is designed to do for you automatically.

I would recommend you 'start slow and simple' by learning how to use a PID controller in its most basic form. The PID library has a very basic example, which I have modified slightly to demonstrate how a PID controller works. I tested this example with a UNO, a potentiometer (variable resistor) and a capacitor. The resistor and capacitor values aren't critical - I used the first things I found in my parts box. The output on Pin 3 is a PWM pulse train signal, and the resistor/capacitor combination filters this pulse train to a variable level analog signal, which the PID controller sees as the analog 'Input' on A5.

Once you have this running, you can vary the pot value to see how the PID changes the output value in order to achieve the setpoint value on the input, and you can vary the setpoint and PID parameters to play around with different configurations. Once you are comfortable with basic PID operation, you should then be able to configure it properly for your application.

Hope this helps,

```
#include <PID.h>

 //Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT);

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

    //initialize the variables we're linked to
    //Input = analogRead(0);
    Input = analogRead(A5);  //I used A5 as A0 was unavailable
    Setpoint = 100;

    //turn the PID on
    myPID.SetMode(AUTOMATIC);
}

void loop()
{
    //Input = analogRead(0);
    Input = analogRead(A5); //I used A5 as A0 was unavailable
    myPID.Compute();
    analogWrite(3, Output);
    Serial.print("Input = "); Serial.print(Input); Serial.print(", Output = "); Serial.println(Output);
    delay(100);

}

```
> 2 votes

---
Tags: c++, pid
---


title: How to create array of references?

text:
# Question
Title: How to create array of references?
I have a class named `timeOut` dealing with timeout tasks.

I'm to write a sketch, common for Sonoff basic and Sonoff Dual, meaning that I may have 1 task for Basic and 2 tasks for Dual.

Declaring instances looks like:

```
timeOUT timeOut_SW0("SW0",TIMEOUT_SW0);
timeOUT timeOut_SW0("SW1",TIMEOUT_SW1);

```

for code simplicity I'd rather create an array of references and call it using a `for` loop:

```
timeOUT TO[]={timeOut_SW0,timeOut_SW1};

```

is it the right way to call it as a reference ?

# Answer
> 3 votes
You can't. The C++ language doesn't support arrays of references. You have the choice to either create an array of objects:

```
timeOUT TO[] = {timeOUT("SW0",TIMEOUT_SW0), timeOUT("SW1",TIMEOUT_SW1);}

```

or an array of pointers:

```
timeOUT *TO[] = { &timeOut_SW0, &timeOut_SW1 };

```

---
Tags: array
---


title: Powering Arduino with Thermostat Power

text:
# Question
Title: Powering Arduino with Thermostat Power
So I want to make an Arduino based thermostat controller. I'm good with the semantics behind this, there's just one detail I want to make sure I get right: Power

I know US thermostat power is 24VAC, but I'm not sure how to convert that to 12V 0.5A DC that the Arduino wants. I'd like to do this efficiently rather than generating a ton of heat in the process, too. I don't even know how many amps "24VAC" is, which is the only specification I can find on thermostat power.

I've found 24VAC to 12VDC converters (made for surveillance cameras) online, but most are rated for 1.5A, and I'd be concerned about frying the Arduino. I am not sure if the Arduino only pulls as much as it needs, or if it would try to pull the full 1.5A and destroy itself. I also do not know if these are relatively power efficient, either.

I'm generally hoping someone has been down this path before so that I don't have to reinvent the wheel.

# Answer
> I don't even know how many amps "24VAC" is

Exactly, because that's a voltage rating (24 Volts AC) and no information about the current capability is given.

> I've found 24VAC to 12VDC converters (made for surveillance cameras) online, but most are rated for 1.5A, and I'd be concerned about frying the Arduino. I am not sure if the Arduino only pulls as much as it needs, or if it would try to pull the full 1.5A and destroy itself

The Arduino, as a semiconductor, will consume only the current it needs. What current it needs is determined by the processor core (if it's e.g. in sleep-mode or not), the activated peripherals (ADC etc) and devices powered externally via the Arduino's +5V or +3.3V pins.

The typical power consumption of an Arduino board running a sketch (no low-power mode + no external devices) is about 20mA, aka 0.020A.

Also note that what's happening is when you feed +12VDC into the VIN pin, it goes to a linear voltage regulator, which converts excess voltage into heat while keeping the current the same. The official Arduino Uno (not a chinese clone!) has a NCP1117ST50T3G, which is a 6.5V-20V (recommended limit:12V) to 5V linear regulator with I\_out of minimum 1A, typical 1.5A (also note I\_out is circa I\_in, the regulator itself needs negligable current). Clones might use a cheaper (and worse) voltage regulator. Also note that this output capability might not be realisitically achievable without a heat-sink on the regulator; since excess voltage is converted into heat, converting +12V to +5V at 1A creates (12V-5V)\*1A = 7W of heat(power). The package cannot sustain that for very long and the regulator shuts down due its built-in thermal protection.

In short it can be said that it's not a problem to connect a higher-rated power supply to an Arduino. The Arduino will pull what it needs to power itself and everything else on the +5V and +3.3V pins, if it's within the limits of the voltage regulator.

These videos might help your understanding of linear voltage regulators: https://www.youtube.com/watch?v=GSzVs7\_aW-Y https://www.youtube.com/watch?v=giGRrODKJSE
> 1 votes

# Answer
If you're just running an Arduino and a few low power components, feeding the Arduino's voltage regulator 12V would be fine. However, if the 24VAC to 12VDC power supply is unregulated, it may well put out more than 12V.

If your Arduino system draws a lot of current from the 5V regulator then it will generate a lot of heat, and might overheat. What else are you driving from the Arduino's 5V and 3.3V lines?

A buck style power supply would be a good choice for this setup.

Here is an example that should work very well:

https://www.amazon.com/SMAKN%C2%AE-Converter-Voltage-Supply-Waterproof/dp/B00RE6QN4U

The picture on that supply says it will work with from 8-35V, so there is a **lot** of "wiggle room" in its supply voltage. Even if the doorbell draws enough current for the 24VAC to drop to 12VAC while the doorbell is ringing, the supply should still be able to keep the Arduino running just fine.

(You could feed the regulated 5V from that supply directly into the USB input on your Arduino)

That is a very high efficiency supply that will waste very little power as heat. You wouldn't need anything else other than that.
> 0 votes

---
Tags: power
---


# Question
Title: Modular Coding - What types of code portions to convert into library files? Rationale and methods?
I'm working on documentation and combining 2 pieces of code for testing parts of a larger project.

I'm supposed to comment and make the code very clear to people who will use it later and make sure it's modular. I'm supposed to make header files, to reference function chunks in the main code from just the `#include(s)`.

I understand in C++, that the convention is that for each header files(?), `.h`, there is a `.cpp`, where the `.h` is the header file that declares all the content, and that the `.cpp` is where you define the `.h`, ie. implementation.

My supervisor told me to put more parts of the code into library files, because additional components will be added in the future -

> but confused because all the length comes from using already existing library files, just a specific pattern of calling pre-defined functions.

**If I put the files into a .h, how do I reference all the calls? Make a `void setup () {}`**?

The compiled code is 348 lines right now. All it has are some `#include(s)`, code to calibrate and read from 2 different sensors using I2C and SPI protocols, with 1 shared master an Adafruit Bluefruit nRF52832, and comments with links to datasheets.

The bulkiness is in the set-ups and the different ways to represent data (have 24 lines just to print out data from 1 sensor).

**Should the entire code be just calling built in functions from a library file? So people who read the code don't see the details so much?**

# Answer
It's very subjective what should and shouldn't be put in a library.

I use the simple rules:

* If it's an atomic piece of code like a hardware driver, it's a library.
* If it's something that could be used in multiple sketches, it's a library.

Maybe things like configuration options could be put in a header file (not a library - a header file in the sketch folder).

You could maybe split portions of your sketch into C++ files or INO files within the sketch (not a library - files in the sketch folder, and using INO files is easier since you don't need header files, the IDE does it all for you) to group things logically together and make it easier to manage (all the LCD code in one file, all the temperature sensor code in another file, that kind of thing).
> 0 votes

---
Tags: programming, library, code-optimization
---


# Question
Title: Using an L298N driver together with servo motors on the same arduino
I'm using an L298N driver (powered by a 12V, 1.5A adapter) on a MEGA Sensor Shield (powered by a USB cable). Everything works fine and I can control the direction and the speed of the DC motor, however when I activate anything else on the shield - the motor will not spin unless I set the PWM to its highest frequency.

Please note that I am using Max/MSP to controls the motors, so when I say activate - I mean setting up the PinMode of pin 17 to "Servo". If I set up the Servo first and then the DC motor pins - it will again start spinning only at maximum PWM, there's no signal reaching the driver otherwise.

Am I missing something in my setup? I would use Arduino Mega on its own, however I need to use over 25 Servo motors together with the L298N driver, which makes the sensor shield inevitable.

# Answer
> 0 votes
It seems that the issue is with the fact that PWM is only supported on pins 2-13, so I shouldn't have connected it to pin 46.

---
Tags: arduino-mega, arduino-motor-shield, l298n
---


# Question
Title: Trouble with setting the PWM frequency for Arduino Due
I'm using Arduino Due and I set the analog read and write resolution to 12-bit for better resolution. Basically all I do is to vary PWM duty cycle by controlling analog DC input voltage from 0 to 3.3V. The simple code as it is now works fine as follows:

```
int pwmPin9 = 9;
int analogPin0 = 0;
int val = 0;

void setup() {

  Serial.begin(9600);

  pinMode(pwmPin9, OUTPUT);  // sets the pin as output
  analogWriteResolution(12);
  analogReadResolution(12);

}

void loop() {

  val = analogRead(analogPin0);  // read the input pin
  Serial.println(val);
  analogWrite(pwmPin9, val);

}

```

My problem is I need to set the frequency of the PWM output to 25kHz or at least something nearest above 25kHz.

I have been searching forums hours and couldn't find any solution. Here I came across a way but there is no library called variant.h in my folders. And that code if I include in my script doesn't change anything. What could be a workaround for this?

(I used to achieve this via this site by using Arduino Uno but for Due couldn't find any working solution)

Edit: I found the file and made the following change in variant.h:

```
 * PWM
 */
#define PWM_INTERFACE       PWM
#define PWM_INTERFACE_ID    ID_PWM
#define PWM_FREQUENCY       20000
#define PWM_MAX_DUTY_CYCLE  4095
#define PWM_MIN_DUTY_CYCLE  0
#define PWM_RESOLUTION      12

/*
 * TC
 */
#define TC_INTERFACE        TC0
#define TC_INTERFACE_ID     ID_TC0
#define TC_FREQUENCY        20000
#define TC_MAX_DUTY_CYCLE   255
#define TC_MIN_DUTY_CYCLE   0
#define TC_RESOLUTION       8

```

But it only works for 20kHz. If I set to 25kHz or 30kHz I don't get any error but also don't get any output :((

# Answer
There are a few things to do. I've used this successfully in the past with older projects.

As a side note one can *very* easily change PWM settings on pins with the esp32, a single line of code being `ledcSetup(PWM_Channel_Number, Frequency, resolution)` without ever having to actually dive into modifying variant.h

To Quote Kerry D. Wong:

> If you take a look at the function PWMC\_ConfigureClocks in pwmc.c, you will see that the highest PWM frequency can be accommodated as the function input is 42 MHz, this is because inside the function it calls FindClockConfiguration which in turn ensures that the frequency parameter passed in is less than the MCK frequency. Thus for integer dividers, the highest frequency we can pass in is 42 MHz (with divider 2).
>
> To achieve the highest output frequency, we can use a one bit PWM which essentially just outputs a square wave with a duty cycle of one. We can then set the prescaler to 2 to obtain an 84 MHz waveform.

```
#include <Arduino.h>

uint32_t pwmPin = 8;
uint32_t maxDutyCount = 2;
uint32_t clkAFreq = 42000000ul;
uint32_t pwmFreq = 42000000ul;

void setup() {
  pmc_enable_periph_clk(PWM_INTERFACE_ID);
  PWMC_ConfigureClocks(clkAFreq, 0, VARIANT_MCK);

  PIO_Configure(
    g_APinDescription[pwmPin].pPort,
    g_APinDescription[pwmPin].ulPinType,
    g_APinDescription[pwmPin].ulPin,
    g_APinDescription[pwmPin].ulPinConfiguration);

  uint32_t channel = g_APinDescription[pwmPin].ulPWMChannel;
  PWMC_ConfigureChannel(PWM_INTERFACE, channel , pwmFreq, 0, 0);
  PWMC_SetPeriod(PWM_INTERFACE, channel, maxDutyCount);
  PWMC_EnableChannel(PWM_INTERFACE, channel);
  PWMC_SetDutyCycle(PWM_INTERFACE, channel, 1);

  pmc_mck_set_prescaler(2);
}

void loop()
{

```

> Note that VARIANT\_MCK is defined in /arduino-1.5.7/hardware/arduino/sam/variants/arduino\_due\_x/variant.h as 84000000. PWM\_INTERFACE\_ID and PWM\_INTERFACE are defined in variant.h as ID\_PWM and PWM which in turn are defined in /arduino-1.5.7/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/sam3x8e.h.
>
> So as the conclusion, the highest stable frequency we can generate using an Arduino Due is 84 MHz. The pictures below show the captured waveforms under different frequencies. For the 21 MHz waveform, pwmFreq is set to 21000000, no prescaler is used. For the 42 Mhz waveform, pwmFreq is set to 420000 with no prescaler. The 84 MHz waveform is generated with set to 42000000 and the prescaler set to 2.

Hope this helps.
> 1 votes

---
Tags: pwm, arduino-due, frequency
---


# Question
Title: Using an NPN transistor as a switch to turn on/off a DC Motor
I am trying to control a 3V DC motor (FA-130) with my Arduino Uno, and am trying to do that using an NPN transistor (2N3904) as a switch, as shown in this diagram.

I used the Blink example and modified the pin used for the output to be the one attached to the transistor's base (e.g. pin 2 in the diagram).

The motor does nothing. If I replace the motor with an external LED component it works, blinking on/off every 1 second. If I connect the motor directly to my Arduino's 5V and GND (or even 3.3V and GND) then the motor runs fine.

Why does the motor not run when connected using the transistor? Is there a significant enough drop in voltage/current/something else?

# Answer
It depends on the transistor. You might not be driving it to full saturation, or it's "on resistance" may be too high to pass enough current to drive the motor. You'd need to tell us the specific transistor, as well as the specs on the motor before we could figure out what's going on.

An LED draws a whole lot less current than a motor, so the transistor may not have any problem powering your LED. (You usually need a current limiting resistor when you drive an LED from 5V to avoid burning it out.)

I would suggest using a MOSFET transistor instead. This one, for example, can drive up to 30A at 60V: https://www.adafruit.com/product/355

It has very low on resistance, and is fully turned on by a 5V CMOS logic output, and requires very little current through the base to turn it on.

As CrossRoads pointed out, if you're using an NPN or other BJT transistor you really need a current limiting resistor between the Arduino output and the gate so you don't draw too much current from the Arudino pin and fry it.

Note that regardless of what type of transistor you use, you need a "flyback diode" on the motor to protect the transistor from back EMF from the motor's inductive coils. Without a flyback diode you run the risk of destroying your transistor.
> 0 votes

---
Tags: motor, switch, transistor
---


# Question
Title: Can you start/stop a code from the serial monitor?
pressing and number in the serial monitor to start code and stop code.

# Answer
> 1 votes
This can be done by using the `Serial.read()`command as referenced in the Arduino documentation here.

Below is an example of how you might apply this.

```

/**
 * NAME: Serial interupt
 * DATE: 18/7/19
 * AUTHOR: Jeremy Fox
 * DESCRIPTION:
 *    FLashes LED until recives enter keystroke from serial monitor.
 */
int incomingByte = 0; // for incoming serial data
int LED = 13; // defines the LED to flash
boolean flash = true; // for flashing loop

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
  while (flash == true){
    // flash LED
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  }

  // record data if available:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
  }

  // checks if enter key was pressed:
  if (incomingByte == 13) {
    flash = true; // enter loop
    incomingByte = 1; // reset incomingByte to avoid feedback loop
  }
}

```

---
Tags: arduino-mega
---


# Question
Title: about how to share one External serial EEprom using two microcontrollers?
**strong text**i have Vector nav100 IMU sensor that sends data serially UART.I want to receive data from it using ATmega32 and then store data in AT24c1024 EEprom using I2C,then using another ATmega32 to read the saved data on AT24c1024 EEprom using I2C to control a servo motor..so,the AT24c1024 EEprom is then shared between the two microcontrollers...i have serached the internet about how to share one External serial EEprom,i found that......(On way would be for the two mcrocontrollers to have an output line as an input to the other. A master that is "using" the EEPROM perhaps pulls his output low (or high - your choice) to say "I'm using it at the moment". The other reads his input first before going near the EEPROM if he finds the line active he backs off until it is set inactive by the other master.i tried this solution but i failed...can any one help me on this solution ? Thanks in advance...... this is my code

```
{

    //the first MCU fristly check the pin
    //if high,then write,then set it low to allow read
    //the second MCU fristly check the pin
    //if low ,then write,then set it high to allow write

    //for the MCu that will write
    //first it will check for the pin ,if it is LOW,
    //then it can write data to EEprom
                     DDRA=0x00;//configure portA as input
            if(PINA==0x00)//check for the pin, if LOw,then wirte
    {
        byte_write(data);
        _delay_ms(10);
    //After writing set the pin as high to allow the second MCU to read
        DDRA=0xff;//configure portA as output
        PORTA=0xff;//set the pin as high
        _delay_ms(10);}

    //for the MCu that will read,i set adelay of 10 ms
    // to allow the first MCU to write some data

                         _delay_ms(1000);//delay from the data to be written on the EEprom
                 DDRA=0x00;//configure portA as input
        if(PINA==0x01)//check for the pin, if HIGH,then read
    {
             y=byte_read(data);
            DDRA=0xff;configure portA as output
            PORTA=0x00;//set the pin as high

}

```

# Answer
You didn't show us a complete, minimal, compilable example, so my answer will only cover some important points.

1. Your indention is way off. It is important to use the correct indention, since it help structure your code and will let you quickly see misplaced brackets. The Arduino IDE even has an autoformat function for this.
2. You are configuring and checking always the whole PORT A, but you have only connected one of the pins. When you configure the whole port as input (without pullup), the other pins will be floating. Also, if both devices have the pin on input (no pullup), this pin will also be floating. The check cannot work this way. You should only look at the first bit in the port registers, since that is the pin, that you connected. You can set all other bits to zero when reading, by performing a bitwise AND operation: `if(PINA & (1<<PA0))`. This will execute, when the first bit of PINA is 1. To set a single bit you can use the bitwise OR: `DDRA |= 1<<PA0;` will set the first bit of DDRA. To erase only that bit from the register, you can use `DDRA &= ~(1<<PA0);`. The rest of the port will stay untoched with this.
3. Your current protocol is, that the first MCU will check for LOW, do it' transmission, then drive the pin actively HIGH as a signal for the second MCU to start transmitting. The second MCU will do it's I2C stuff and then drive the pin actively LOW. So now we have an active LOW and active HIGH on the same pin, which in principle is a short. A rather big amount of current will flow from one MCU to the other, most likely destroying at least one of the pins (meaning the output hardware in the MCU, that serves that pin). To avoid this, you can use a principle like that, that the I2C port uses: Open Drain logic. You can start with the first MCU's pin configured as OUTPUT LOW, while the other is INPUT PULLUP. LOW means the first MCU can work. If the first MCU want's the second MCU to do a transmission, it will release the line by setting the PIN to INPUT PULLUP. The second MCU now sees a HIGH level on it's pin and starts it's transmission. When it is finished, it will drive the line actively LOW for a defined duration (enough for the first MCU to react) and then to INPUT PULLUP again. The first MCU will then see a LOW level on it's pin as a signal, that the second MCU is finished. It then itself drives the line actively LOW. Then the play starts again. The important thing is, that a HIGH state is only done by a pullup, not actively driven.

---

That said, I still don't see the necessity to share an external EEPROM for this use case. You are overthinking the problem. You wrote, that you don't want to miss a frame, if the second MCU is still processing the last frame. There are better ways to do that (especially when you consider the limited lifetime of EEPROM).

* You didn't tell us, why you are using 2 MCU's, so maybe your goal can be reached with only 1 MCU, which will eliminate the whole need for transmission.
* You could use another UART interface via `SoftwareSerial` or it's sibling libraries to let the MCU's communicate directly. "Not missing a frame" will still be the case, when you are not disabling interrupts. The library will read the data into a buffer in interrupts, while you are processing the previous frame. Depending on how much data you send, you might want to make the buffer bigger, but that is a simple change in the libraries definitions.
* If you want to use I2C to communicate between both MCU's, you have 2 ways of doing it. You can either go the same way as described above for UART, by just letting it fill a big enough buffer, or you can do this through the bus transmissions. The first MCU would be the master, that tries to send the data to the second MCU (slave), when there is new data available. The slave will receive the data normally. When the frame is finished receiving, the slave can leave the bus, until it is finished processing. So, when the master tries to send more data in this time, the transmission will fail at the start, since no slave with that address is on the bus (the slave MCU left the bus for this period of time). You can check the return value of `Wire.endTransmission()`, which will reflect the corresponding error code. If this error code is returned, the master should wait a bit and try to send this frame again, until it is received successfully. That also means, that the master needs a big enough buffer for storing new data, while waiting for the slave to be ready. Or another way: The master can request 1 byte from the slave, that indicates, if the slave is ready for new data. If not, the master will wait a bit and ask again. If yes, it will transmit the data.

Note: Either way the frequency of data reception and processing must be equal for continuous operation. The whole chain will be as fast as the slowest part. If you receive data faster, than it get's processed, the buffer will fill up fast, until you really have to drop frames. The prinicples above are more about the case, when the processing and receiving may misalign or vary a bit, but at the average staying at the same speed. And for this simple communication buffers, that all communication libraries use, with enough space for maybe 2 to 4 transmissions (depending on the variation) are way enough.
> 2 votes

---
Tags: arduino-uno, serial, avr, eeprom
---


title: What is this extender?

text:
# Question
Title: What is this extender?
I recently got an Arduino starter kit from a friend that he wasn't using and this came with it but, i can't find anything about it, cause i don't know how to search for it. Anyone can enlighten me what it is?

# Answer
Looks similar to:

"8 Channel 5V/3.3V IIC UART SPI TTL Logic Level Converter"

Image above was screen capped from: https://www.aliexpress.com/item/32977711795.html
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Why do all analog pins measure the same value?
I measure 2 analog pins: A4 and A5. The A5 pin is connected to another Arduino's digital out (through a 10k resistor) which has a simple program: 5ms on and 100ms off. The A4 pin is not connected anywhere.

The analog pins are inited with pinMode(APIN, INPUT), reading is simply performed with the analogRead(APIN) function (there is no delay between the readings). I have tried with delays between the measurements but the results are the same.

The results:

The A5 pin (which is connected) measures the correct value. However, the unconnected A4 pin is clearly interferred by the input of A5. It works like this with another pins, delays between the readings, double use of analogRead()... I even swapped the Arduinos (Arduino Nano and Uno) and the results are the same.

Is it because of that these Arduinos are clones? Or are these Arduinos damaged?

# Answer
If you want to measure a pin (i.e. defined as input pin, either digital or analog), you have to use a pull up or pull down resistor (either internal or external depending on what the MCU GPIOs have).

This resistor makes sure in case there is nothing attached, that the (mostly high ohm) resistor will make sure the nonconnected pin will either give a LOW or HIGH as input (or in case of analog, the minimum or maximum value).

When the pin is connected, the pull down/up resistor will change the result so marginally that it can be ignored.
> 2 votes

# Answer
I believe what you are seeing is the effect of the *sample and hold* process used by the Arduino analog to digital converter (ADC).

The way the *sample and hold* circuit in the ADC works is

1. Connect the pin to an internal, fixed size capacitor
2. Disconnect the pin
3. Compare the capacitor voltage against a fixed value

All the analog pins in the Arduino share the very same capacitor, so if such capacitor has no opportunity to discharge another reading will be influenced by the previous one.

Ref.

1. https://en.wikipedia.org/wiki/Sample\_and\_hold
2. http://ww1.microchip.com/downloads/en/appnotes/atmel-8456-8-and-32-bit-avr-microcontrollers-avr127-understanding-adc-parameters\_application-note.pdf
> 0 votes

---
Tags: arduino-uno, arduino-nano, analogread, clones
---