# Question
Title: Short battery life concern with Arduino Pro Mini
I am using an Arduino Pro Mini with a L293D H-bridge driver to drive a bi-directional motor. The system takes input from a capacitive sensor which is constantly looking for a trigger. I don't have any low power optimization in the code. I was using Arduino UNO before which lasted for one day with a 9V battery. I switched to Arduino Pro Mini for longer battery life but the battery lasted for one day in that case as well.

Can anyone please help me understand what could be the possible reason for higher power consumption than normal for Arduino Pro Mini?

Thanks in advance for your help!

Niloy

# Answer
> 0 votes
A standard alkaline 9V battery has a capacity rating of around 500mAh (milliAmp-hours). That rating is probably based on a current consumption of around 10mA. However, if the current consumption is higher, the apparent capacity drops. At 100mA, most 9V batteries have a capacity rating of about 300mAh, and at 500mA current draw, the apparent capacity drops down to 170mAh.

This means, if you are drawing 100mA of current constantly, a 9V battery will last (0.3Ah / 0.1A) = 3h.

A typical Arduino pro mini will draw current at around 20mA.

```
500mAh / 20mA = 20h

```

This is not even counting the motor and driver.

A standard alkaline AA battery has a nominal voltage of 1.5V and a capacity of about 2000mAh, and 3 of them will provide a voltage between 4.5V (fully charged `1.5V x 3`) and 2.7V (fully discharged `0.9V x 3`)

With that voltage range, you could operate the Arduino pro mini in 3.3V mode, with no linear regulator, at a reduced clock frequency, such as 8Mhz, which will reduce power consumption even more.

Being able to put the chip in power-saving mode, and periodically check for necessary activity will help even more.

See http://www.gammon.com.au/power for a description of many practical methods.

That said, the Arduino is going to be a pretty small contributor to power draw compared to a DC motor, so your overall run time will heavily depend on how often the motor is turned on.

---
Tags: arduino-pro-mini
---


# Question
Title: Arduino Micro draws too much power from iPhone. How can I change that?
I'm building a USB keyboard that has two buttons - space and enter. The plan is to use this USB keyboard (with an Apple Lightning connector to USB) with the built in iOS switch control. I bought the lightning to USB dongle, and hooked it up to a normal keyboard, and it works fine.

Next, I took an Arduino Micro (ATMEGA32u4) and programed it to act as a keyboard with the two keys I need (space and enter). On a PC, it works just fine, but when I hook it up to my iPhone, I get the message:

```
Arduino Micro: The connected device requires too much power.

```

I've done quite a bit of research on this, and I found this post. In a nutshell, that post said that when you connect a device to an iOS device, one of the first things it does is tell the iDevice how much current it *could potentially* draw. This number (about 200mA for the Arduino Micro) is what decides whether the iDevice will support the device or not, when in truth, the device will not come close to its max current draw, at least not in my case.

I hooked up a meter to the normal keyboard, and it draws just over 4mA. When I hook up the Arduino, it is drawing almost 40mA. While the Arduino is drawing much more than the keyboard, it should be okay, because when I plugged in a flash drive, it was drawing 50mA, but the iPhone didn't complain.

There is my story, here is my question:

Is there any way to change it so that the Arduino Micro doesn't request so much power? In other words, is there a way to reset the value that is causing the iPhone to not use the device?

---

# Answer
> 3 votes
The power consumption is part of the exchange with the PC when it is plugged in. You can change that. Find the file `USBCore.h` in your Arduino install directory. In my case (under Linux) it was:

```
./hardware/arduino/avr/cores/arduino/USBCore.h

```

Inside that file, at around line 269 (depending on the distribution) you should see these lines:

```
#define D_CONFIG(_totalLength,_interfaces) \
    { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) }

```

On the right of the second line is the requested power consumption in milliamps (currently 500). Change that to (say) 100:

That is, change `USB_CONFIG_POWER_MA(500)` to `USB_CONFIG_POWER_MA(100)`.

Save and recompile.

You may find that the bootloader initially requests 500 mA even with this change (as it initially runs the bootloader). However when the sketch starts it should re-establish a USB connection and only request 100 mA. To fix that you would need to recompile the bootloader with the same fix, and reinstall it, a somewhat more complex task.

Another possible approach would be to tweak the fuses so that it doesn't run the bootloader, if you have finished debugging your code. Only do that if you are confident with playing with the fuses.

# Answer
> 1 votes
Yes, but it requires manual modification of the Arduino core software.

1. Find the file `USBCore.h` within your AVR boards installation (it could be in the data storage folder wherever that is on your OS, or within the actual IDE software)
2. Look for the line `#define D_CONFIG(_totalLength,_interfaces) \`
3. The *next* line has the power setting. Change `USB_CONFIG_POWER_MA(500)` to what you require (for example `USB_CONFIG_POWER_MA(50)`

---
Tags: power, keyboard, atmega32u4
---


# Question
Title: Lowest latency triggering multiple Arduinos using NRF24L01+
I'm building a rig with multiple DSLR cameras. I need to synchronize the cameras to take a photos with lowest possible latency. The only constraint is we want the ability to address each camera individually if needed.

I've seen in other posts: Choosing wireless tech for lowest possible lag

NRF24L01+ seems to be a good choice. An answer on that post states: sending a 32 byte payload...283µs on 2Mbps mode.

Given the esp8266 has a clock speed of 80MHz/160MHz I'm not too concerned about the lag involved in processing the signals.

Most multi-cast information out there is for sensor arrays, so multiple out single in. I'm after resources on single out multiple in for NRF24L01+ networks.

Added bonus of esp8266 is that non timing critical tasks such as logging and error checking could be performed over wifi so NRF24L01+ would be purely for one -way triggering.

If each camera had it's own esp8266 based board with attached NRF24L01+ hardware and was given an address in software from 0-255, is it possible to broadcast a single 32 byte packet of data where each bit would represent a camera address and have all receiver devices receive the same signal, do an AND against it's address and trigger if needed?

# Answer
Yes, that should work, however also think about the following issues:

* What if one (or more) camera does not receive the signal? You might need to add an ACK signal, but of course this will reduce the latency (a lot). If you don't want an ACK signal
* To prevent an ACK, you can send the signal many times (and cameras who already processed the signal not react for a fixed amount of time). Of course it will received by the other cameras (at least) 283 us later.
* If reliability is important, you could try using a less high speed, the latency will go up, but reality too.

Also you probably can fire the cameras even faster, if you first send the address bytes (4 bytes). And than send the shoot signal which can be in principle 1 bit. You can use one of the bits for that in case 128 cameras would suffice. Or send one byte extra which contains the signal to shoot.
> 1 votes

---
Tags: esp8266, nrf24l01+, wireless
---


# Question
Title: Splitting a Serial.readString into string array
I am working on a project where I need to split incoming data from serial (time to be exact, so aa:bb:cc) and need to split it into aa then bb and cc, ideally into an array. I know I could use readStringUntil and make 3 separate variables, but I would prefer it is in arrays. Here is the code that supposed to do this. It works with predefined string (eg. 00:00:00), but with reading serial it says that the initializer fails to determine size of "input". Thank you in advance for helpful suggestions.

Here is the code:

```
void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  Serial.begin(9600);
  while(!Serial.available()){} //wait until Serial data received
  String vst = Serial.readString();
  char buf[vst.length()+1];
  vst.toCharArray(buf, vst.length());
  char input[] = vst;
  char delic[] = ":";
  char* sub = strtok(input, delic);
  while(sub != NULL){
   Serial.println(ptr);
    sub = strtok(NULL, delic);
  }

```

}

# Answer
Your main problem is this:

```
char buf[vst.length()+1];

```

You can't initialize an array with the return value of a function.

Instead you would need to use `alloca` to perform the same function:

```
char *buf = alloca(vst.length()+1);

```

However, the way you're doing it is wasteful. You don't need `buf` at all. You can directly access and manipulate the internal `char` buffer inside the string using `vst.c_str();`.

For convenience you can point `buf` at it:

```
char *buf = vst.c_str();

```

To complete the picture here's a routine that takes the string and gives you three integers. Since we expect a specific format with only 3 sections to it we don't really need a loop.

```
// Use readStringUntil to avoid the 1 second delay.
String vst = Serial.readStringUntil('\n');
char *buf = vst.c_str();

char *hourString = strtok(buf, ":");
char *minuteString = strtok(NULL, ":");
char *secondString = strtok(NULL, ":");

if (secondString != NULL) { // Will only be true if we have two colons
    int hours = atoi(hourString);
    int minutes = atoi(minuteString);
    int seconds = atoi(secondString);

    Serial.print("It is ");
    Serial.print(minutes);
    Serial.print(" and ");
    Serial.print(seconds);
    Serial.print(" seconds past ");
    Serial.println(hours);
} else {
    Serial.println("Invalid time format");
}

```
> 0 votes

---
Tags: arduino-uno, string, c-string
---


title: How can i stop a loop after 1 minute?

text:
# Question
Title: How can i stop a loop after 1 minute?
This is my first Arduino project, and I would like to stop my servo's loop after 1 minute. Can someone help me?

```
#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(5);
}

void loop()
{
  myservo.write(45);
  delay(1000);
  myservo.write(125);
  delay(1000);
}

```

Thanks!

# Answer
> 3 votes
As suggested by Jot in a comment, one way would be to simply do what you want (which takes roughly two seconds per iteration) in a loop, like this:

```
#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(5);

  for (int i = 0; i < 30; i++)
    {
    myservo.write(45);
    delay(1000);
    myservo.write(125);
    delay(1000);
    }
}

void loop()
{
}

```

---

The problem with that is it relies upon knowing how long your delays are, and assumes that the `myservo.write()` functions take no time. A better method is:

```
#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(5);

  unsigned long start = millis ();

  while (millis () - start <= 60000)  // for 60 seconds
    {
    myservo.write(45);
    delay(1000);
    myservo.write(125);
    delay(1000);
    }
}

void loop()
{
}

```

This uses the `millis()` function call to find out how much time has elapsed, and wait for 60000 milliseconds (60 seconds).

---

I've put the code into `setup` because that is where you put things you want done once.

# Answer
> 1 votes
To answer your question as asked, add this to `loop()`:

```
if (millis() >= 60000) exit(0);

```

However, I would suggest you seriously consider Jot's comment: simply stopping `loop()` from running is most of the time *not* what you may want to do.

# Answer
> 0 votes
Another way to handle this is to use a variable endTime to tell the loop when to stop moving the servo:

```
unsigned long endTime;

void setup()
{
  myservo.attach(5);
  endTime = millis() + 60000;
}

void loop()
{
  if (millis() <= endTime) {
    myservo.write(45);
    delay(1000);
    myservo.write(125);
    delay(1000);
  } else {
    //code to run once the servo is done running
  }
}

```

This code will move the servo back and forth for about 1 minute, then stop. It's set up so you can do something else once the loop has completed.

Note that by using a variable endTime and leaving your servo code in the loop() function, you can have your program start doing something else once the motor motion is completed. You can also add code to set up a new value in EndTime, at which point the servo will start moving back and forth again.

Also note that using delay is bad practice. When you do that you bring the arduino to a full stop while the delay code is running. You can't be doing something else. Say, for example, you wanted to move 2 different servos at different time intervals.

Instead of using delays you should track the end time for each phase of your loop, and execute your code once that end time passes.

---
Tags: arduino-uno
---


title: Stuttering motor using rf module

text:
# Question
Title: Stuttering motor using rf module
I am trying to control a stepper motor wirelessly with a button. I am using the 433MHZ rf module and the Virtualwire library.

the code is working, the receiver is getting the messages from the transmitter, but the problem is the messages are sent extremely slowly, so much so that the receiver circuit led is flashing on and off instead of staying in the on position when the transmitter button is being held down. consequently the stepper motor stutters instead of moving smoothly.

I have tried increasing the bits per second in the vw\_setup but that just makes the led flash faster and not stay in the on position. it also makes the stepper vibrate more.

how do i make the stepper motor move smoothly wirelessly over rf?

transmitter code:

```
#include <VirtualWire.h>

int currentlocation = 0;
const int stepPin = 3;
const int dirPin = 4;
int active = 0;
const int ledPin =  13;      // the number of the LED pin
String dataout;
char buffer[1];
int idx=0;

class Button {

  public:

    int pin;
    int state;
    int location;
    int Speed;
    int Direction;
    int active;
    int prevstate;

    Button(int pin1, int state1, int location1, int active1, int previousState)
    {
      pin = pin1;
      state = state1;
      location = location1;
      active = active1;
      prevstate = previousState;
    }

    Button(int pin1, int state1, int speed1, int direction1)
    {
      pin = pin1;
      state = state1;
      Speed = speed1;
      Direction = direction1;
    }

    Show(){
      if (digitalRead(pin) == HIGH){
          digitalWrite(ledPin, HIGH);
          } else {
          // turn LED off:
          digitalWrite(ledPin, LOW);
          }
    }
};

Button button(7,0,0,0,0);
Button button2(8,0,30,0,0);
Button Movebutton1(5,0,500,HIGH);
Button Movebutton2(6,0,500,LOW);
Button buttons[2] = {button, button2};
Button Movebuttons[2] = {Movebutton1, Movebutton2};

void setup() {
      vw_setup(2000);
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);      // open the serial port at 9600 bps:
}

void loop() {
    for (int i = 0; i<2; i++){
      buttons[i].Show();
      if (digitalRead(buttons[i].pin) == HIGH){
      sprintf(buffer, "%d", i);
      vw_send((uint8_t *)buffer, strlen(buffer));
      vw_wait_tx();
      }
    }
    for (int i = 0; i<2; i++){
      Movebuttons[i].Show();
      if (digitalRead(Movebuttons[i].pin) == HIGH){
      sprintf(buffer, "%d", i+2);
      vw_send((uint8_t *)buffer, strlen(buffer));
      vw_wait_tx();
      }
    }
}

```

Receiver code:

```
#include <VirtualWire.h>

char message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
int last_idx = 0;

int currentlocation = 0;
const int stepPin = 3;
const int dirPin = 4;
int active = 0;
const int ledPin =  13;      // the number of the LED pin
String str_out;

class Button {

  public:

    int pin;
    int state;
    int location;
    int Speed;
    int Direction;
    int active;
    int prevstate;

    Button(int pin1, int state1, int location1, int active1, int previousState)
    {
      pin = pin1;
      state = state1;
      location = location1;
      active = active1;
      prevstate = previousState;
    }

    Button(int pin1, int state1, int speed1, int direction1)
    {
      pin = pin1;
      state = state1;
      Speed = speed1;
      Direction = direction1;
    }

    Relocate(){
      int shift = location - currentlocation;
      if (shift > 0){
        Direction = 0;
      }
      else{
        Direction = 1;
      }
      shift = abs(shift);
      digitalWrite(dirPin,Direction); // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
      for(int x = 0; x < shift; x++) {
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(500);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(500);
      }
      currentlocation = location;
    }

    Move(){
      digitalWrite(dirPin,Direction); // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(Speed);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(Speed);
      if (Direction == 1){
      currentlocation -= 1;
      }
      else{
      currentlocation += 1;
      }
    }

    Show(){
      if (vw_get_message(message, &messageLength)){
          digitalWrite(ledPin, HIGH);
          } else {
          // turn LED off:
          digitalWrite(ledPin, LOW);
          }
    }
};

Button button(7,0,0,0,0);
Button button2(8,0,30,0,0);
Button Movebutton1(5,0,500,HIGH);
Button Movebutton2(6,0,500,LOW);
Button buttons[2] = {button, button2};
Button Movebuttons[2] = {Movebutton1, Movebutton2};

void setup() {
        // Initialize the IO and ISR
      vw_setup(2000); // Bits per sec
      vw_rx_start(); // Start the receiver
      Serial.begin(9600);
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
      pinMode(ledPin, OUTPUT);
}

void loop() {

      // Set buffer to size of expected message
    if (vw_get_message(message, &messageLength)){
    int idx=atoi(message);
    Serial.print(message);
    for (int i = 0; i<2; i++){
      buttons[i].Show();
      if (idx == i){
      buttons[i].Relocate();
      active = i;
      //buttons[i].location = currentlocation;
      }
    }
    for (int i = 2; i<4; i++){
      Movebuttons[i-2].Show();
      if (idx == i){
      Movebuttons[i-2].Move();
      buttons[active].location = currentlocation;
      }
    }
    }
}

```

# Answer
What is the incoming message interval (1/incomingMessageFrequency)? Whenever the receiving end receives a "button-down" message, it should activate the motor for that interval + long enough to receive or not receive the next "button-down". Once the next "button-down" should have been received and has been missed, that's when you should stop the motor.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Trying to Pulse an LED a number of times outside of the main loop
I'm trying to call a class function that pulses an LED "x" number of times. I dont want to use a delay, which is making it tough. If I use a while loop, the LED just stays on. I attach an interrupt in the `begin()` \- the location of the LED is pin `13`

I call the following in my sketch like so:

```
robot.lights.pulse(0, 2000, 10000, 500); //in milliseconds

```

My goal is to pulse an LED "x" number of time at a rate I specify.

This is the code inside my class:

```
void StatusLights::begin(int locations[]){
    for(int i=0;i<NUM_OF_LIGHTS;i++){
        this->locations[i]=locations[i];
        pinMode(locations[i], OUTPUT);
    }

    ledState = LOW;
    previousMillis = 0;
    attachInterrupt(0, pulse_ISR, RISING);

};

void StatusLights::pulse(int location, int interval, int count, int speed){

    int value = 0;
    previousMillis = 0;
    // while(pulsecnt<count) {
        long currentMillis = millis();

        if (currentMillis - previousMillis >= interval) {
            previousMillis = currentMillis;
            value = 128+127*cos(2*PI/interval*(speed-currentMillis));
            analogWrite(locations[location], value);
        };
    // };
    // digitalWrite(locations[location], LOW);
};

void pulse_ISR() {
    pulsecnt++;
};

```

This is my first time using interrupts to do this - I'm really trying to avoid delays since i need other things to happen synchronously.

Thanks!

# Answer
> 1 votes
You'll want a class function that decides whether 'now' is time to toggle the LED or not, and returns quickly. Call that function frequently from your loop function. Your other class functions will set or clear the whether the LED is to toggled, and when, how many times, etc. Something like the following pseudo-code, which is not a full solution but should point out the essential details:

```
void loop()
{
   myStatusLights.updateLED();     // call this frequently
}

...

void StatusLights::updateLED(){
  if LED_active,
     if it's time to change the LED,
        toggle LED on/off;
        if LED has toggled enough times,
           set LED_active false;
        endif;
     endif;
  endif;
}

```

Update:

> How would you refresh the count, track the pulses, and refresh the state of the status light without any parameters?

Some class-function must initiate the blinking, whether it knows to do it itself or it is called from your application code. That class-function will need to set those parameters. If it to be called from outside, perhaps the outside sets them - ? Only you know that. Either way, they will need to get saved in the class' private data so the .updateLED() function can have access to them. The .updateLED() function will, for instance, count down the remaining number blinks to display, keep track of whether the LED is on or off, actually turn it on or off, etc., until there is nothing left for it to do. In that case it just quickly returns without doing anything.

---
Tags: led, interrupt, robotics, class
---


# Question
Title: ESP-8266 stopped working due to possibly faulty perfboard layout
I have been following this tutorial to set up my ESP8266. I have also recreated on a perfboard the circuit provided in the tutorial, and I intend to use this perfboard circuit in my project.

The problem arises when I plug my ESP into the perfboard and try to talk to it through the serial monitor. When using a baud rate of 115200, the ESP responds to commands but in a garbled format. Also, the blue LED stays on after powerup for increasingly long periods of time. Now the blue LED is always on and the ESP no longer responds to any commands, except when reset and asked for the startup firmware info. I suspect that the ESP is now broken but am not sure how to check.

Also note that the ESP was working fine on a breadboard at 9600 baud, prior to the blue LED incident. Now it won't work with the breadboard either.

All commands were sent with newline and carriage return.

Is the ESP8266 broken? Could there be something wrong with my perfboard circuit? The circuit is rather dense and contains wiring for several other components in addition to the ESP-8266.

# Answer
It turns out the real culprit was the `AT+IPR=9600` command bricking the board. The board was "fixed" by obtaining the firmware and flashing it to the board using `esptool.py`. Download the repo's source code, navigate to the directory `bin/at/`, and see the file `README.md` to see which addresses to flash the different parts to.
> 2 votes

---
Tags: esp8266, softwareserial
---


# Question
Title: Can you save data to heap section in Arduino memory?
On normal computers, heap will be cleaned as you close the program, but can I save data to Arduino's heap with `malloc` function. And will it be cleaned after I power off the Arduino?

# Answer
> 4 votes
Yes, you can use `malloc()` on the Arduino - however it is not something I would recommend you use since memory is at a premium and excessive use of `malloc()` and `free()` causes heap fragmentation which can eat your memory up and cause random crashes (`String` is the biggest culprit of this).

I am not sure what you mean by "clean" the memory. When power is removed the content of the memory is lost. The whole of the SRAM forgets its contents if there is no power to maintain that state. A bit like when you unplug your computer it "forgets" that Windows is loaded.

If you want to retain information with the power removed you need to use the EEPROM.

---
Tags: arduino-uno, c, memory
---


# Question
Title: Arduino Nano, Uno and Mega - XBee connection difference
I have a simple sketch working on arduino Uno and Nano sending data using an XBee. However, if I run the project on an Arduino Mega it does not work.

What differences between Uno/Nano and the Mega could be causing issues?

Connection: I just connect 3.3V-\>3.3V, Gnd-\>Gnd, and have tried various ports for DIN and DOUT (normally pins 2/4, but have tried A0/A1, 22/23 etc..).

Sketch: pastebin

Have brought a second Mega in case of hardware faults, but the problem persists. Have stripped anything which might be tying up a timer. Am choosing the right board type in the arduino IDE.

# Answer
> 1 votes
Not all arduino Mega pins support 'change interrupts', which is needed for Software Serial. Only the following can be used for RX:

10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

---
Tags: arduino-mega, xbee, atmega2560
---


title: ESP8266 TCP/IP communication

text:
# Question
Title: ESP8266 TCP/IP communication
So I'm looking into having a TCP communication between 1 ESP8266 Chip (Station) and 2 ESP8266 (Clients) connected to that station. Every time I find a code including the TCP, they only include things like client.print(). But how can I write a message to a certain IP address in that network.

When I do client.print() it sends the message to ALL the clients. But I want to be able to do something like client1.print() and client2.print()

# Answer
> 4 votes
WiFiClient object wraps a TCP socket. A normal TCP socket is connected to IP address and port. WiFiServer starts a listening socket on a port. If server on listening socket is contacted by a remote client socket, it creates a local socket connected with the remote client socket on a free port and returns a WiFiClient object wrapping the socket. Everything you write or print to a WiFiClient is send to that one remote socket.

If one of your client boards creates a WiFiClient and connects it to IP address and port of the WiFiServer on your 'server' board, then you get there a WiFiClient from server.available() and this two WiFiClient objects are connected. What you write/print on one side you read only from the WiFiClient object on the other side.

client socket

```
if (client.connect(serverIP, PORT)) {
  client.print("request\n");
  String response = client.readStringUntil('\n');
  Serial.println(response);
  client.stop();
}

```

server side

```
WiFiClient client = server.available();
if (client && client.connected()) {
  String request = client.readStringUntil('\n');
  Serial.println(request);
  client.print("response\n");
  client.stop();
}

```

---
Tags: esp8266
---


# Question
Title: Pressing reset button restarts program only seconds latter
I am wondering why after pressing the reset button on my Arduino, the latest program loaded runs but only after about 5seconds. The same thing happen when I run my arduino from the computer using the Arduino 1.6.9 software.

Is there any way to make this delay shorter?

Thanks, IF

# Answer
> 3 votes
The first thing that happens when you apply power to a board or press reset, is the bootloader executes. That waits for a short time to accept a new sketch over the serial port. If nothing arrives it terminates and executes the existing sketch.

On the Uno that delay is only 2 seconds. However on the Leonardo the delay is much longer (around 5-8 seconds) owing to how the serial port is implemented: it has to allow time for the host computer to re-enumerate the USB device after a reset, and that takes a second or two.

If you don't want that delay you will need to remove the bootloader (i.e., ignore it) and program the board through a hardware programmer and the ICSP pins (which will disable the bootloader for you). You lose the convenience of programming through the USB connection though.

Alternatively choose a different board that doesn't have such a delay for the bootloader - one that uses a different programming method.

# Answer
> 0 votes
Having had the same issue , I recently found out that the Leonardo/Micro jumps directly into the user application when it is powered up, either by inserting a USB cable connected to a cellphone charger i.e power only USB , or by connecting external power via the RAW power input. So, if you need a quick restart after reset, just cut and reconnect the power supply.

---
Tags: arduino-leonardo, reset
---


title: Is my board broken by soldering?

text:
# Question
Title: Is my board broken by soldering?
I've soldered a featherwing on my feather, then unsoldered it because it had stopped working: after the soldering of the featherwing, I was unable to upload new software to the board.

But now that the featherwing was removed, I still can't upload a software onto the board.

Here's the complete log I get:

```
$ ~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/bin/avrdude -C~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf -v -v -v -v -patmega328p -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:/tmp/arduino_build_190205/Blink.ino.hex:i

avrdude: Version 6.3, compiled on Jan 17 2017 at 11:00:16
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf"
         User configuration file is "~/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: Send: 0 [30]   [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

avrdude done.  Thank you.

```

I used to have this error from time to time before, but I always was able to make it work, either by using another USB port, choosing the right port for the arduino or rebooting Linux, but now nothing I do works.

So, I think I might have broken the board because of the soldering/unsoldering.

I attached the pictures of both sides of the board.

Three LEDs continue to blink: the red one when I connect the board to the USB, the battery one and the RX one when there is an attempt at transmission.

Can you tell me whether the board looks damage?

# Answer
It looks like you have soldering paste all over the circuit board. If enough paste bridges a gap between the ceramic resonator and the IC, it can attenuate the oscillator signal to the point where the board won't work.

I use an old tooth brush and Isopropyl alcohol to clean excess soldering paste. As the alcohol evaporates, a lot of moisture forms on the circuit board, so it's important to ensure it's completely dry before you power it up.

Try cleaning the circuit board and see if that fixes the problem.

**EDIT:**

I would like to show you how much soldering paste it takes to stop a 328P from working. The following image shows the bottom of a perfboard with 0.1" hole spacing. You can see the soldering paste bridging the gap between pins 8, 9, and 10 of a Atmega328P DIP IC. Pin 8 is ground, and pins 9 and 10 are connected to the crystal / capacitors. All three pins are connected together via the paste, and since I forgot to clean the board before "final assembly", it's possible other pins are connected together via the paste.

The circuit board is from a "kitchen clock project", and was taken the day it stopped working. There are no mechanical connections to this circuit board except for the 328P's IC socket. This clock worked for 3 months, then it quit suddenly. I re-booted it once, it worked for an hour, then it quit again. The only factor that changed after the first three months was a change of seasons (the ambient temperature in the kitchen was reaching 90+ degrees F during the day). I don't know if the "blobs" of paste were touching each other when I assembled it, but they were when it failed. How does thick soldering paste start moving around on it's own? With some heat and Capillary action of course :)

Cleaning the board with Isopropyl alcohol fixed the problem, and the clock has been running for the past 6 months without issue.

**EDIT 2**

When I monitor pin 9 of a 328P on a 5V Arduino Uno, this is the waveform I see.

You can see the small amount of voltage change the oscillator has to make for the 328P to sense it, and function correctly (800mV peak to peak). If the soldering paste is conductive, capacitive or perhaps both, connecting this signal through the paste to ground, power or several other pins can disrupt the signal to the point where the IC fails to operate.
> 2 votes

# Answer
There is flux on the board and that is **not** going to cause the problems you are seeing. At worst the flux may have an affect on the ability to get a proper lock at 2.5GHz, and that is unlikely.

Clean the board and use magnification to look for damage to the copper foil on the board and inside the plated holes. That will most likely be the problem.

This was from a question regarding no-clean fluxes but the information also applies to the use of regular flux as well.

> Today, one of the most common reasons to remove no-clean fluxes is to prevent malfunctions in circuits with clock speeds over 1 gigahertz. "When you get above 1 gigahertz, the electronscan conducted on the outer surface of the conductor. If you have flux on those conductors that have those high clock speeds, it can interfere with these fast signals." http://www.circuitnet.com/experts/73284.html

Most electronics are not cleaned after soldering. The company I work for went to a no clean process 20 years ago.
> 2 votes

---
Tags: adafruit
---


# Question
Title: How to program an Arduino pro mini using native serial port (on my mainboard)
How can I program my Pro Mini using the native RS232 Serial port on my Mainboard (aka com1).

Google-ing did not really help and a quick search here for "pro mini programming com1" did not deliver *any* results.

I already have a MAX232 module connected between the Pro Mini and the PC.

I have already tested the com1 port for function by sending stuff to an Arduino mega via its usb-to-serial port and echo-ing that to com1.

Which succeeded (at least sort-of \[receiving some random clutter in between characters or missing some characters at all\])

I did try the obvious (i.e. selecting pro mini from the board menu and then selecting the com1 port and hit upload).

But that did just produce a timeout-error…

An Option to set the programmer to simple Serial Connection or something similar does not exist to my knowledge (well it does but only if we're talking about STM32 based boards like the blue pill).

# Answer
> 1 votes
To upload a hex file to Arduino over Serial interface, the bootloader must be active. The bootloader is active after reset. It waits a short time if a new application is uploaded. If not, it jumps to existing application.

To reset the MCU on Arduino boards with independent USB chip a circuit connected to DTR line of serial is used.

On a board like the Pro Mini there is no chip for USB neither an auto reset circuit. You must reset the board with the reset button right before avrdude sends the hex file. avrdude tries ten times, so you have 10 chances to time it right after you hit the Upload button.

Some USB-to-TTL-Serial adapters (or RS232 adapters) have the DTR line and it can be used to reset the board.

Or use ISP flashing over the ICSP header with a programmer or other board as programmer.

# Answer
> 0 votes
Open the IDE, select File:Preferences and turn on Verbose Outputs. Press & Hold Reset on the Promini. Start the download. At the end of compilation you will see something like

> Sketch uses 960 bytes (2%) of program storage space. Maximum is 32256 bytes.

Then the IDE will try and download 3 times.

Release Reset when you see the line above - it may take a few tries to get the release timing correct.

---
Tags: serial, arduino-pro-mini
---


title: Precise On/Off control for IR LED

text:
# Question
Title: Precise On/Off control for IR LED
My goal is to be able to send/receive IR messages in my own custom format and send messages ~10 bytes long. My message object will get serialized down to individual bits, which are transmitted by turning the IR LED on/off at specific timings of my choosing to represent logical ones and zeros. From what I've seen, an IR LED can be turned on/off in either a while loop or as a PWM signal in order to transmit the message. I'm under the assumption the only thing gained by using a PWM signal is that the work there is done on a timer callback and let other code run seemingly simultaneously. For simplicity, I opted for the while loop approach.

The issue I am seeing is one of two. Either the receiver is not reading the timings right, or the transmitter is not turning the LED on/off as fast as I would expect.

For the example code below, the IR LED is turned on for 600 microseconds, and off for 300. (Eventually, my custom messages will be built up using something along these lines.) However, as you can see in the Sample Outputs below the receiver is not seeing the IR signal as on or off for anywhere near that amount of time.

Not sure if this is a setup issue, or something else. The two Arduino boards I'm using are both Arduino Pro ATmega328p boards. For the board sending the IR signal, Pin 6 goes to a 330 Ohm resistor, then to the LED, then to ground. The IR Receiver on the other board has no resistors, just direct connections to pins. When reading the IR signals, I hold the receiver a few centimeters away from the LED.

My questions are:

1. Is this a viable setup? Should this work? Or am I all wrong in my assumptions and need to look some other way of doing this?
2. Is my assumption about turning the LED on/off with a while loop vs. a PWM signal true? Or should I remove the loop concept and only use a PWM signal.

IR Transmit Code:

```
#define IRpin          6

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

void loop() {
  //LED On
  PORTD |= (1 << IRpin);
  delayMicroseconds(600);

  //LED Off
  PORTD &= ~(1 << IRpin);
  delayMicroseconds(300);
}

```

IR Receive Code (taken from an online example, only modifications are to output text):

```
#define IRpin_PIN      PIND
#define IRpin          2

// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define RESOLUTION 20

uint16_t pulses[300][2];  // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing

void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

void loop(void) {
  uint16_t highpulse, lowpulse;  // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length

  while (IRpin_PIN & (1 << IRpin)) {
    // count off another few microseconds
    highpulse++;
    delayMicroseconds(RESOLUTION);

    // If the pulse is too long, we 'timed out' - either nothing
    // was received or the code is finished, so print what
    // we've grabbed so far, and then reset
    if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
      printpulses();
      currentpulse = 0;
      return;
    }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;

  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
    // pin is still LOW
    lowpulse++;
    delayMicroseconds(RESOLUTION);
    if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
      Serial.println("Breaking - Hit max Pulse Low");
      printpulses();
      currentpulse = 0;
      return;
    }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
}

void printpulses(void) {
  uint32_t totalMicroseconds = 0;
  for (uint8_t i = 0; i < currentpulse - 1; i++) {
    Serial.print("On(");
    Serial.print(pulses[i][1] * RESOLUTION , DEC);
    Serial.print(");");
    Serial.println("");
    Serial.print("   Off(");
    Serial.print(pulses[i + 1][0] * RESOLUTION , DEC);
    Serial.println(");");

    totalMicroseconds += pulses[i][1] * RESOLUTION;
    totalMicroseconds += pulses[i + 1][0] * RESOLUTION;

    if (i % 8 == 0) {
      Serial.println("");
    }
  }

  Serial.print("On(");
  Serial.print(pulses[currentpulse - 1][1] * RESOLUTION, DEC);
  Serial.print(");");
  totalMicroseconds += pulses[currentpulse - 1][1] * RESOLUTION;

  Serial.println("");
  Serial.print("Total Microseconds: ");
  Serial.println(totalMicroseconds, DEC);
}

```

Sample Outputs:

```
Ready to decode IR!
On(20);
   Off(62064);

On(0);
   Off(12060);
On(360);
   Off(1860);
On(440);
   Off(8940);
On(20);
   Off(15460);
On(80);
   Off(25672);
On(40);
Total Microseconds: 127016
On(40);
   Off(6740);

On(300);
   Off(6740);
On(20);
   Off(8520);
On(40);
   Off(6740);
On(1540);
   Off(15720);
On(40);
   Off(34860);
On(20);
Total Microseconds: 81320

On(3000);
   Off(35384);

On(40);
   Off(14180);
On(1220);
   Off(54440);
On(980);
Total Microseconds: 109244

On(200);
Total Microseconds: 200
On(20);
   Off(29160);

On(60);
   Off(26700);
On(60);
   Off(22880);
On(20);
   Off(2928);
On(20);
Total Microseconds: 81848

```

# Answer
I ended up also asking this question at electronics.stackexchange.com. I know that's frowned upon, but the topic really did toe the line between being an Arduino subject or electronics.

To summarize the accepted answer, no IR messages cannot be sent/received the way I thought. The IR LED needs to be on/off at a frequency that matches what the receiver is set to be able to receive. Generally 38kh. So On for 13 microseconds, then Off for 13 microseconds. Then repeat.

https://electronics.stackexchange.com/questions/417387/precise-on-off-control-for-ir-led/417391
> 0 votes

---
Tags: ir
---


# Question
Title: Can you current-limit Arduino 101 GPIO pins?
A number of questions ask about max possible in/out current on a GPIO pin, that's not my question here. I'm asking if it's possible to set a maximum current limit on a GPIO pin, such that any attempts to draw more than that current would result in the Arduino entering a constant current mode e.g. reducing the pin voltage?

I've read this, this, this, and skimmed the Curie datasheet, but I don't see a feature like this mentioned anywhere.

The only half-answer I have seen is on the Ruggeduino website, which explains that they have added a fuse to each GPIO pin to avoid overcurrent draws due to short circuits.

For context - I have an external sensor that claims to be more reliable with a small amount of constant current. I didn't know if I could easily add that limitation (e.g. max 15mA at 3.3V) into the GPIO pin as a safety measure, so I went on a search to find out which has eventually led me here

# Answer
No. I have never heard of a microcontroller with constant current or current limiting on the GPIO pins.

You may get a *drive strength* on the pins of an FPGA, but I have never seen such a thing on a microcontroller.

In general, if you have a need to reduce the voltage as the current increases you would just slip a resistor in the circuit. Or for more precise control using the GPIO pin to control a *constant current source* or *constant current sink* is the normal way of doing it.

GPIO pins are generally designed for communicating with other logic level devices. They require minimal current. Some microcontrollers provide a higher drive strength to work with larger *fanouts* (lots of devices connected to one pin, such as in SPI buses), but they are not intended for providing power to a device or giving control over their current.
> 3 votes

# Answer
Typically port pins do have some current limiting inherent in the design of the chip. But it isn't something that should be used as protection. More line a fact that should be taken into account when implementing a design.

Say a 3.3 volt processor has a maximum rating of 12mA. With a 5 mA draw from the pin the high output voltage might be 3.0 volts. When 12mA is drawn from the chip the output voltage might only be 2.5 volts. It is important to check the data sheet to determine what you will get under the expected conditions.

A port with an internal pull up option may be considered more like (but not like) a constant current source. But that's stretching things a bit.
> 0 votes

---
Tags: pins, current, arduino-101
---


# Question
Title: Passing class member function as argument
I need to pass a class member function to server.on, unfortunately i get an error.

> error: no matching function for call to 'ESP8266WebServer::on

I have done some searching but could not understand anything I found. No simple explanation.

This works:

```
void handleRoot(){}
server.on("/", handleRoot);

```

This doesn't:

```
void myClass::handleRoot(){}
void myClass::setup(){
    server.on("/", handleRoot);
}

```

The second argument to server.on is

```
typedef std::function<void(void)> THandlerFunction;

```

Unfortunately I have no idea what it means.

# Answer
It's quite common question related to C++ programming.

The extensive explanation can be found here.

The short answer is: it's very different from taking the address of a regular function.

Workarounds (that might or might not work for you, depending on what else you need that function to do) are:

* make it static
* declare it as friend function, rather than member function

Either way, the point is that it should not be something associated to an instance of the class, but rather to the class as a whole.
> 3 votes

# Answer
I've ben hitting this same problem.
Some further research on c++ syntax helped me find this clean solution, based on the

std::bind syntax:

```
server.on("/", std::bind(&myClass::handleRoot, this));

```
> 4 votes

# Answer
This will get the job done - using anonymous function syntax:

```
server->on("/", [&]() {
   handleRoot();
});

```
> 4 votes

---
Tags: c++, arduino-ide, esp8266
---


# Question
Title: How to emulate an analog potentiometer with PWM
I have a piece of electronic that controls a motor. It takes power from AC power.

Now there is a 10KOhm Potentiometer. The data sheet of this controller says that the control signal is 10Vcc.

Here's the connections diagram (in Italian):

I'd like to emulate the Potentiometer with Arduino. I'm not sure if PWM will do the job.

Any hints?

# Answer
Adding to Ricardo's answer:

PWM can do the job, sort of. You need a low pass filter (LPF) to convert the PWM to an analog voltage and an amplifier to take it from 0-5 to 0-10V. Or you can get a dedicated digital-to-analog (DAC) chip but that will obviously be more expensive than a resistor and capacitor for the LPF.

Here's some tutorials on converting your PWM to an analog voltage:

Analog-Output: How-To Arduino’s AnalogWrite – Converting PWM to a Voltage

Then you need to basically double the voltage. You do that with an operational amplifier. The resistors you pick for the op amp set its "gain", in this case you want it to be 2 so you can go from ~5v (max output) to 10v.

Here's an example of that: My First OP-AMP Circuit
> 3 votes

# Answer
You can take an analog (PWM) output from the Arduino and turn it into 0 to 10 V DC using something like this:

## Amplification

The op-amp shown is hooked up as a non-inverting amplifier, where the gain is given by:

VOut / VIn = 1 + (R2 / R1)

Since R2 and R1 in this case are both 1 k then the output will be the input multiplied by:

```
1 + (1000/1000) = 2

```

Thus, if we have 5 V coming from D3 we will have 10 V at the output of the op-amp. We need to supply a bit more than 10 V to the op-amp supply pin (pin 8) because this is not a rail-to-rail op-amp, that is, it cannot output all the way up to its supply voltage.

---

## Low-pass filter

The resistor R3 and the 10 µF capacitor form a low-pass filter that filters the PWM signal from the Arduino into a more-or-less smooth DC voltage.

This shows the difference between the Arduino PWM output, and the output of the op-amp:

You can see from the scope traces that the yellow line (the PWM output) has a 50% duty cycle, and the blue line (the op-amp output) is 5 V and has a slight ripple.

With a 100% duty cycle, the output is 10 V.

---

## Ripple

Switching the scope to AC coupling we can see how much ripple we have in the op-amp output:

The scale for the blue channel has changed in this image, and the cursor shows that we have around 140 mV of ripple.

We can reduce the ripple by using a larger resistor for R3. For example, making it 10 k reduces the ripple to 86 mV.

The larger resistance make the output less responsive to changes at the input (it takes time to charge or discharge the capacitor) but in testing it still seems pretty responsive.

---

## Code

Test code:

```
void setup ()
  {
  }

void loop ()
  {
  analogWrite (3, analogRead (A0) / 4);
  }

```

I had a potentiometer connected to A0 and adjusted it to alter the duty cycle of the PWM output on pin D3.

---

## Theory

You might ask "Why 138 mV of ripple? Why not 50 mV? Why not 200 mV?".

Let's look at the theory. First, the image posted above looks a bit noisy, so let's take an average of the *input* to the op-amp:

Now we can see that the ripple is about 57 mV (the output of the op-amp would be double that). Indeed, the averaged output is `57 * 2 = 114 mV`

The general formula for calculating the time taken by a RC network to reach a certain voltage is:

```
t = -log((V-Vc)/V)R*C

```

Where "exp" is the natural exponent.

See Ladyada - RC Delay Calculator.

Also Mathematical treatment of charging and discharging a capacitor.

```
V  = supply voltage   (initial voltage)
Vc = output voltage   (target voltage)
R  = resistance in ohms
C  = capacitance in farads
t  = time in seconds

```

These figures will be on the RC discharge graph at roughly the point indicated:

See Wikipedia - RC circuit

Introducing our values for the resistor and capacitor (using Lua) we get:

```
VS = 5.0       -- supply voltage
VMED = VS / 2  -- 50% duty cycle
VL = VMED - 27.2e-3   -- low voltage as measured
VH = VMED + 29.6e-3   -- high voltage as measured
RES = 4700            -- resistance in ohms
CAP = 10e-6           -- capacitance in farads

T1 = -math.log ( (VS - VH) /VS) * RES * CAP
T2 = -math.log ( (VS - VL) /VS) * RES * CAP

print ("T1 =", T1)
print ("T2 =", T2)
print ("diff = ", T1 - T2, "seconds")

```

Results:

```
T1 = 0.0331
T2 = 0.0321
diff =  0.0010 seconds

```

The time difference is 1 ms which agrees with the observations.
> 4 votes

# Answer
You can use any typical motor control chip like a ULN2003 with PWM and maybe a smoothing capacitor, Google "ULN2003 Arduino" for many examples.

Based on the pinouts from Ricardo's answer, you'd get the 10V from pin 1 and ground from pin 3, and feed the PWM'd output from the ULN2003 back into pin 2.
> 2 votes

# Answer
I won't be able to answer your question completely, but hopefully I'll be able to make things a bit clearer for someone more knowledgeable to complete the answer.

From what I could understand from the datasheet, inputs 1, 2 and 3 are used to connect a pot that will control the motor speed. It's the POTENZIOMETRO DI COMANDO (control pot) in the figure linked in the question.

The datasheet also specifies (in the figure below) that you can connect terminal 3 to ground and feed terminal 2 with a voltage from 0 to 10Vcc, that will control the motor. That's how you control the motor using a MCU, I suppose.

Here's where my knowledge is getting short. I'm guessing that a PWM signal won't do the trick. You'll need to feed an actual voltage in terminal 2 to control the motor properly. To do that you have a few alternatives:

1. Use an ADC IC
2. Use an R2R resistor ladder network using digital outputs and some means to amplify its voltage to 10Vcc.

I hope this helps a bit.
> 1 votes

# Answer
my solution is simple get a servo (pwm input) and connect the shaft of the servo to the pot with a coupler then just use a simple servo control program
> 0 votes

---
Tags: arduino-uno, potentiometer
---


# Question
Title: How to convert jpeg byte stream into jpeg image and display on 1.8 inch TFT display
I have an ESP32 having a cam and it is transmitting compressed JPEG stream.

* TTGO T-Journal ESP32
* Camera Development Board
* OV2640
* SMA WiFi
* 3dbi Antenna
* 0.91 OLED Camera Board

I have an ESP32 having a 1.8 inch TFT screen and a SD card slot which act as receiver.

* ESP32 TS V1.2
* MPU9250
* 1.8 Inch TFT
* Bluetooth
* Wifi
* MicroSD Card Slot
* Speakers Module

On Chrome browser, I get a display of the JPEG images as a continuous image after image (video).

I can see the incoming compressed JPEG stream and i print it on serial monitor . But I need to decode/ decompress the JPEGstream at receiving end and paint pixel of TFT screen .

Which steps am I missing? Can anybody suggest code of JPEG image rendering on TFT screen?

Sketch of transmitter:

```
#include "OV2640.h"
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiClient.h>

#define ENABLE_OLED //if want use oled ,turn on thi macro

#ifdef ENABLE_OLED
#include "SSD1306.h"
#define OLED_ADDRESS 0x3c
#define I2C_SDA 14
#define I2C_SCL 13
SSD1306Wire display(OLED_ADDRESS, I2C_SDA, I2C_SCL, GEOMETRY_128_32);
#endif

OV2640 cam;
WebServer server(80);

IPAddress apIP = IPAddress(192, 168, 1, 1);

void handle_jpg_stream(void)
{
    WiFiClient client = server.client();
    String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
server.sendContent(response);

while (1)
{
    cam.run();
    if (!client.connected())
        break;
    response = "--frame\r\n";
    response += "Content-Type: image/jpeg\r\n\r\n";
    server.sendContent(response);

    client.write((char *)cam.getfb(), cam.getSize());
    server.sendContent("\r\n");
    if (!client.connected())
        break;
    }
}

void handle_jpg(void)
{
    WiFiClient client = server.client();

    cam.run();
    if (!client.connected())
    {
        return;
    }
     String response = "HTTP/1.1 200 OK\r\n";
     response += "Content-disposition: inline; filename=capture.jpg\r\n";
    response += "Content-type: image/jpeg\r\n\r\n";
    server.sendContent(response);
    client.write((char *)cam.getfb(), cam.getSize());
}

void handleNotFound()
{
    String message = "Server is running!\n\n";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET) ? "GET" : "POST";
   message += "\nArguments: ";
   message += server.args();
   message += "\n";
   server.send(200, "text/plain", message);
}

void setup()
{
    Serial.begin(115200);
    while (!Serial)
    {
        ;
     }
camera_config_t camera_config;
camera_config.ledc_channel = LEDC_CHANNEL_0;
camera_config.ledc_timer = LEDC_TIMER_0;
camera_config.pin_d0 = 17;
camera_config.pin_d1 = 35;
camera_config.pin_d2 = 34;
camera_config.pin_d3 = 5;
camera_config.pin_d4 = 39;
camera_config.pin_d5 = 18;
camera_config.pin_d6 = 36;
camera_config.pin_d7 = 19;
camera_config.pin_xclk = 27;
camera_config.pin_pclk = 21;
camera_config.pin_vsync = 22;
camera_config.pin_href = 26;
camera_config.pin_sscb_sda = 25;
camera_config.pin_sscb_scl = 23;
camera_config.pin_reset = 15;
camera_config.xclk_freq_hz = 20000000;
camera_config.pixel_format = CAMERA_PF_JPEG;
camera_config.frame_size = CAMERA_FS_SVGA;

cam.init(camera_config);

WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
bool result = WiFi.softAP("TTGO-CAMERA", "12345678", 1, 0);
if (!result)
{
    Serial.println("AP Config failed.");
    return;
}
else
{
    Serial.println("AP Config Success.");
    Serial.print("AP MAC: ");
    Serial.println(WiFi.softAPmacAddress());
}

#ifdef ENABLE_OLED
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(128 / 2, 32 / 2, WiFi.softAPIP().toString());
display.display();
#endif

server.on("/", HTTP_GET, handle_jpg_stream);
server.on("/jpg", HTTP_GET, handle_jpg);
server.onNotFound(handleNotFound);
server.begin();
}

void loop()
{
    server.handleClient();
}

```

Sketch of receiver:

```
#include <WiFi.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <Adafruit_ImageReader.h> // Image-reading functions
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPI.h>
#include "WiFi.h"
#include <JPEGDecoder.h>
//#include <FileIO.h>

// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS 16
#define TFT_RST 9  // you can also connect this to the Arduino reset
                  // in which case, set this #define pin to -1!
#define TFT_DC 17

// Option 2: use any pins but a little slower!
#define TFT_SCLK 5   // set these to be whatever pins you like!
#define TFT_MOSI 23   // set these to be whatever pins you like!
#define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 15
#define PIN_NUM_CLK  14
#define PIN_NUM_CS   13

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK,     TFT_RST);

String text="";

const char* ssid     = "TTGO-CAMERA";
const char* password = "12345678";
const char* host     = "192.168.1.1";
const char* url      = "/";

IPAddress local_IP(192, 168, 1, 3);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8); //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional

//PImage logo;

#define BUFFPIXEL 20
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have     padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;               // pixel color for tft
  File     bmpFile; File     bmpFile1;
  uint32_t pos = 0, startTime ;
  uint8_t xx=0; uint16_t yy=0; int ww=0; int hh=0;
  int bmpfilepos;

//How to use -
//tft.fillScreen(ST7735_BLACK);
//testdrawtext(2,3,ST7735_GREEN,text);

void testdrawtext( int leftoffset , int topoffset , uint16_t color ,  String text ) {
  tft.setCursor(leftoffset, topoffset);  // (offset from left margin , offset from top margin. )
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.setTextSize(1);
  tft.print(text  );
    }

void jpegbytesdisplay()
{
 // Create a buffer for the packet
    char dataBuff[240];

    delay(5000);

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  int cnt=0;

  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the cam server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
           "Host: " + host + "\r\n" +
           "Connection: close\r\n\r\n");
  unsigned long timeout = millis();

  while (client.available() == 0)
  {
    if (millis() - timeout > 5000)
    {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

   int max_y=200;
   int ypos =200;
   int max_x=0 ;
   int xpos =0;

  // Read all the lines of the reply from server and print them to Serial

  ImageReturnCode stat;
  while (client.available())
  {
    //================================
   // String line = client.readStringUntil('\r');
   // Serial.print(line);

    //================================
    //bytes put into char[len] databuffer.
    size_t len=client.available();
    unsigned char buf[len];
    client.readBytes(buf, len);

    Serial.println("------------------------");
    Serial.println(len);
    //Serial.write(buf);

     //================================
     // bufffer to tft screen pixel rendering

      int col=0;
  int buffidx =0;
  cnt++;

    tft.fillScreen(ST7735_BLACK);
    tft.startWrite();
    tft.setAddrWindow(0, 0, 500, 500);

String fname="/image2" + String(cnt) + ".jpg";
File myFile = SD.open(fname, FILE_WRITE);
myFile.write(buf,len);
myFile.close();

     for (col=0; col<len; col++)
       {
          Serial.print(buf[col]);
       }
    Serial.println();
    Serial.println("------------------------");

      // For each pixel...
     for (col=0; col<len; col++)
     {
         if (buffidx >= sizeof(buf))
              {
          buffidx = 0; // Set index to beginning
                break;
        }

        b = buf[buffidx++]; //          [B]
        g = buf[buffidx++]; //     [G]
        r = buf[buffidx++]; //   [R]

        tft.pushColor(tft.color565(r,g,b));
                             // Display pixel on tft screen one after another.

   } // end pixel loop.

    //================================

   delay(1000);
    tft.endWrite();
  }

    }

 void setupNormal()
{

   Serial.begin(115200);

   // Use this initializer if you're using a 1.8" TFT
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab

  Serial.println("Initialized");

  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

  tft.fillScreen(ST7735_BLACK);

}

void setup()
{

    setupNormal();
    jpegbytesdisplay();

      }

void loop()
{

}

```

# Answer
> 1 votes
Here is what i found for JPEG image file display on any TFT -

i used JPEGDecoder library and instead of tft.pushColor , i used tft.drawPixel method.

```
  for (int jj  =mcu_y;jj<mcu_y + win_h;jj++)
     {
        for (int ii=mcu_x;ii<mcu_x + win_w ;ii++)
        {
            // TFTscreen.drawPixel(ii,jj,tft.color565(255,0,0));
             TFTscreen.drawPixel(ii,jj,*pImg++ );
        }
     }

```

For BMP , we need rgb values to render each pixel on TFT screen.

But in case of JPG , first we need to decode and create MCU tiles on TFT. Then we paint those MCU tiles by color which we receive from JPEG stream decoder. Here \*pImg is the pointer which hold the color information. As we increment \*pImg++ array , each time we receive new color code of type uInt8\_t type . Within MCU tiles , these color have to be injected . Each MCU tile is colored and drawn in the given sequence by considering where the border line of TFT screen is.

It automatically create a JPEG image .

```
//////////////////////////////////////////////////////////////
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <Adafruit_ImageReader.h> // Image-reading functions

// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS 16
#define TFT_RST 9  // you can also connect this to the Arduino reset
                      // set these to be whatever pins you like!
// in which case, set this #define pin to -1!
#define TFT_DC 17

// Option 2: use any pins but a little slower!
#define TFT_SCLK 5   // set these to be whatever pins you like!
#define TFT_MOSI 23

Adafruit_ST7735 TFTscreen = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

//////////////////////////////////////////////////////////////

#include <JPEGDecoder.h>  // JPEG decoder library

//////////////////////////////////////////////////////////////
// include the necessary libraries
#include <SPI.h>
#include <SD.h>
//////////////////////////////////////////////////////////////

// pin definition for the Mega
#define sd_cs  53
#define lcd_cs 49
#define dc     48
#define rst    47

#define TFT_WHITE 0xFFFF
#define TFT_BLACK 0x0000
#define TFT_RED   0xF800

 //////////////////////////////////////////////////////////////

 #define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 15
#define PIN_NUM_CLK  14
#define PIN_NUM_CS   13

  Adafruit_ImageReader reader;
    ///////////////////////////////////////////////////////

String text="";

// this function determines the minimum of two numbers
#define minimum(a,b)     (((a) < (b)) ? (a) : (b))

  //====================================================================================
    //   setup
    //====================================================================================

void setup() {
  // initialize the GLCD and show a message
  // asking the user to open the serial line
  //////////////////////////////////////////////////////////////////
   // Use this initializer if you're using a 1.8" TFT
  TFTscreen.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
//////////////////////////////////////////////////////////////////

  TFTscreen.fillScreen(TFT_WHITE); // Alternative:

TFTscreen.background(255, 255, 255);

TFTscreen.setTextColor(TFT_RED); // Alternative: TFTscreen.stroke(0, 0, 255);
  TFTscreen.println();
  TFTscreen.println(F("Arduino TFT Jpeg Example"));

  TFTscreen.setTextColor(TFT_BLACK); // Alternative: TFTscreen.stroke(0, 0, 0);
  TFTscreen.println(F("Open serial monitor"));
  TFTscreen.println(F("to run the sketch"));

  // initialize the serial port: it will be used to
  // print some diagnostic info
  Serial.begin(115200);
  while (!Serial) {
    // wait for serial port to connect. Needed for native USB port only
  }

  // clear the GLCD screen before starting
//  TFTscreen.background(255, 255, 255);
  TFTscreen.fillScreen(TFT_WHITE);

  // try to access the SD card. If that fails (e.g.
  // no card present), the setup process will stop.
  Serial.print(F("Initializing SD card..."));

//////////////////////////////////////////////////////////////////

  SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CS);

  if (!SD.begin(PIN_NUM_CS)) {
    Serial.println(F("failed!"));
    while (1); // SD initialisation failed so wait here
  }
  Serial.println(F("OK!"));
//////////////////////////////////////////////////////////////////

  // initialize and clear the GLCD screen
 // TFTscreen.begin();
  TFTscreen.fillScreen(TFT_WHITE); // Alternative: TFTscreen.background(255, 255, 255);

  // now that the SD card can be accessed, check the
  // image file exists.
  if (SD.exists("/EagleEye.jpg")) {
    Serial.println("EagleEye.jpg found on SD card.");
  } else {
    Serial.println("EagleEye.jpg not found on SD card.");
    while (1); // Image file missing so stay here
  }

}

//====================================================================================
//   Main loop
//====================================================================================
void loop() {

  // open the image file
  File jpgFile = SD.open( "/EagleEye.jpg", FILE_READ);

  // initialise the decoder to give access to image information
  JpegDec.decodeSdFile(jpgFile);

  // print information about the image to the serial port
  jpegInfo();

  // render the image onto the screen at coordinate 0,0
  renderJPEG(0, 0);

  // wait a little bit before clearing the screen to random color and drawing again
  delay(4000);

  // clear screen
  TFTscreen.fillScreen(random(0xFFFF));  // Alternative: TFTscreen.background(255, 255, 255);
}

//====================================================================================
//   Print information about the image
//====================================================================================

void jpegInfo() {
  Serial.println(F("==============="));
  Serial.println(F("JPEG image info"));
  Serial.println(F("==============="));
  Serial.print(F(  "Width      :")); Serial.println(JpegDec.width);
  Serial.print(F(  "Height     :")); Serial.println(JpegDec.height);
  Serial.print(F(  "Components :")); Serial.println(JpegDec.comps);
  Serial.print(F(  "MCU / row  :")); Serial.println(JpegDec.MCUSPerRow);
  Serial.print(F(  "MCU / col  :")); Serial.println(JpegDec.MCUSPerCol);
  Serial.print(F(  "Scan type  :")); Serial.println(JpegDec.scanType);
  Serial.print(F(  "MCU width  :")); Serial.println(JpegDec.MCUWidth);
  Serial.print(F(  "MCU height :")); Serial.println(JpegDec.MCUHeight);
  Serial.println(F("==============="));
}

//====================================================================================
//   Decode and paint onto the TFT screen
//====================================================================================
void renderJPEG(int xpos, int ypos) {

  // retrieve infomration about the image
  uint16_t *pImg;
  uint16_t mcu_w = JpegDec.MCUWidth;
  uint16_t mcu_h = JpegDec.MCUHeight;
  uint32_t max_x = JpegDec.width;
  uint32_t max_y = JpegDec.height;

  // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
  // Typically these MCUs are 16x16 pixel blocks
  // Determine the width and height of the right and bottom edge image blocks
  uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
  uint32_t min_h = minimum(mcu_h, max_y % mcu_h);

  // save the current image block size
  uint32_t win_w = mcu_w;
  uint32_t win_h = mcu_h;

  // record the current time so we can measure how long it takes to draw an image
  uint32_t drawTime = millis();

  // save the coordinate of the right and bottom edges to assist image cropping
  // to the screen size
  max_x += xpos;
  max_y += ypos;

   char str[100];
  // read each MCU block until there are no more
  while ( JpegDec.read()) {

    // save a pointer to the image block
    pImg = JpegDec.pImage;

    // calculate where the image block should be drawn on the screen
    int mcu_x = JpegDec.MCUx * mcu_w + xpos;
    int mcu_y = JpegDec.MCUy * mcu_h + ypos;

    // check if the image block size needs to be changed for the right and bottom edges
    if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
    else win_w = min_w;
    if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
    else win_h = min_h;

    // calculate how many pixels must be drawn
    uint32_t mcu_pixels = win_w * win_h;

    // draw image block if it will fit on the screen
    if ( ( mcu_x + win_w) <= TFTscreen.width() && ( mcu_y + win_h) <= TFTscreen.height()) {
      // open a window onto the screen to paint the pixels into
      //TFTscreen.setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1);
      //TFTscreen.setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1);
      // push all the image block pixels to the screen

 ////////////////////////////////////////////////////////

 // while (mcu_pixels--)
 // {
 // TFTscreen.pushColor(*pImg++);
 // } // Send to TFT 16 bits at a time

 ////////////////////////////////////////////////////////

 //  Write all MCU pixels to the TFT window

  for (int jj=mcu_y;jj<mcu_y + win_h;jj++)
     {
        for (int ii=mcu_x;ii<mcu_x + win_w ;ii++)
        {
            // TFTscreen.drawPixel(ii,jj,tft.color565(255,0,0));
             TFTscreen.drawPixel(ii,jj,*pImg++ );
        }
     }

 ////////////////////////////////////////////////////////

    }

    // stop drawing blocks if the bottom of the screen has been reached
    // the abort function will close the file
    else if ( ( mcu_y + win_h) >= TFTscreen.height()) JpegDec.abort();

  }

  // calculate how long it took to draw the image
  drawTime = millis() - drawTime; // Calculate the time it took

 // print the results to the serial port
  Serial.print  ("Total render time was    : "); Serial.print(drawTime); Serial.println(" ms");
  Serial.println("=====================================");

}

```

---
Tags: esp32
---


# Question
Title: Strange values on Serial Monitor even with matched baud rate
I am using the Adafruit Flora, connected with a Max 4466 microphone sensor. When I read values from the pin numbered 12 (which is marked as a11 for analog input on the schematic of the flora) I get random characters in the serial monitor as shown in the attached image, with my code. Trying to read other pins that are connected to nothing doesn't read any information. My baud rate in the serial monitor and the code are the same as you can see in the image.

Looking at the max 4466 explanation on the Adafruit website it says you don't need a capacitor or anything and can just directly plug the out pin on the MAX 4466 to the analog pin on an Arduino. I'm not sure if a different protocol has to be followed for a Flora instead of an Arduino. It also says to convert the information to an actual signal I need to use the FFT libraries, but I don't think this input being read is even correct.

If the FFT library is the problem here, I would need help on how to use it because there is no clear value being read in the example code. I had to set up a delay in the code otherwise the IDE would crash from all the info.Additionally, the VCC on the max is connected to 3.3V, the GND to GND, and the OUT to the #12 pin on the Flora.

# Answer
You can't concatenate string and value inside `Serial.println()`.

Print them using two different `Serial.println()`.

```
int pin12;
int A12 = A12;

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

void loop() {
  // put your main code here, to run repeatedly:
  pin12 = analogRead(A11);

  Serial.print("pin 12 is ");
  Serial.println(pin12);

  delay(5000);
}

```
> 4 votes

---
Tags: serial, error
---


# Question
Title: How do I make a Servo Stop if it Hits Resistance?
I am trying to make a device which will turn a turn key with a servo.

However, I want it to stop turning the turn key if the resistance is too great (meaning it is locked and will not ever turn).

How do I do this? Would I just tell it to turn and then have it turn back after a time (because if it is locked or not it should be done within that time)?

I do not want to damage my servo by having it try to turn something that it can't turn.

I am using an Arduino Uno and the library "Servo.h". The servo being used is a Batan S1123.

# Answer
> 2 votes
It depends on what kind of failure you expect. If you're afraid the motor may break your linkage (the gears, cranks, belts, whatever you have in place), you have to react very fast, and it's only feasible with a current measurement. That would require sensing the current and reacting very quickly on over-current to be effective.

If you know for a fact that your linkage can withstand the stall torque of the motor, you just have to worry about overheating the motor. Such a protection can be done with a position sensor or a limit switch if you happen to have one. You could even implement a protection with no sensors at all: drive the motor for just long enough to do its job and then stop: either it will turn the key or it won't, but it won't overheat if stalled for a second or two.

# Answer
> 1 votes
You could either:

1. Use a limit-switch to sense that the servo has completed it move. If it doesn't complete it a reasonable time, return it to its original position. Or,
2. Measure the motor current by putting a low value resistor inline with the ground side of the motor's power supply. With one of the A/D pins, measure the voltage on the motor side of the resistor, which increases with motor current. You'll need to have figured out how much current the motor draws when operating normally. If the motor stalls, your controller could sense that by seeing that current increase. Pick a value (try 150%, for example) of over-current as an indicator that the motor is stalled, and return it to its original position.

The first way is easier to implement but possibly lets the motor stall while you wait for the expected move time to expire. The second way lets you detect stalling and take action immediately.

# Answer
> 0 votes
The best way is use external feedback. Hall sensor for example. 200-250ms after using servo check status of hall sensor

# Answer
> 0 votes
I suggest detecting the current flowing through the servo or using a potentiometer to detect whether the servo is moving. You could also put a clutch between the servo and the key, but then you wouldn't know the angle of the key at any given time.

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


# Question
Title: Badly formatted characters using JDY-30 bluetooth module
I have a JDY-30 bluetooth module and have it wired like this (except using an Arduino Uno):

It is working, but I need to use it with a 115200 baud rate instead of the default one of 9600. I also got that working. Here is the code:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial (2, 3); // RX, TX

// state | RXD | TXD | GND | VCC | EN

void setup () {
  mySerial.begin(115200);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
}

void loop() {

  while (mySerial.available()) {
    delay(10);
    Serial.write(mySerial.read());
    delay(10);
  }

  while (Serial.available()) {
    mySerial.write(Serial.read());
  }

}

```

But when I type things I often get badly formatted characters.

Some examples:

> 16:32:33.212 -\> +VERSION=Firmware V3.0.6,Bluetooth V4.0 L⸮
>
> 16:32:38.990 -\> +VERSION=Firmware V3.0.6,Bluetooth V4.0 LE

more:

> 16:33:27.144 -\> +NAME=CC61-A
>
> 16:33:30.054 -\> +NAME=CC41-A

If I also use 115200 baud rate for the Arduino, then it gets really worse.

Is there a solution for this?

See more about the JDY-30 here: http://myosuploads3.banggood.com/products/20181203/20181203214419JDY-30-SPP-Bluetooth-Module.pdf

# Answer
> 0 votes
As @Majenko pointed out:

> It is impossible to reliably receive using SoftwareSerial at 115200 baud. The UNO is just too slow for that.

I got results that where a lot better by first making a string when reading and then once we have a string send that. Instead of sending what we read all the time. For example, when I tried `AT+VERSION` now it took me 16 attempts to get a wrong one, and only one character out of 42 was wrong that time.

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial (2, 3); // RX, TX

// state | RXD | TXD | GND | VCC | EN

void setup () {
  mySerial.begin(115200);
  Serial.begin(115200);
  Serial.println("Enter AT commands:");
}

void loop() {

  String input_string = "";

  while (mySerial.available()) {
    input_string += (char)mySerial.read();
  }

  if (input_string != "") {
    Serial.write(input_string.c_str());
  }

  while (Serial.available()) {
    mySerial.write(Serial.read());
  }

}

```

---
Tags: arduino-uno, serial, bluetooth
---


# Question
Title: Why is my servo spinning over 360 degrees?
I decided to try out my servo on my Arduino. I'm pretty new to this and I can't seem to figure out why this is happening. My servo will spin for about 5 seconds in one direction and then it will spin the opposite way for less than a second and pause for about 3 seconds. This is the code I uploaded to my Arduino:

```
# include <Servo.h>
const int servopin = 8;
Servo servo;

void setup() {
  Serial.begin(9600);
  servo.attach(servopin);
  servo.write(0);
}

void loop() {
  servo.write(0);
  delay(5000);
  servo.write(180);
  delay(5000);
}

```

I believe the servo is a Tower Pro Micro Servo 99 (either 9 might be a g) SG90.

# Answer
> 1 votes
I might want to try decreasing the range, e.g. start from 10 instead of 0, or finish at 170 instead of 180. Here is an example:

```
# include <Servo.h>
const int servopin = 8;
Servo servo;

void setup() {
  Serial.begin(9600);
  servo.attach(servopin);
  servo.write(0);
}

void loop() {
  servo.write(10);
  delay(5000);
  servo.write(170);
  delay(5000);
}

```

After checking it works, try experimenting with different ranges to see how your servo reacts.

**For me starting at 7 instead of 0 did the job.**

# Answer
> 1 votes
When I am getting started with my Servo motor SG90, I have experience the same issue, and finally I have solved the issue. I have used external power supply for Servo and my Arduino with laptop USB port and control signal from Arduino to Servo motor make my Servo motor to spinning continuously.

Make sure ground reference of power supply of Servo motor and Arduino are same.

---
Tags: arduino-uno, programming, motor, servo
---


# Question
Title: Detect DS18B20 sensors and correctly assign them to relays
I'm relatively new to microcontroller programming, so please excuse me if my question is dumb. I've created a simple device that allows me to control 4 relays based on temperature. I bought four DS18B20 sensors, 4 relay board and Wemos D1. Everything works fine - I'm able to read the temperature of each sensor based on their address.

But I started wondering how I can replace a single DS18B20 without recompiling the code; currently this isn't possible. After searching a bit I found a couple of questions about the order of 1Wire sensors. For example, this one. I have no control over the order in which sensors are detected.

Is there a best practice when it comes to configuring DS18B20 sensors? I would like to set up my device. By set up, I mean that I would like to assign a specific DS18B20 to a specific relay.

I imagine it like so:

1. Take a new DS18B20, connect it to a device and power the device.
2. The device should scan for DS18B20 sensors. If it finds one then it should assign it to relay 1 and store its address in EEPROM.
3. Then unplug the device from power, plug the second DS18B20 and power the device again.
4. The device again scans for DS18B20 sensors. It finds 2 devices. The first one is known (the address was stored in EEPROM) so it is skipped. The second is assigned to relay 2 and the address is stored in EEPROM.
5. The same procedure is applied to the third and fourth sensors.
6. If four sensors are connected (the addresses are from EEPROM), then the device can run.
7. When the user wants to replace a non-functioning sensor, the same procedure can be used.

As I wrote, I'm new to microcontroller programming, so if there is a better way please let me know. I'm mostly learning by following examples and tutorials, so if anyone knows of an example showing such a configuration procedure I'll be grateful for any materials.

# Answer
> 1 votes
If you can easily disconnect the sensors one at a time then your way is fine.

If you can't easily disconnect them then you can maybe use readings to set the order, although this depends on the environment. If, for example, all the sensors are generally room temperature then you have the code check the temp of all the sensors at start up. If it finds one sensor at less than 0C then assign that sensor to the least-recently-replaced relay index (also stored in EEPROM).

Then when you want to put a sensor into the working set, hold an ice cube on it for a few seconds before powering up the controller. There are other combinations of this technique you can imagine that use a button or jumper wires to specifically set the index of the out-of-range-at-startup sensor.

Alternately if you have an extra pin on the Arduino, then you can make a procedure where you connect a new sensor to that pin before attaching it to the string. You can make a rule like "if you ever see a sensor on pin X then remember its device ID and assign it to relay Y". There are lots of UI ways to pick Y. Note that you do not even need any extra hardware for this.

---
Tags: arduino-uno, esp8266, ds18b20, 1-wire
---


# Question
Title: Print Byte Array in Serial monitor screen of Arduino IDE
I need to print mentioned below byte array on the serial monitor screen of Arduino IDE

```
char b[]= {'0x7E', '0x00', '0x1C','0x90', '0x00', '0x13', '0XA2', '0x00', '0x41', '0x58', '0x1C', '0xCB', '0xFF', '0xFE', '0xC1', '0x7C', '0x00','0x0F', '0x00', '0x01', '0x00', '0x00', '0x37', '0x46', '0x46', '0x46', '0x00', '0x00', '0x00', '0xE7' };
void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(b[]);
delay(500);
}

```

But whenever I am trying a print, the error problem was there which was not resolved which is

```
C:\Users\Misha\Desktop\test\Test_2\Test_2.ino: In function 'void loop()':

Test_2:8:18: error: expected primary-expression before ']' token

 Serial.println(b[]);

                  ^

exit status 1
expected primary-expression before ']' token

```

Any suggestions on this will be great help.

# Answer
> 4 votes
You can’t print an array in that way.

If you want to print an array of hexadecimal value (with two digits), you have to use `sprintf` function and change declaration of `b` array.

```
uint8_t b[]= {0x7E, 0x00, 0x1C, 0x90, 0x00, 0x13, 0XA2, 0x00,
              0x41, 0x58, 0x1C, 0xCB, 0xFF, 0xFE, 0xC1, 0x7C,
              0x00, 0x0F, 0x00, 0x01, 0x00, 0x00, 0x37, 0x46,
              0x46, 0x46, 0x00, 0x00, 0x00, 0xE7};
int i;

void printHex(uint8_t num) {
  char hexCar[2];

  sprintf(hexCar, "%02X", num);
  Serial.print(hexCar);
}

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

void loop() {
  for(i=0; i<sizeof(b); i++){
    printHex(b[i]);
 }

 Serial.println();
 delay(500);
}

```

The output produced is:

> 7E001C900013A20041581CCBFFFEC17C000F0001000037464646000000E7 7E001C900013A20041581CCBFFFEC17C000F0001000037464646000000E7 7E001C900013A20041581CCBFFFEC17C000F0001000037464646000000E7

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: Can not print an element in an specific position in an arduino list
I have been tying to print an element of a list with the same position as the number that it matches, but it does not seem to work and I can not figure out if I made some mistake, could someone please check it? Would really appreciate it

Here are the list declarations:

```
int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char *users[10] = {"Josh", "John", "Frederic", "Mikael", "Anthony", "Charles", "Tom", "Chris", "Steve", "Mike" };

```

And this is what I am using to print the name I need:

```
if (attempt != FINGERPRINT_OK) return -1;
Serial.println ("Belongs to: ");
if(data.fingerID == names[n]) {
    Serial.print(users[n]);
}

```

Complete Code:

```
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);
pinMode (12, OUTPUT);
pinMode (13, OUTPUT);

Adafruit_Fingerprint data = Adafruit_Fingerprint(&mySerial);

int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char *users[10] = {"Josh", "John", "Frederic", "Mikael", "Anthony",
"Charles", "Tom", "Chris", "Steve", "Mike" };

void setup() {
  Serial.begin(9600);
  while (!Serial);
  data.begin(57600);
  if (data.verifyPassword()) {
    Serial.println("Verified connection");
}

  else {
    Serial.println("Unnable to verify connection, try again");
 while (1) { delay(2500); }
}

data.getTemplateCount();
Serial.print("Waiting for one of the:"); Serial.print(data.templateCount);
Serial.println("valid fingerprint");

int getFingerprintIDez();
uint8_t getFingerprintID();

void loop() {
for ( int i = 0; i <= 10; i++) {
 uint8_t attempt = data.getImage();
  switch (attempt) {
   case FINGERPRINT_OK:
   break;
 delay (2500);
}

attempt = data.image2Tz();
  switch (attempt) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
    break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
    return attempt;
  }

 attempt = data.fingerFastSearch();
   if (attempt == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
    digitalWrite (13, HIGH);
    delay(1250 );
    digitalWrite (13, LOW);
  }
   else if (attempt == FINGERPRINT_NOTFOUND) {
   Serial.println("Did not find a match");
   digitalWrite (12, HIGH);
   delay(1250 );
   digitalWrite (12, LOW);
   return attempt;
  }
Serial.print("Found ID #"); Serial.print(data.fingerID);
Serial.print(" with confidence of "); Serial.println(data.confidence);
return data.fingerID;

uint8_t attempt2 = data.getImage();
if (attempt2 != FINGERPRINT_OK) return -1;
 attempt2 = data.image2Tz();
if (attempt2 != FINGERPRINT_OK) return -1;
 attempt2 = data.fingerFastSearch();
if (attempt2 != FINGERPRINT_OK) return -1;
 Serial.println ("Presents: ");
if(data.fingerID == names[n]) {
    Serial.print(users[n]);
}
}
}

```

I am attempting that when a fingerprint is verified, the position that matches it out of all the stored fingerprints gets stored as n so I can later print the name asigned to that same position. Thanks

# Answer
> 1 votes
How about you completely delete

```
int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

```

and instead do:

```
if (attempt != FINGERPRINT_OK)
    return -1;

Serial.println ("Belongs to: ");
Serial.print(users[data.fingerID - 1]);

```

---
Tags: arduino-uno
---


# Question
Title: LCD shows output without pressing the sensor
```
#include<LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);
#define vibrate_sense 7

char str[70];
char *test="$GPGGA";
char logitude[10];
char latitude[10];

int i,j,k;
int temp;
//int Ctrl+z=26;    //for sending msg
int led=13;

void setup()
{
  lcd.begin(16,2);
  Serial.begin(4800);
  pinMode(vibrate_sense, INPUT);
  pinMode(led, OUTPUT);
  lcd.setCursor(0,0);
  lcd.print("..Initializing..");
  lcd.setCursor(0,1);
    lcd.print("....System...");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
  lcd.print("Searching for");
    lcd.setCursor(0,1);
      lcd.print("Gps Signals");
  delay(2300);
lcd.clear();
  lcd.setCursor(0,0);
    lcd.print("Setup Completed");
  delay(500);
  lcd.setCursor(0,0);
    lcd.print("Accident detect");
  lcd.setCursor(0,1);
    lcd.print("& Alert system");
  delay(1500);
  lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("No accident");
        lcd.setCursor(0,1);
        lcd.print("occured");

}

void loop()
{
  if (digitalRead(vibrate_sense)==0)
  {
    for(i=18;i<27;i++)          //extract latitude from string
    {
      latitude[j]=str[i];
      j++;
    }

    for(i=30;i<40;i++)          //extract longitude from string
    {
      logitude[k]=str[i];
      k++;
    }

lcd.clear();
    lcd.setCursor(0,0);        //display latitude and longitude on 16X2 lcd display
    lcd.print("Latitude(N)");
    lcd.print(latitude);
    lcd.setCursor(0,1);
    lcd.print("Longitude(E)");
    lcd.print(logitude);
    delay(500);
    lcd.clear();
        lcd.setCursor(0,0);
    lcd.print("Accident has");
            lcd.setCursor(0,1);
    lcd.print("been Detected");
delay(500);
lcd.clear();
    lcd.print("Sending SMS");
    delay(500);
    lcd.clear();
    Serial.begin(9600);

    Serial.println("AT+CMGF=1");    //select text mode
    delay(10);
    Serial.println("AT+CMGS=\"7066128969\"");  // enter receipent number
    Serial.println("Vehicle Accident occured:");
    Serial.print("Latitude(N): ");             //enter latitude in msg
    Serial.println(latitude);                  //enter latitude value in msg
    Serial.print("Longitude(E): ");            //enter Longitude in Msg
    Serial.println(logitude);                  //enter longitude value in msg
    Serial.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
    Serial.println(latitude);
    Serial.println("+");
    Serial.println(logitude);
    Serial.write(26);                      //send msg  Ctrl+z=26

      lcd.setCursor(0,0);
    lcd.print("SMS Sent");
delay(1000);
lcd.clear();
          lcd.setCursor(0,0);
    lcd.print("Help Please");

    temp=0;
    i=0;
    j=0;
    k=0;
    delay(20000);                        // next reading within 20 seconds
    Serial.begin(4800);
  }
}

void serialEvent()
{
  while (Serial.available())            //Serial incomming data from GPS
  {
    char inChar = (char)Serial.read();
     str[i]= inChar;                    //store incomming data from GPS to temparary string str[]
     i++;
     if (i < 7)
     {
      if(str[i-1] != test[i-1])         //check for right string
      {
        i=0;
      }
     }
    if(i >=60)
    {
     break;
    }
  }
}

```

This is my code for my project.
It is accident detection system and it has to work like, when I press the sensor or limit switch, it has to show a message on an LCD that an accident occurred. But it shows the message on the LCD WITHOUT pressing the sensor button.

What to do? I think there is a mistake in my program. Can anybody please tell me where it is?

# Answer
> 1 votes
First off I edited indentation in your code because incorrect indentation is little bit confusing.

```
#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);
#define vibrate_sense 7

char str[70];
char *test="$GPGGA";
char logitude[10];
char latitude[10];

int i,j,k;
int temp;
//int Ctrl+z=26;    //for sending msg
int led = 13;

void setup(){
  lcd.begin(16,2);
  Serial.begin(4800);

  pinMode(vibrate_sense, INPUT);
  pinMode(led, OUTPUT);

  lcd.setCursor(0,0);
  lcd.print("..Initializing..");
  lcd.setCursor(0,1);
  lcd.print("....System...");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Searching for");
  lcd.setCursor(0,1);
  lcd.print("Gps Signals");
  delay(2300);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Setup Completed");
  delay(500);
  lcd.setCursor(0,0);
  lcd.print("Accident detect");
  lcd.setCursor(0,1);
  lcd.print("& Alert system");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("No accident");
  lcd.setCursor(0,1);
  lcd.print("occured");
}

void loop(){
  if (digitalRead(vibrate_sense) == 0){
    for(i = 18; i < 27; i ++){          //extract latitude from string
      latitude[j]=str[i];
      j++;
    }

    for(i=30;i<40;i++){          //extract longitude from string
      logitude[k] = str[i];
      k++;
    }

    lcd.clear();
    lcd.setCursor(0,0);        //display latitude and longitude on 16X2 lcd display
    lcd.print("Latitude(N)");
    lcd.print(latitude);
    lcd.setCursor(0,1);
    lcd.print("Longitude(E)");
    lcd.print(logitude);
    delay(500);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Accident has");
    lcd.setCursor(0,1);
    lcd.print("been Detected");
    delay(500);
    lcd.clear();
    lcd.print("Sending SMS");
    delay(500);
    lcd.clear();
    Serial.begin(9600);

    Serial.println("AT+CMGF=1");    //select text mode
    delay(10);
    Serial.println("AT+CMGS=\"7066128969\"");  // enter receipent number
    Serial.println("Vehicle Accident occured:");
    Serial.print("Latitude(N): ");             //enter latitude in msg
    Serial.println(latitude);                  //enter latitude value in msg
    Serial.print("Longitude(E): ");            //enter Longitude in Msg
    Serial.println(logitude);                  //enter longitude value in msg
    Serial.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
    Serial.println(latitude);
    Serial.println("+");
    Serial.println(logitude);
    Serial.write(26);                      //send msg  Ctrl+z=26

    lcd.setCursor(0,0);
    lcd.print("SMS Sent");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Help Please");

    temp = 0;
    i = 0;
    j = 0;
    k = 0;
    delay(20000);                        // next reading within 20 seconds
    Serial.begin(4800);
  }
}

void serialEvent(){
  while (Serial.available()){            //Serial incomming data from GPS
    char inChar = (char)Serial.read();
    str[i] = inChar;                    //store incomming data from GPS to temparary string str[]
    i++;
    if (i < 7){
      if(str[i-1] != test[i-1]){         //check for right string
        i = 0;
      }
    }
    if(i >= 60){
      break;
    }
  }
}

```

---

Second thing is this line `if (digitalRead(vibrate_sense) == 0){` you are checking there vibrate\_sense for value 0. Are you sure, that triggered value is 0 and not 1? Try this code to test which value is equal to triggered state.

```
#define vibrate_sense 7

void setup() {
  Serial.begin(9600);
  Serial.println("Sensor testing");
  pinMode(vibrate_sense, INPUT);

}

void loop() {
  Serial.println(digitalRead(vibrate_sense));
  delay(300);
}

```

---

Last thing is connection of your sensor/button. For button you have to use also PULL\_UP/PULL\_DOWN resistor to have correct logic value on digital pin.

---
Tags: lcd, sketch
---