# Question
Title: Any reason to acquire more watts than really needed?
Basic question (again):

I have a LED-strip that requires 5V, and each LED (150 in total) requires about 60 milliamps. Calculating everything, I need 3 of these LED-strips (450 LED in total). This in turn tells me that they require 27 000 milliamps (27 amps), which is about 135W. Which means I need an external power supply to power them. I think about buying a 5V 40A (200 W), which should be sufficient(?).

But, is there any reason that I should not buy anything with more watts (250 or 300)?

Thanks for any help!

# Answer
Are you sure every led is 60 mA? Or you mean maybe each Red, green and blue led inside each led (3 x 20 mA).

You always should buy slightly more than you need (but you think about 200W instead of 135W) already which is more than enough safety overhead.

Why would you need more? If you mean to control it with an Arduino Uno, that MCU (including the LEDs etc) is high likely more than a few hundred mA. So the only reason why you need more, is if you want to control later more LED strips, or any motor or other power hungry external devices.
> 0 votes

---
Tags: arduino-uno, power
---


# Question
Title: WS2812B LED Stripe going crazy with Arduino and External Power Supply
I have a simple connection here:

* A WS2812B 5m 300 leds strip 5V;
* A Power Supply MS-150-5 150W 5V;
* Arduino with a simple code to blink 10 first leds;

TEST: If I connect my power supply to my LED with a wireless controller with some saved presets, everything works fine. Colors, red, blue, white ( some voltage downhere ), but ok, working. If take off the wireless controller and connect the LED to the Arduino, GND,+5, DATA, with a simple code, it's ok, 10 leds blinking, working fine. BUT if I connect only the data to Arduino and connect the power to my power supply, now all the stripe go crazy, show no sense colors.

The Arduino code is ok, voltage is ok. Power supply is big enough. Even say to blink only one light is turning on all leds.

I was with a differente power supply before, same but 70w and was working ok. Now with 150w is not working. Why is not working with this one that is bigger? Maybe any noise ?

I'm connecting the power supply directly to the LED and only using the Arduino Data.

# Answer
Just make sure the Gnd from the Arduino and power supply are connected together - otherwise it would cause a common issue. Another recommendation would be to include a capacitor, usually a size of 1000uf is recommended.
> 1 votes

# Answer
Tks for reply guys. Thats correct. I have connected the GND of the external power supply with the GNC of Arduino and everything is fine.
> 0 votes

---
Tags: power, ws2812
---


# Question
Title: What is the best way to connect multiple Arduinos?
In my situation, I have a map divided into multiple parts, each part could have about 20 to 100 Arduinos that they should send information from time to time to the master. How could I do this?

Second problem. How could I use the other Arduinos to send the info from Arduino that are so far from the Master?

Example in part 1: Arduino X is 500 meters far away from the master. How could use the other to send the information?

Can I do this with NodeMcu or such equipment with built-in WiFi?

# Answer
I think you should start with using Wifi modules and you use an esp-01 too instead of NodeMCU. Once you are familiar with esp-01's, you will find them as good as NodeMCU. Esp-01's only lack multiple pins when compared to NodeMCU.

And for communication between arduino and esp-01, use serial ports- 0 and 1.

Here is example code- For Master Arduino

```
int temp;
int hum;

void setup(){
 Serial.begin(115200);
 delay(2000);
}
void loop() {

 temp = random(0,100);
 hum = random(100,200);
 Serial.print(temp);
 Serial.println('t');
 delay(2000);
 Serial.print(hum);
 Serial.println('h');
 delay(2000);
 Serial.flush();
}

```

For Slave Esp or any other slave arduino -

```
String inString = "";    // string to hold input

float temp = 0,hum = 0;

boolean newtemp=false, newhum=false;

void setup() {
  Serial.begin(115200);
  Serial.println("ESP 8266 - 01 Module is ready to receive codes from Master Arduino");
 }

void loop() {
  // Read serial input:
  while (Serial.available() > 0) {
    int inChar = Serial.read();

    if (inChar != '\n') {

      if (inChar == 't')
      newtemp = true;

      if (inChar == 'h')
      newhum = true;

      inString += (char)inChar;
    }
    else {
      Serial.print("Input string: ");
      Serial.println(inString);
      if ( newtemp == true ) {
      temp = inString.toFloat();
      Serial.print("Received Temperature:");
      Serial.println(temp);
      newtemp = false;
      }
      if ( newhum == true ) {
      hum = inString.toFloat();
      Serial.print("Received Humidity:");
      Serial.println(hum);
      newhum = false;
      }
      inString = "";
    }
  }
}

```

Pin connections -

Master Arduino TX -- Slave board RX
> 1 votes

# Answer
This is a classical application for `LoRa` technology, not WiFi. Designing a `LoRa` mesh is no simple task, though.

Check this post, or this other post
> 1 votes

# Answer
You could use low radio frequency modules to get to the 500m. For example there are the so called xbee modules (XBee Pro 60mW PCB Antenna - Series 1). You can find cheaper ones, but from my experience they are a bit harder to understand and not reliable.

You can make a TCP-like connection, where before data is send, the "slave" asks the "master" whether he can catch data or not. If not, he'll just keep asking after a delay has passed till he gets through. Even though TCP is mostly used in WiFi 2.4G, you could still apply it to your project

If you want to use WiFi than you can make a connection between the "slave" and "master" by having some middle man chips in between that pass on the data, but you would need the middle man chips to be constantly powered on (or use a RTC to time the "wake time").
> 0 votes

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


# Question
Title: Parsing HTML GET request with params with WiFiEsp
So I'm Setting up webserver with esp-01f+arduino uno. I'm using WiFiEsp library. I want to toggle led on. Pin will be given in GET request by url. Example: host.com/?ledpin=9 How can I parse it, then get 9 number?

Code:

```

#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif

char ssid[] = "Twim";            // your network SSID (name)
char pass[] = "12345678";        // your network password
int status = WL_IDLE_STATUS;

int ledStatus = LOW;

WiFiEspServer server(80);

// use a ring buffer to increase speed and reduce memory allocation
RingBuffer buf(8);

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT); // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);   // initialize serial for debugging
  Serial1.begin(9600);    // initialize serial for ESP module
  WiFi.init(&Serial1);    // initialize ESP module

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  printWifiStatus();

  // start the web server on port 80
  server.begin();
}

void loop()
{
  WiFiEspClient client = server.available();  // listen for incoming clients

  if (client) {                               // if you get a client,
    Serial.println("New client");             // print a message out the serial port
    buf.init();                               // initialize the circular buffer
    while (client.connected()) {              // loop while the client's connected
      if (client.available()) {               // if there's bytes to read from the client,
        char c = client.read();               // read a byte, then
        buf.push(c);                          // push it to the ring buffer

        // printing the stream to the serial monitor will slow down
        // the receiving of data from the ESP filling the serial buffer
        //Serial.write(c);

        // you got two newline characters in a row
        // that's the end of the HTTP request, so send a response
        if (buf.endsWith("\r\n\r\n")) {
          sendHttpResponse(client);
          break;
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (buf.endsWith("GET /H")) {
          Serial.println("Turn led ON");
          ledStatus = HIGH;
          digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
        }
        else if (buf.endsWith("GET /L")) {
          Serial.println("Turn led OFF");
          ledStatus = LOW;
          digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
        }
      }
    }

    // close the connection
    client.stop();
    Serial.println("Client disconnected");
  }
}

void sendHttpResponse(WiFiEspClient client)
{
  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:text/html");
  client.println();

  // the content of the HTTP response follows the header:
  client.print("The LED is ");
  client.print(ledStatus);
  client.println("<br>");
  client.println("<br>");

  client.println("Click <a href=\"/H\">here</a> turn the LED on<br>");
  client.println("Click <a href=\"/L\">here</a> turn the LED off<br>");

  // The HTTP response ends with another blank line:
  client.println();
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

```

Details gives me only this:

```
GET /favicon.ico HTTP/1.1
Host: 192.168.0.165:5000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://192.168.0.165:5000/H
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7

```

# Answer
The answer is to use indexOf and substring functions of response String
> -1 votes

---
Tags: esp8266, led, wifi, arduino-uno-smd
---


# Question
Title: How to power and switch on / off multiple boards at the same time?
I have many nodes.

Each node consists of an MPU9250 and ESP32. Each node functions independently. They don't interact with each other.

How can I power all of them at the same time, and switch them all on / off at the same time easily ?

# Answer
> 0 votes
You need to provide more details. How many is "many"? How far apart are they physically? Can you run wires between them? Could you use radio control?

You said in the comments that they are each powered by separate batteries.

One possibility would be to put a power MOSFET transistor on each battery, switching the power supply for a given node. Then wire the gates (and grounds) all together and control them with a switch connected to the supply from one of your batteries (or from a 5V logic line.) MOSFETs draw almost no power at idle, and draw very little gate current for switching, so you should be able to drive dozens of them from a single 5V control line. However, this would require that you have a wire running from a central switch to every node, as well as a common ground to all of them.

---
Tags: power, esp32, imu
---


# Question
Title: Error Compiling sketch for Arduino Uno(ld return 1)
I have got an telnet server with esp8266 + SoftwareSerial+ UNO, and here I want to on led with command ON . will be 1 or 2. It is for recive 1 or 2 numbered pins. And I extract pin from request with indexOf and substring functions and write:

```
pinMode(pin,OUTPUT);
digitalWrite(pin,HIGH);

```

I write if pin is not 0 or 1 and it is in range 2-9 for type 1 and if pin is in range 10-13. But at compile time it gives me error compiling for uno. And it gives me this error whn I use pinMode. When I write it to setup it don't give me error. Why? What happenes?

Full code:

```
#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif
 String res = "";
char ssid[] = "ssid";            // your network SSID (name)
char pass[] = "passs";         // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
int reqCount = 0;                // number of requests received

WiFiEspServer server(23);

 WiFiEspClient client;

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

  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
Serial.println(WiFi.localIP());

WiFi.config(IPAddress(192,168,0,165));

  // start the web server on port 80
  server.begin();
}

void loop(){
  if(!client){
    client = server.available();
    if(client){
      client.println("Welcome to telnet server!, 192.168.0.165:23");
      client.flush();
    }

  }

  if(client){
if(client.available()>0){
  res = "";
  while(client.available()>0){

char c = client.read();

res += c;

  }
  Serial.println(res);

int i = res.indexOf("ON")+3;
int j = i+1;
String hh = res.substring(i,j);
int type = hh.toInt();
Serial.println(hh);
if(type == 1)
{
  int ii = res.indexOf("ON")+5;
int jj = ii+1;
String hhh = res.substring(ii,jj);
Serial.println(hhh);
int ihhh = hhh.toInt();
if(ihhh != 0 && ihhh != 1 && (2 <=ihhh)&& ( ihhh <= 9 ))
{
  pinMode(ihhh,OUTPUT);
  digitalWrite(ihhh,HIGH);
}
else{
  client.print("Pin is TX/RX, or not 2<= pin <=9\r\n");
  client.flush();
}
}else if(type == 2){
    int iii = res.indexOf("ON")+5;
int jjj = iii+2;
String hhhh = res.substring(iii,jjj);
Serial.println(hhhh);
int ihhhh = hhhh.toInt();
if(ihhhh != 0 && ihhhh != 1 && !((2<=ihhhh)&&(ihhhh <= 9)) && (10 <= ihhhh)&&(ihhhh <= 13 ))
{
  pinMode(ihhhh,OUTPUT);
  digitalWrite(ihhhh,HIGH);
}
else{
  client.print("Pin is TX/RX, or not 2<= pin <=9\r\n");
  client.flush();
}
}

}

    if(!client.connected())
    Serial.println("Client disconnected from Telnet Server");

  }

}

```

Error is:

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE\_1.8.21.0\_x86\__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\HardwareSerial.cpp: In member function 'availableForWrite':

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE\_1.8.21.0\_x86\__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\HardwareSerial.cpp:203:1: internal compiler error: Segmentation fault

}

^

Please submit a full bug report,

with preprocessed source if appropriate.

See http://gcc.gnu.org/bugs.html for instructions.

lto-wrapper.exe: fatal error: C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE\_1.8.21.0\_x86\__mdqgnx93n4wtt\hardware\tools\avr/bin/avr-gcc returned 1 exit status

compilation terminated.

c:/program files/windowsapps/arduinollc.arduinoide\_1.8.21.0\_x86\__mdqgnx93n4wtt/hardware/tools/avr/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed

collect2.exe: error: ld returned 1 exit status

exit status 1 Error compiling for board Arduino/Genuino Uno.

Arduino IDE version is: 1.8.9(Windows Store 1.8.21.0)

# Answer
This is a bug in the compiler (linker) used by the Arduino AVR Core. It's not because of a bug in your code, and there's not much you can do about it except using a different version of the AVR Core.

See this forum post:

> Here's the traditional workaround:
>
> 1. Tools \> Board \> Boards Manager
> 2. Wait for downloads to finish.
> 3. When you move the mouse pointer over "Arduino AVR Boards", you will see a "Select version" dropdown menu appear. Select "1.6.21".
> 4. Click "Install".
> 5. Wait for installation to finish.
> 6. Click "Close".
> 2 votes

---
Tags: arduino-uno, esp8266, wifi, web-server, avr-gcc
---


# Question
Title: Problems / doubts on battery-powered Arduino Nano WiFi weather station I built
I've almost finished my first Arduino project and I'm realizing I might have gone a bit over my head - I'm a web programmer, I have a very basic electronics knowledge and started tinkering with Arduino with just a couple simple, tutorial-like small circuits.

I then started building this project of a battery-powered Weather Station that sends sensors data via WiFi to my server - I managed to have a working product but I'm bumping into issues that are starting to look a bit bigger than what they initially seemed.

The workflow (schematics follow):

On the +5V pin of the Arduino Nano (actually a cheap chinese clone) I've put an **AMS1117** to stabilize down the voltage to **3.3V** (the 3.3V ArduinoNano output wasn't powerful enough), and from there I power several modules; a **DS3232** wakes up the Arduino (pin 2) when put in deep sleep mode (every 30 mins); when woken up I read data from the **DHT11** (humidity), the **BMP085** (pressure), the **DS18B20** (temperature) and **FC-37** (rain), I connect to my WiFi using the **ESP-01**, send data to my server, and put the Arduino back to sleep until the next cycle.

Everything worked when on the breadboard, worked after building the circuit with a perfboard; heck, it worked even when connected to my power supply, which is something similar to this project: https://www.arduinolab.net/solar-li-ion-charger-and-power-supply-for-arduino/

My battery is a **3,7V 2500mA** instead, but all components are almost the same and I use a regular USB - type B cable to connect this to my Arduino Nano

But after an hour or so it stopped working - I checked again by connecting the Arduino to my PC and it appeared to be fine, but when connected to the battery everything was powered up (all leds on!) but the ESP wasn't trasmitting (never saw the flashing blue led).

So I started some reading around and I tought it might be a problem of too much current needed, and the battery wasn't enough anymore after it got under a certain voltage (I still measured 3.80V on the battery terminals though..)...

This is what I'm thinking:

1. to **cut/remove the LEDSs** from all the modules (dht, rtc, fc-37 has two!, AMS1117) to save power (it's 5 LEDs + the arduino power on LED). Is it safe? Will they still work with the LED circuitry interrupted?
2. connect my power source directly to the Vin+ of the AMS1117, instead of using the **+5v Arduino output** pin (but I read it can safely outsource 500mA, which is the limit for the USB power in anyway, so it shouldn't be an issue...)
3. for the "long run", use a transistor to power on the sensors when Arduino is awaken, keeping them off the rest of time to spare battery juice, if nothing else...But I really don't know how to start for this, I thought of an NPN transistor (I have a PN222A available) with Base to Arduino (through a 1k Ohm Resistor), Collector to +5V and Emitter to the AMS1117 Vin+, is this sensible?
4. increase power output? but how? the power source lets 5V 600mA through a regulated DC-DC booster, it should be ideal in theory...How do I understand if it's right for me?
5. Ditch the ESP01 in favor of the **NRF24L01** (I already have a couple of these, but any other suggestion is appreciated)...but that would require a new setup, new coding (never used those modules), a "receiver" that then sends to wifi, and btw I don't know if the signal can make it from the balcony (where I plan to put the WeatherStation) to the inside of the house (I think it will, as the WiFi does - at least I think it does)

I don't really know how to actually measure the consumption of my circuit...I've read something around but, as I said, my electronics knowledge is limited, I don't have much spare time to dedicate on this, and therefore I cannot figure out without a clear guidance, sorry...

I'm not attaching my code because I don't think it's necessary - the sleep mode I'm using is SLEEP\_MODE\_PWR\_DOWN from the avr/sleep.h library, other than that it works fine as it is.

Can someone give me suggestions or pointers on how to analyze my problem? Am I on the right track or my reasonings are off?

Thanks for any help you could provide, if you need any more info I'll do my best (in due time though, as I said I've not that much time to work on this...if I could muster 1 or 2 hours a week it would be a dream!)

# Answer
You are wasting a lot of power in your system. You need to be far more efficient when running off battery.

1. Don't boost your battery voltage to 5V. Instead use a system that runs entirely at 3.3V.
2. Never use a linear voltage regulator like the AMS1117 since it just wastes power as heat. Instead use a switching "buck" regulator.
3. Turning off modules when not being used is a very good idea. Sleeping the Arduino only saves some of the power - the modules will all still consume power.

I would suggest the ideal way forward would be:

1. Remove the Arduino from the schematic completely
2. Replace the ESP-01 with an ESP8266 module with more pins, or better still an ESP32 module.
3. Connect all the sensors (optionally with P-channel MOSFETs to control the 3.3V supply to them) direct to the ESP32
4. Remove the 5V boost from the power supply
5. Connect the power supply through a 3.3V switching regulator to power the whole circuit.
> 3 votes

---
Tags: esp8266, sensors, arduino-nano, power, current
---


# Question
Title: Maximum frequency of digital signal in Arduino Uno?
As Arduino Uno has a 16 MHz oscillator but while running program it has less frequency because some of the processing power is used for running the program. I have used the `delay(1)` but it is giving me around 500 Hz.

**My questions:**

1. Is there any way to achieve more than 500 Hz?
2. What would be the maximum frequency of digital signal for below program?

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

void loop() {
  digitalWrite(13, HIGH);
  digitalWrite(13, LOW);
}

```

# Answer
1. Yes, use the hardware timers.
2. You can achieve 8 MHz.

Example sketch which outputs 8 MHz on pin 9 on a Uno:

```
#ifdef __AVR_ATmega2560__
  const byte CLOCKOUT = 11;  // Mega 2560
#else
  const byte CLOCKOUT = 9;   // Uno, Duemilanove, etc.
#endif

void setup ()
  {
  // set up 8 MHz timer on CLOCKOUT (OC1A)
  pinMode (CLOCKOUT, OUTPUT);
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS10);   // CTC, no prescaling
  OCR1A =  0;       // output every cycle
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

```

If you change OCR1A you can get lower frequencies. If you change the prescaler you can get lower frequencies again.

See my page about timers for more details.
> 9 votes

# Answer
Also, don't forget that there are alternative methods of toggling outputs.

You can use PORTS to do the job.

Here's a good example. And another here.

And this code is the idea behind it:

```
void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11111111; // set PORTD pins (digital 7~0) high
  PORTD = B00000000; // set PORTD pins (digital 7~0) low
}

```

P.S. Don't forget that the port numbering is in reference to the chip pins and not the Arduino pins/legs.
> 2 votes

# Answer
**Nick Gammon's** code worked fine for me. Here is an **oscilloscope picture** of the waveform I've got from **his code**:

His code above (*from Nick Gammon, on Jan 25 '16 at 20:33*) worked excellent for me. I used his code on Arduino UNO and got about **7.9 MHz** of output frequency on an approximately **1 V amplitude** (peak-to-peak, with spikes making it go to about **2 V peak-to-peak amplitude**).

The image above was obtained with my 40 MHz Oscilloscope from *ICEL Manaus* (manufacturer) at pin 9 (I used the Arduino UNO), with a LED and a resistor as a load at pin 9:

* a green LED of about 1.79 V voltage drop
* and a 4.7 Ohms resistor with 5% tolerance

The oscilloscope probe (*Channel 2, with fall slope trigger detect*) is on the 4.7 Ohms resistor. It follows the connection order out of the pin 9 from Arduino UNO: *PIN 9* \> *green LED* \> *4.7 Ohms resistor* \> *GROUND*.

The green LED keeps blinking at a normal luminescence, as compared when used at other output frequencies.

I used a external 5 V DC power supply, along with the USB connection on my PC.

If you have any questions just put them here. Thanks and thanks Nick Gammon
> 2 votes

---
Tags: arduino-uno, frequency
---


# Question
Title: tty doesn't list ttyUSB0 so arduino doesn't list serial ports
Okay so lsusb gives Bus 002 Device 019: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

dmesg|grep 'ttyUSB' gives

\[63723.589107\] usb 2-1: ch341-uart converter now attached to ttyUSB0

but tty lists only /dev/pts/0 although in /dev there is a ttyUSB0 file (or whatever it is because vim says its not a file)

I can use cu -l /dev/ttyUSB0 -s 9600 and transmit to arduino nano as the rx LED blinks. On starting arduino I get the "java.lang.NullPointerException thrown while loading gnu.io.RXTXCommDriver" error.

System: Linux Mint 19.1 Tessa (64 bit)

# Answer
Sorry, I was using the software center to get arduino IDE and that didn't work well. Downloading the official IDE from arduino.cc worked without hassle. Lesson learnt: Not all linux distros have package repos as up-to-date as Arch. :P
> 2 votes

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


# Question
Title: Arduino memory issue with old HP HDSP-2000 display chips
I'm running into memory issues with an Arduino Nano driving some old HDSP-2000/HDSP-2011 chips.

I cannot seem to get the ASCII 5x7 array into `PROGMEM` and have it read properly. It's so low on memory that I set up a second Arduino to send `char[]` strings through I2C to keep the Nano from locking up. This sort of worked to my advantage that I can multi-task and I'll probably keep it that way but it still keeps locking up or spitting gibberish.

The display Arduino is constantly bit-banging the displays - multiplexed with two 14-bit (acts as one 28-bit) Serial in / parallel out shift registers and and 5 column drivers. All displays use 5 common anode + columns, which have to be pulse timed with the registers.

```
#include <Wire.h>

//*** HDSP2011 Display Demo
//*** ASCII-DEMO
//*** phuinink@gmail.com
//*** Paul Huinink has a webpage on displays www.huinink.info and specifically HDSP200X series displays www.spagmon.com
//*** Modified December-2013 by Patrick Hickey: added HP HDSP single digit display and RGB LED
//*** Patrick Hickey ph@nipht.com

//modified 3/2018 by Brandon McRee - removed support for LED and single digit HDSP DISPLAY

//figure out latch pin

// an array of 5 bytes per ASCII
// 5 bytes cause 5 columns
// 7 bits per column (no LSB)

const byte ascii_5x7[] = {    //when I put this in PROGMEM i get gibberish, without it the SRAM is 87% full...
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xF2, 0x00, 0x00,// !
    0x00, 0xE0, 0x00, 0xE0, 0x00,// "
    0x28, 0xFE, 0x28, 0xFE, 0x28,// #
    0x24, 0x54, 0xFE, 0x54, 0x48,// $
    0xC4, 0xC8, 0x10, 0x26, 0x46,// %
    0x6C, 0x92, 0xAA, 0x44, 0x0A,// &
    0x00, 0xA0, 0xC0, 0x00, 0x00,// 39
    0x00, 0x38, 0x44, 0x82, 0x00,// 40
    0x00, 0x82, 0x44, 0x38, 0x00,// 41
    0x28, 0x10, 0x7C, 0x10, 0x28,// *
    0x10, 0x10, 0x7C, 0x10, 0x10,
    0x00, 0x0A, 0x0C, 0x00, 0x00,
    0x10, 0x10, 0x10, 0x10, 0x10,
    0x00, 0x06, 0x06, 0x00, 0x00,
    0x04, 0x08, 0x10, 0x20, 0x40,
    0x7C, 0x8A, 0x92, 0xA2, 0x7C,//48 0
    0x00, 0x42, 0xFE, 0x02, 0x00,//49 1
    0x42, 0x86, 0x8A, 0x92, 0x62,//50 2
    0x84, 0x82, 0xA2, 0xD2, 0x8C,
    0x18, 0x28, 0x48, 0xFE, 0x08,
    0xE4, 0xA2, 0xA2, 0xA2, 0x9C,
    0x3C, 0x52, 0x92, 0x92, 0x0C,
    0x80, 0x8E, 0x90, 0xA0, 0xC0,
    0x6C, 0x92, 0x92, 0x92, 0x6C,
    0x60, 0x92, 0x92, 0x94, 0x78,
    0x00, 0x6C, 0x6C, 0x00, 0x00,
    0x00, 0x6A, 0x6C, 0x00, 0x00,
    0x10, 0x28, 0x44, 0x82, 0x00,
    0x28, 0x28, 0x28, 0x28, 0x28,
    0x00, 0x82, 0x44, 0x28, 0x10,
    0x40, 0x80, 0x8A, 0x90, 0x60,
    0x4C, 0x92, 0x9E, 0x82, 0x7C,
    0x7E, 0x88, 0x88, 0x88, 0x7E,//65 A
    0xFE, 0x92, 0x92, 0x92, 0x6C,
    0x7C, 0x82, 0x82, 0x82, 0x44,
    0xFE, 0x82, 0x82, 0x44, 0x38,
    0xFE, 0x92, 0x92, 0x92, 0x82,
    0xFE, 0x90, 0x90, 0x90, 0x80,// 70
    0x7C, 0x82, 0x92, 0x92, 0x5E,
    0xFE, 0x10, 0x10, 0x10, 0xFE,
    0x00, 0x82, 0xFE, 0x82, 0x00,
    0x04, 0x02, 0x82, 0xFC, 0x80,
    0xFE, 0x10, 0x28, 0x44, 0x82,
    0xFE, 0x02, 0x02, 0x02, 0x02,
    0xFE, 0x40, 0x30, 0x40, 0xFE,
    0xFE, 0x20, 0x10, 0x08, 0xFE,
    0x7C, 0x82, 0x82, 0x82, 0x7C,
    0xFE, 0x90, 0x90, 0x90, 0x60,// P
    0x7C, 0x82, 0x8A, 0x84, 0x7A,
    0xFE, 0x90, 0x98, 0x94, 0x62,
    0x62, 0x92, 0x92, 0x92, 0x8C,
    0x80, 0x80, 0xFE, 0x80, 0x80,
    0xFC, 0x02, 0x02, 0x02, 0xFC,
    0xF8, 0x04, 0x02, 0x04, 0xF8,
    0xFC, 0x02, 0x0C, 0x02, 0xFC,
    0xC6, 0x28, 0x10, 0x28, 0xC6,
    0xE0, 0x10, 0x0E, 0x10, 0xE0,
    0x86, 0x8A, 0x92, 0xA2, 0xC2,
    0x00, 0xFE, 0x82, 0x82, 0x00,
    0x40, 0x20, 0x10, 0x08, 0x04,
    0x00, 0x82, 0x82, 0xFE, 0x00,
    0x20, 0x40, 0x80, 0x40, 0x20,
    0x02, 0x02, 0x02, 0x02, 0x02,
    0x00, 0x80, 0x40, 0x20, 0x00,
    0x04, 0x2A, 0x2A, 0x2A, 0x1E,
    0xFE, 0x12, 0x12, 0x12, 0x0C,
    0x1C, 0x22, 0x22, 0x22, 0x22,
    0x0C, 0x12, 0x12, 0x12, 0xFE,// 100 d
    0x1C, 0x2A, 0x2A, 0x2A, 0x1A,// 101 e
    0x00, 0x10, 0x7E, 0x90, 0x40,
    0x12, 0x2A, 0x2A, 0x2A, 0x3C,
    0xFE, 0x10, 0x10, 0x10, 0x0E,
    0x00, 0x00, 0x5E, 0x00, 0x00,
    0x04, 0x02, 0x02, 0xBC, 0x00,
    0x00, 0xFE, 0x08, 0x14, 0x22,
    0x00, 0x82, 0xFE, 0x02, 0x00,
    0x3E, 0x20, 0x1C, 0x20, 0x3E,
    0x3E, 0x10, 0x20, 0x20, 0x1E,
    0x1C, 0x22, 0x22, 0x22, 0x1C,
    0x3E, 0x28, 0x28, 0x28, 0x10,
    0x10, 0x28, 0x28, 0x28, 0x3E,
    0x3E, 0x10, 0x20, 0x20, 0x10,
    0x12, 0x2A, 0x2A, 0x2A, 0x24,
    0x20, 0x20, 0xFC, 0x22, 0x24,
    0x3C, 0x02, 0x02, 0x02, 0x3C,
    0x38, 0x04, 0x02, 0x04, 0x38,
    0x3C, 0x02, 0x0C, 0x02, 0x3C,// x
    0x22, 0x14, 0x08, 0x14, 0x22,// y
    0x20, 0x12, 0x0C, 0x10, 0x20,// z
    0x22, 0x26, 0x2A, 0x32, 0x22,//123 {
    0x00, 0x10, 0x6C, 0x82, 0x82,//124 |
    0x00, 0x00, 0xEE, 0x00, 0x00,//125 }
    0x82, 0x82, 0x6C, 0x10, 0x00,
    0x20, 0x40, 0x40, 0x40, 0x80,
    0xA8, 0x68, 0x3E, 0x68, 0xA8,
    0xBE, 0x2A, 0x2A, 0x2A, 0xA2,
    0x00, 0x20, 0x50, 0xA0, 0x00,
    0x04, 0x22, 0x7C, 0xA0, 0x40,
    0x84, 0xFC, 0x04, 0x00, 0x20,
    0xFE, 0x02, 0x02, 0x12, 0x02,
    0x1C, 0x22, 0x14, 0x08, 0x36,
    0x4E, 0x3E, 0x60, 0x40, 0x40,
    0x0C, 0x12, 0x52, 0xB2, 0x1C,//136 ÃƒÆ’Ã†â€™Ãƒâ€šÃ‚Âª
    0x08, 0x1C, 0x2A, 0x2A, 0x2A,
    0xF8, 0x40, 0x40, 0x3C, 0x02,
    0x7C, 0x92, 0x92, 0x7C, 0x00,
    0x42, 0x44, 0x38, 0x04, 0x02,
    0x20, 0x3E, 0x20, 0x3E, 0x22,
    0x10, 0x20, 0x3C, 0x22, 0x20,
    0x18, 0x24, 0x7E, 0x24, 0x18,
    0x1C, 0x22, 0x0C, 0x22, 0x1C,
    0x82, 0xC6, 0xAA, 0x92, 0x82,
    0x3A, 0x46, 0x40, 0x46, 0x3A,
    0x54, 0x54, 0x54, 0x54, 0x54,
    0x44, 0x28, 0x10, 0x28, 0x44,
    0x10, 0x10, 0x54, 0x10, 0x10,
    0x00, 0x70, 0x88, 0x88, 0x70,
    0x60, 0x90, 0x8A, 0x80, 0x40,
    0xFE, 0xFE, 0x92, 0x92, 0x92,
    0x0A, 0x1A, 0x2A, 0x4A, 0x8A,
    0x8A, 0x4A, 0x2A, 0x1A, 0x0A,
    0x28, 0x2C, 0x38, 0x68, 0x28,
    0x04, 0xFE, 0x80, 0x80, 0x80,
    0x4C, 0x92, 0x92, 0x7C, 0x00,//157 ÃƒÆ’Ã†â€™Ãƒâ€¹Ã…â€œ
    0x04, 0x02, 0x7C, 0x80, 0x40,
    0x38, 0x44, 0x38, 0x44, 0x38,
    0xAA, 0x54, 0xAA, 0x54, 0xAA,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xBE, 0x00, 0x00,
    0x38, 0x44, 0xFE, 0x44, 0x00,
    0x12, 0x7E, 0x92, 0x92, 0x42,
    0xBA, 0x44, 0x44, 0x44, 0xBA,
    0xA8, 0x68, 0x3E, 0x68, 0xA8,
    0x00, 0x00, 0xEE, 0x00, 0x00,
    0x50, 0xAA, 0xAA, 0xAA, 0x14,
    0x00, 0x80, 0x00, 0x80, 0x00,
    0x7C, 0xBA, 0xAA, 0xAA, 0x7C,
    0x12, 0xAA, 0xAA, 0xAA, 0x7A,
    0x10, 0x28, 0x54, 0xAA, 0x44,
    0x80, 0x80, 0x80, 0x80, 0xC0,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x7C, 0xAA, 0xBA, 0x82, 0x7C,
    0x80, 0x80, 0x80, 0x80, 0x80,
    0x00, 0xE0, 0xA0, 0xE0, 0x00,
    0x22, 0x22, 0xFA, 0x22, 0x22,
    0x00, 0x48, 0x98, 0xA8, 0x48,
    0x00, 0x00, 0xA8, 0xA8, 0x70,
    0x00, 0x00, 0x40, 0x80, 0x00,
    0x04, 0xF8, 0x10, 0x10, 0xE0,
    0x60, 0xFE, 0x80, 0xFE, 0x80,
    0x00, 0x00, 0x10, 0x10, 0x00,
    0x08, 0x00, 0x02, 0x04, 0x00,
    0x00, 0x48, 0xF8, 0x08, 0x00,
    0x00, 0xE8, 0xA8, 0xE8, 0x00,
    0x44, 0xAA, 0x54, 0x28, 0x10,
    0xF0, 0x04, 0x0C, 0x14, 0x2E,
    0xF0, 0x00, 0x12, 0x26, 0x1A,
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
    0x0C, 0x12, 0xA2, 0x02, 0x04,
    0x1E, 0xA8, 0x68, 0x28, 0x1E,
    0x1E, 0x28, 0x68, 0xA8, 0x1E,
    0x1E, 0xA8, 0xA8, 0xA8, 0x1E,
    0x9E, 0xA8, 0xA8, 0xA8, 0x9E,
    0x9E, 0x28, 0x28, 0x28, 0x9E,
    0x1E, 0x68, 0xA8, 0x68, 0x1E,
    0x7E, 0x90, 0xFE, 0x92, 0x92,
    0x70, 0x8A, 0x8C, 0x88, 0x88,
    0x3E, 0xAA, 0x6A, 0x2A, 0x22,
    0x3E, 0x2A, 0x6A, 0xAA, 0x22,
    0x3E, 0xAA, 0xAA, 0xAA, 0x22,
    0xBE, 0x2A, 0x2A, 0x2A, 0xA2,
    0x00, 0xA2, 0x7E, 0x22, 0x00,
    0x00, 0x22, 0x7E, 0xA2, 0x00,
    0x00, 0xA2, 0xBE, 0xA2, 0x00,
    0x00, 0xA2, 0x3E, 0xA2, 0x00,
    0x10, 0xFE, 0x92, 0x82, 0x7C,
    0xBE, 0x90, 0x88, 0x84, 0xBE,
    0x1C, 0xA2, 0x62, 0x22, 0x1C,
    0x1C, 0x22, 0x62, 0xA2, 0x1C,
    0x1C, 0xA2, 0xA2, 0xA2, 0x1C,
    0x9C, 0xA2, 0xA2, 0xA2, 0x9C,
    0x9C, 0x22, 0x22, 0x22, 0x9C,
    0x44, 0x28, 0x10, 0x28, 0x44,
    0x3A, 0x4C, 0x54, 0x64, 0xB8,
    0x3C, 0x82, 0x42, 0x02, 0x3C,
    0x3C, 0x02, 0x42, 0x82, 0x3C,
    0x3C, 0x82, 0x82, 0x82, 0x3C,
    0xBC, 0x02, 0x02, 0x02, 0xBC,
    0x60, 0x10, 0x4E, 0x90, 0x60,
    0xFE, 0x44, 0x44, 0x44, 0x38,
    0x7E, 0xA4, 0xA4, 0x58, 0x00,
    0x04, 0xAA, 0x6A, 0x2A, 0x1E,
    0x04, 0x2A, 0x6A, 0xAA, 0x1E,
    0x04, 0xAA, 0xAA, 0xAA, 0x1E,
    0x84, 0xAA, 0xAA, 0xAA, 0x9E,
    0x04, 0xAA, 0x2A, 0xAA, 0x1E,
    0x04, 0x6A, 0xAA, 0x6A, 0x1E,
    0x2E, 0x2A, 0x1C, 0x2A, 0x3A,
    0x30, 0x4A, 0x4C, 0x48, 0x00,
    0x1C, 0xAA, 0x6A, 0x2A, 0x1A,
    0x1C, 0x2A, 0x6A, 0xAA, 0x1A,
    0x1C, 0xAA, 0xAA, 0xAA, 0x1A,
    0x1C, 0xAA, 0x2A, 0xAA, 0x1A,
    0x00, 0x80, 0x5E, 0x00, 0x00,
    0x00, 0x00, 0x5E, 0x80, 0x00,
    0x00, 0x40, 0x5E, 0x40, 0x00,
    0x00, 0x40, 0x1E, 0x40, 0x00,
    0x0C, 0x12, 0x52, 0xB2, 0x1C,
    0xBE, 0x90, 0xA0, 0xA0, 0x9E,
    0x0C, 0x92, 0x52, 0x12, 0x0C,
    0x0C, 0x12, 0x52, 0x92, 0x0C,
    0x0C, 0x52, 0x52, 0x52, 0x0C,
    0x4C, 0x52, 0x52, 0x52, 0x4C,
    0x0C, 0x52, 0x12, 0x52, 0x0C,
    0x10, 0x10, 0x10, 0x54, 0x10,
    0x18, 0x26, 0x3C, 0x64, 0x18,
    0x1C, 0x82, 0x42, 0x02, 0x1C,
    0x1C, 0x02, 0x42, 0x82, 0x1C,
    0x1C, 0x42, 0x42, 0x42, 0x1C,
    0x1C, 0x42, 0x02, 0x42, 0x1C,
    0x20, 0x12, 0x4C, 0x90, 0x20,
    0xFE, 0x48, 0x48, 0x30, 0x00,
    0x20, 0x92, 0x0C, 0x90, 0x20,

};

int column[] = {
    8,7,6,5,4}; // change this to other general input/output arduino-pins as you like d8=pin 1
int data = 2;   // change this to other general input/output arduino-pins as you like
int clock = 3;  // change this to other general input/output arduino-pins as you like

int brightness = 2000; // keep high for max visibility. To high will cause flikkering

const int numberOflDisplays = 4; // change this if total number of HDSP200x's is different.

int tekstDat[numberOflDisplays * 4 * 5]; // this is the array that store's what on the displays. 4 digits per display and 5 columns per digit.

unsigned long tijd; // used to trigger events in one of the examples below

char buf[40];
boolean flagRx = false; //allowed to receive if false

//*****************************************************************setup*************************************************************
void setup(){
    //Serial.begin(9600);

    for (int i = 0; i < 5; i++){
        pinMode(column[i], OUTPUT);
    }
    for (int i = 0; i < 5; i++){
        digitalWrite(column[i], LOW);
    }
    pinMode(data, OUTPUT);
    pinMode(clock, OUTPUT);
    digitalWrite(data, LOW);
    digitalWrite(clock, HIGH);
    tijd = millis();

    Wire.begin(8);                // join i2c bus with address #8  >>important<<
    Wire.onReceive(receiveEvent); // register event

}

//***********************************************************************************end setup******************************************************

void loop(){

    char PROGMEM clr[] = "    ";
    char PROGMEM scroll[]  = "1979 TECH CONTROL PANEL by Brandon McRee";
    char PROGMEM scroll2[] = "Remember Stupid... you have to drive this home :)";

    if(flagRx == false){
        delay(10); //needs this delay to be stable
        scrollText(scroll, 8); //scrolling text, speed : second number is var howslow how slow this is a test of fastdraw text (short strings)
        delay(1000);
        //scrollText(scroll2, 10);
        delay(10);
        flagRx = true; // can now recieve
    }
    else{
        writeText(buf);
        for (int i = 0; i< 50; i++) draw(); //does this continuously - display HDSP2011

    }
    /*
            scrollText(scroll3, 10);
            delay(10);

        //short quick text write
        scrollText(hello, 8);
        scrollText(world, 8);
        delay(500);

            delay(5);
        writeText("TEST") ;                   //letters only? special charachters
        for (int i = 0; i< 100; i++) draw();
                delay(5);
        writeText("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ;
        for (int i = 0; i< 70; i++) draw();
                delay(5);
        writeText("1234567890") ;
        for (int i = 0; i< 100; i++) draw();
                delay(5);
        writeText("!@#$%^&*()") ;
        for (int i = 0; i< 50; i++) draw(); //delay??
                delay(5);

        delay(1000);

            */

    writeText(buf);
    for (int i = 0; i< 50; i++) draw(); //does this continuously

}
//****************end of main loop *********************************

void receiveEvent(int howMany) {

    int i;
    for (i=0; i<howMany; i++){
        buf[i] = Wire.read(); //read I2C data (address 8)
    }

    flagRx = true;    // set flag, we received something. will figure out how to clear when

    // while (1 < Wire.available()) { // loop through all but the last

}

//int x = Wire.read();    // receive byte as an integer not used
//Serial.println(x);          // print the integer

void writeDigit(int positie, int ascii){
    for (int i =0; i< 5;i++){
        tekstDat[(numberOflDisplays * 4 - positie) * 5 + i] = ascii_5x7[ascii*5+i];
    }
}

void scrollText(String tekkst, long howSlow){
    int leng = tekkst.length();
    for (int u=-numberOflDisplays*4;u<leng;u++){ // first N digits will be spaces. N = all digits of display. So one screen blank before first character apears.
        for (int v=0; v< numberOflDisplays*4;v++){
            if (( (u+v) >= 0 ) && ((u+v) < leng)){ // separete leading and tailing spaces from actual string
                char oneChar= tekkst.charAt(u+v);
                writeDigit(v+1, oneChar); // write the character of the string
            }
            else{
                writeDigit(v+1, 32); // write ascii-value 32 = a space.
            }
        }
        for (long teller = 0; teller < howSlow; teller++){
            draw();
        }
    }
}

void writeText(String tekst){
    int tl = tekst.length();
    int spacesNeeded = 4 * numberOflDisplays - tl;
    if (spacesNeeded <0){
        tl = 4 * numberOflDisplays;
    }
    else{
        for (int u = 0; u < spacesNeeded; u++){
            tekst.concat(" ");
        }
        tl = 4 * numberOflDisplays;
    }
    char tekst_[tl];
    for (int vv = 0; vv < tl; vv++){
        char tt = tekst.charAt(tl-vv-1);
        for (int i =0; i< 5;i++){
            //tekstDat[vv*5+i] = ascii_5x7[tt*5+i]; //old using SRAM
            //tekstDat[vv*5+i] = (pgm_read_byte(ascii_5x7))[tt*5+i]; //new  try and read from PROGMEM does not compile :/
        }
    }
}

void dot(byte x, byte y, boolean oo){
    if ((x < (numberOflDisplays *4 * 5)) && (y < 7)){
        byte oldByte = tekstDat[x] & (0xFF - (2<<y));
        tekstDat[x] = oldByte | (2<<y);
    }
}

void draw(){
    for (int Kolom = 0; Kolom < 5; Kolom++){ // 5 columns to be strobed
        // pumping in 3 x 4 x 7 bits per one stobe of the column
        for (int displayNo = 0; displayNo < numberOflDisplays; displayNo++){  // number of  displays
            for (int digitNo = 0; digitNo < 4; digitNo++){ // 4 characters per display
                for (int diodeNo = 0; diodeNo < 7; diodeNo++){ // 7 row-elements
                    digitalWrite(clock, HIGH);
                    digitalWrite(data, tekstDat[Kolom + 5*(displayNo*4 + digitNo) ] &(2<<diodeNo)); // magic
                    digitalWrite(clock, LOW);
                }
            }
        }
        digitalWrite(column[Kolom], HIGH);
        delayMicroseconds(brightness);
        digitalWrite(column[Kolom], LOW);
    }
}

```

# Answer
> 1 votes
Take a look at an ASCII table such as the one here.

You could remove the first 32 ASCII characters which are the control characters and don't show up on the display. That would save 160 bytes. You will just need to make sure your index lines up.

You can then remove the last 127 characters which make up the extended character set. These are rarely used in the English language. This would save you an additional 635 bytes.

Overall that would save you 795 precious bytes.

# Answer
> 0 votes
Ran into the same issue. Added the following line to setup():

```
// The following line is magic needed for pgm_read_byte() to function.
if (millis() > 100000L) Serial.println((uint16_t) font, HEX);

```

Note the Serial.println() is never executed, but the compiler doesn't know that. Without this line pgm\_read\_byte() produces garbage. With this line added to setup() the code runs fine.

Disassembling the code it looks as if without the Serial.println((uint16\_t) font) the compiler optimizes away the begin address of the array, dropping "font" from the symbol table.

Complete sketch at https://github.com/koendv/retroleds

---
Tags: arduino-nano, flash, progmem
---


# Question
Title: Notoriously unstable ESP8266 MQTT-client
I am doing a project where an ESP8266 receives data from an Arduino Uno and publishes it via MQTT. After a random amount of time, it will stop sending data to my MQTT broker. It might be an hour, it might be a day or two.

It's set up to send data every second, and I made a debug output telling me the WiFi signal quality as well. Seems like that's not it.

I have tried making checks that will reconnect to MQTT if it looses connection, and that it resets itself if it looses WiFi connection. I'm out of ideas right now, any help appreciated!

Here's my MQTT reconnnect function

```
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("pressure/debug", "ESP8266: reconnected!");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

```

and here's where it checks for WiFi

```
void checkWifiConnection() {
  if (WiFi.status() != WL_CONNECTED)
  {
    int countdown = millis() + 15000;
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      if (countdown > millis()) {
      delay(500);
      Serial.println("Connecting to WiFi..");
      } else {
        Serial.println("Timed out! Restarting...");
        ESP.reset();
      }
  }
  }
}

```

Both are run every loop.

The arduino sends the data like it's supposed to, and I've lowered the connection speed to 19200bps in order to ensure a more stable connection, using SoftwareSerial. Any more things i could monitor? I tried it with two different ESP8266MOD/"ESP07" boards with the same result.

Here's a debug output:

```
09:13:05.039 -> unpub data 0/ AP:Akvasafe/ RSSI:-69 dB / Vcc:3519mV / free heap:49440 / fragmentation:1%

```

# Answer
I use adafruit mqtt library. After a few fixes, it is running very stable.

**Tips:**

1) Make sure you put subscribe line BEFORE connecting to mqtt (you can put it in setup and connect to mqtt in loop)

**Like:**

Setup: `mqtt.subscribe(&motor);`

Loop: `MQTT_connect();`

Yes, you can both publish and subscribe at the same time.

2) **IN THE LINE:** `Adafruit_MQTT_Client(server,port,user,pass)`

**CHANGE TO THIS:** `Adafruit_MQTT(server,port,clientid,user,pass)`

Use this with client id (MUST BE UNIQUE (EG: Different for all clients)) or your client will be kicked off when other client with same id connects.

3) **Convert value.lastread from char\* to int :** `int val = atoi((char *)sensor.lastread);`

More about ESP8266 & ESP32 : http://github.com/ajaybnl
> 1 votes

---
Tags: esp8266, mqtt
---


# Question
Title: MQTT PubSubClient connection problem with ESP32
I am experiencing some problems with string in Arduino application with ESP32. I don't understand why this code works:

`mqtt.setServer ("m20.cloudmqtt.com", port); //is OK`

and this does not work does not connect

`String strSBM = "m20.cloudmqtt.com";
mqtt.setServer (strSBM.c_str (), port); //no OK`

I use library PubSubClient 2.7

Any of you can help me

Many thanks

# Answer
When you set the server from a C string it doesn't copy the string - it just retains a pointer to it:

```
PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
    this->domain = domain;
    this->port = port;
    return *this;
}

```

If the string it's pointing to goes out of scope (it's a local variable and the function finishes) the data for the string will be invalidated and lost.

It is really intended to work with string literals and global constant variables that never change.

If this is the one and only time that you ever set the server you could get away with using `strdup()` to duplicate the string data on the heap, but without direct access to the `domain` member variable of the `PubSubClient` class you have no way to `free()` the memory again should you ever wish to change the server.

```
String strSBM = "m20.cloudmqtt.com";
mqtt.setServer (strdup(strSBM.c_str()), port);

```

To make it so you can `free` the value you need to keep track of it separately:

```
static char *temp = NULL;
if (temp != NULL) {
    free(temp);
    temp = NULL;
}
temp = strdup(strSBM.c_str());
mqtt.setServer(temp, port);

```
> 1 votes

---
Tags: esp32, mqtt
---


# Question
Title: I need help programming my arduino in assembly
I am new to using an Arduino and I am trying to program my it to implement a ﬂashing pattern with two LEDs. When one LED is oﬀ, the other must be on. The program needs to be done in assembly. I have a working program in c++ but I need to convert it to assembly. I have an Arduino UNO ATmega 328p

Here is my c++ program:

```
 const int led = 13;
 const int led2 = 12;

 void setup() {
    pinMode(led, OUTPUT);
    pinMode(led2, OUTPUT);
 }

 void loop() {
   digitalWrite(led, HIGH);
   delay(1000);
   digitalWrite(led, LOW);
   digitalWrite(led2, HIGH);
   delay(1000);
   digitalWrite(led2, LOW);
 }

```

# Answer
In the case, that this is a school assignment and you actually have to program directly in assembler, you probably don't want to directly convert your C++ sketch. It will generate way more assembler code, than is really necessary for alternatively blinking two LEDs (for example `digitalWrite()` contains not only the actual writing to the corresponding pin registers, but much more code), and it will be obvious, that you didn't write it yourself.

In this case you have to go the harder way. You should start by looking into existing assembler blink programs. Via google I found this series at github gist, which also has a blink example. You can derive some of the program from there. Also there is a list of assembler command with descriptions.

In the end everything, that is done on a microcontroller, comes down to reading and writing Special Function Registers (SFR). The pins are organized in ports with 8 (or sometimes less) pins. Every port is then represented by one byte in the corresponding SFR (1 bit per pin). For changing the direction of a pin between output and input, the DDRX registers are used (where X is the character of the port used). For actually setting the output state (or enabling/disabling the internal pullup resistor) the PORTX registers are used. The current state (LOW or HIGH; while input or output) can be read from the PINX registers. For these things, the datasheet of the microcontroller (here the Atmega328P) is a must read (meaning: not completely, but enough to feel comfortable getting needed information from it).

Learn how to set single bits in a byte (in a SFR). You can learn it from the linked example, or from tutorials over the internet. Then write code to write the correct value to the corresponding DDRX bits to set the LED pins to output. Then you can use this to write a value to an output pin.

For blinking you need a timer. If you google for something like "arduino assembler blink" you will also find an example, which configures the timer for blinking. Basically it involves setting the Timers SFRs to the wanted values. If you don't want to do this, you might get away with executing a high number of "nop" operations (which does nothing). You would have to write a loop, that will execute a high number of times. ( very "nop" will need 1 clock cycle - credits to Ghanima for searching that up). The clock runs on 16MHz, so you can do the math to calculate, how long 1 "nop" needs, and then calculate, how many of them you need).
> 2 votes

# Answer
There are also a couple of ways of including assembler code right inside your Arduino IDE.

By including the assembler in the Arduino IDE, the assembler source is assembled and linked into your project and uploaded to your Arduino from within the IDE - just like any other program.

This makes it easy to get started with Assembler while still retaining the familiarity of the Arduino IDE. Why? Because since you can mix C / C++ code with the Assembler code this means that you do not have to write a complete assembler program that manages all of the hardware initialisation nitty gritty - you can start small and expand your assembler as and when you you feel comfortable or need to do so. Like the example below, you can start with just two lines of assembler that fit into a larger program if you wanted to.

Following are the instructions for creating a mixed C / Assembler program in Arduino. I also give an example of how to pass parameters and get a result from an Assembler function.

To create a mixed C + Assembler program create a new project in the Arduino IDE (call it whatever you like) and enter the following code into the IDE:

```
extern "C" {
  void myInit();
  void myLoop();
  int myAdd(int, int);
}

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

  // This is just a dummy example showing inline assembler using the asm "directive"
  // Refer to this tutorial, or similar, for details of inline assembler in Arduino:
  // https://ucexperiment.wordpress.com/2016/03/11/arduino-inline-assembly-tutorial-5-2/
  asm(
    "ldi   r26,42"
  );
}

void loop() {
  myLoop();

  int ans = myAdd(240, 25);
  delay(ans);
  Serial.print("Answer: ");
  Serial.println(ans);
  delay(1000);
}

```

Next click the little down arrow in the top right corner of the IDE as per the following diagram and select "New Tab":

Enter `myFunctions.S` as the name of the new tab as shown below. Note that the name does not really matter, but, it **must end with the extension .S** and the "S" must be a capital "S" not a lowercase "s":

Paste the following code into the `myFunctions.S` tab.

```
; Example assembler file that blinks an LED.
; and adds two numbers together.

#define __SFR_OFFSET 0

#include "avr/io.h"

// Declare the three function entry points as "globals"
.global myInit
.global myLoop
.global myAdd

myInit:
  sbi   DDRB,5      ; Set PB5 (the built in LED on Arduino Uno) as output
  ret

myLoop:
  ldi   r20,250     ; Set the delay duration in ms. Maximum value is 255.
  call  myDelay_ms
  sbi   PORTB,5     ; Set PB5 HIGH
  ldi   r20,250     ; Delay for another 250 ms.
  call  myDelay_ms
  cbi   PORTB,5     ; Set PB5 LOW
  ret

; These symbols are for internal to this assembler file's use only.
; They are private because they are not listed as a global symbol
; Also, they do not conform to the subroutine calling conventions used
; by the Arduino IDE's compiler. i.e. they are not compatible with
; being called directly from C. However, since we are calling them from
; our own assembler, we can (almost) make up any calling convention we like.
myDelay_ms:
  ; Delay about r20*1ms. Destroys r20, r30, and r31.
  ; One millisecond is about 16000 cycles at 16MHz.
  ; The basic loop takes about 5 cycles, so we need about 16,000,000 / 5 = 3000 loops.
  ; NB: most instructions are 8 bit, so we load the 16 bit counter using
  ;     two 8 bit loads.
  ldi   r31, 3000>>8    ; high(3000)
  ldi   r30, 3000&255   ; low(3000)
delaylp:
  sbiw    r30, 1        ; Decrement our 1 ms counter (this instruction operates on a 16 bit value in R31:R30).
  brne    delaylp       ; If R30 is non zero, loop back
  subi    r20, 1        ; Otherwise we have passed 1 ms so, decrement the high order byte of our counter.
  brne    myDelay_ms    ; If this is non zero, loop back.
  ret                   ; Otherwise, we have counted down from R20 * 3,000 - so return.

; Function to add two integers and return an integer.
; For few parameter functions, the Arduino IDE uses registers built into the
; Microcontroller (i.e. the CPU) to exchange data between subroutine caller and callee.
; Return values are as follows:
;   - single Byte (e.g. char, byte) R24 only
;   - double Byte (e.g. int)        R25:R24 (R25 is the high order byte)
;   - quad Byte   (e.g. long)       R25:R24:R23:R22 (R25 is the high order byte)
; Parameters are passed in similar ways starting with R25 and working down, but exactly
; what is where will depend upon the parameter types.
; Refer to this tutorial for more details or the AVR compiler documentation from ATMEL
;   https://ucexperiment.wordpress.com/2016/04/02/arduino-inline-assembly-tutorial-12-functions/
; In our case, a is passed in R25:R24 and b is passed in R23:R22
myAdd:
  add     r24, r22      ; Add the low order bytes
  adc     r25, r23      ; Add the high order bytes PLUS any value carried from the previous addition.
  ret                   ; The result is in R25:R24 which is where it needs to be to pass back to the C code.

```

Upload it to your Uno, start the serial monitor and you should see some sum's being ouput (well one sum continuously being output). Feel free to change the values in the main loop to see different results.

I've put loads of comments and a few references into the code to get you started on the path to finding more information.

One other reference that will be useful if you are going to mess with assembler on the UNO is the ATMega-328P reference manual/datasheet (all 662 pages of it) which you can obtain from Microchip's ATmega328p reference page. There are a whole bunch more useful resources there that will likely come in handy from time to time.
> 2 votes

# Answer
It "needs" to be done in assembly as an assignment, right? Otherwise you would "want to learn" assembly.

What I suggest you do is change the C program to use port manipulation, for example:

```
 void setup() {
   DDRB |= 0b00100000;  // D13 to output mode
 }

 void loop() {
   PORTB |= 0b00100000;  // turn on D13
   delay(2000);
   PORTB &= ~0b00100000;  // turn off D13
   delay(2000);
 }

```

Now at least you are flashing D13 without using the rather complex digitalWrite and pinMode library functions. The delay is another issue I'll leave you to investigate however my page about timers might help you.

Now you can disassemble the generated code to see what the compiler generated in assembler and use that to help you learn how to do it.

For example, when I compiled the above code and turned on "verbose compiling" I found the location of the generated .elf file.

Running avr-objdump on that file (like this):

```
avr-objdump -S /tmp/build436d41bc5c0da39afe99cd9c05ac272a.tmp/sketch_aug13a.ino.elf > temp.txt

```

Gives me the following code for "loop":

```
00000094 <loop>:
  94:   2d 9a           sbi 0x05, 5 ; 5
  96:   60 ed           ldi r22, 0xD0   ; 208
  98:   77 e0           ldi r23, 0x07   ; 7
  9a:   80 e0           ldi r24, 0x00   ; 0
  9c:   90 e0           ldi r25, 0x00   ; 0
  9e:   0e 94 c5 00     call    0x18a   ; 0x18a <delay>
  a2:   2d 98           cbi 0x05, 5 ; 5
  a4:   60 ed           ldi r22, 0xD0   ; 208
  a6:   77 e0           ldi r23, 0x07   ; 7
  a8:   80 e0           ldi r24, 0x00   ; 0
  aa:   90 e0           ldi r25, 0x00   ; 0
  ac:   0c 94 c5 00     jmp 0x18a   ; 0x18a <delay>

```

What we basically see there is one "sbi" instruction to turn the LED on and one "cbi" instruction to turn it off.

As for the rest, well I don't want to do your homework for you. Have fun learning how to program in assembler!
> 1 votes

# Answer
Try this method to convert your sketch

https://sourceforge.net/projects/arduino-to-assembly-converter/
> 0 votes

---
Tags: arduino-uno, atmega328, assembly
---


# Question
Title: Setting up I2C with HTU21D, no response after beginTransmission
I'm playing with the temperature/humidity sensor HTU21D. Datasheet: https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+Sheet%7FHPC199\_6%7FA6%7Fpdf%7FEnglish%7FENG\_DS\_HPC199\_6\_A6.pdf%7FCAT-HSC0004

The sensor is properly wired and yields reasonable values if I use the library and example here: https://github.com/sparkfun/SparkFun\_HTU21D\_Breakout\_Arduino\_Library/blob/master/examples/SparkFun\_HTU21D\_Demo/SparkFun\_HTU21D\_Demo.ino

But I'm more interested in how I2C works, so I'm trying to write a small sketch from scratch to communicate with the sensor. Here is what I have right now:

```
#include <Wire.h>

#define SensorAddress 0x40
#define SoftReset 0xFE
#define TriggerTemperatureNoHold 0xF3
#define TriggerHumidityNoHold 0xF5

void setup(){

    Serial.begin(9600);
    Serial.println("HTU21D library");

    //delay(50);

    //Wire.beginTransmission(SensorAddress);
    //Wire.write(SoftReset);
    //Wire.endTransmission();

    //delay(50);
    Serial.println("init finished");

}

void loop(){

    Serial.println("entering");
    Wire.beginTransmission(0x40);
    Wire.write(0xF3);
    Wire.endTransmission();
    Serial.println("hello");

    //Hang out while measurement is taken. datasheet says 50ms, practice may call for more
    bool validResult;
    byte counter;
    for (counter = 0, validResult = 0 ; counter < 10 && !validResult ; counter++){
        delay(100);

        //Comes back in three bytes, data(MSB) / data(LSB) / Checksum
        validResult = (3 == Wire.requestFrom(0x40, 3));
        Serial.println(validResult);

    }
    Serial.println("here");
}

```

I'm in the middle of debugging the sketch. When the sketch is uploaded, I'm reading on the serial connection, and all I can see is:

```
HTU21D library
init finished
entering

```

It seems the program hangs on the first communication attempt, when I send the TriggerTemperatureNoHold command.

Could you give me a hand please? I don't understand why it's hanging there.

# Answer
> 0 votes
You forgot `Wire.begin();`. You should add it in `setup()`.

`Wire.begin();` will configure the IO pins for I2C usage. Without that the signals don't get in or out of the MCU, so I2C functions that wait for an ACK signal never see it and don't complete.

---
Tags: arduino-uno, i2c
---


# Question
Title: Merge two 8 bit arrays to one 16 bit array
I am an absolute newbie to Arduino and C++ and try to go through some tutorials to gain a minimal insight. However I stuck already at some tiny Points. What I want to do? Merge two 8 bit integer Arrays in to one 16 bit Array:

```
int summand_one[8] = {0,0,0,1,1,0,0,0};
int summand_two[8] = {1,0,0,0,0,0,0,1};

int * summand = new int[16];
std::copy(summand_one, summand_one+8, summand);
std::copy(summand_two, summand_two+8, summand+8);

```

The result should be

```
{0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1}

```

However it's not working at all. Constructor/destructor/type errors…

Any helpful idea how to do this?

# Answer
> 1 votes
It's better to avoid dynamic memory allocation on an Arduino, with only 2 KB of SRAM memory.

Note that your arrays cost 2 (bytes/int) * (8 + 8 + 16) = 64 bytes. And it seems you are only storing booleans, which could be stored in one bit. So consider another alternative (I will not work that out, since maybe memory consumption is not a problem).

However, an easy solution is to use uint8\_t.

Also, I would use a simple memcpy. Very naively it would look like:

```
uint8_t summand_one[8];
uint8_t summand_two[8];
uint8_t summand[16];

void setup()
{
}

void loop()
{
  memcpy(summand, summand_one, 8);
  memcpy(summand + 8, summand_two, 8);
}

```

Using some constants for the sizes, you get more flexible/readable and maintainable code:

```
static const uint8_t SummandOneSize = 8;
static const uint8_t SummandTwoSize = 8;

uint8_t summand_one   [SummandOneSize];
uint8_t summand_two   [SummandTwoSize];
uint8_t summand_merged[SummandOneSize + SummandTwoSize];

void setup()
{
}

void loop()
{
  memcpy(summand_merged                 , summand_one, SummandOneSize);
  memcpy(summand_merged + SummandOneSize, summand_two, SummandTwoSize);
}

```

---
Tags: programming, array
---


# Question
Title: How do you determine Lead Screw position using Absolute Encoder?
I need to control the position of a lead Screw Stepper motor using **EMS22A Absolute Encoder**? I've seen James Bruton do this in his video. can anyone help me?

James Bruton Video: https://www.youtube.com/watch?v=ngazw18f6zw

edit: What i did was to determine the "Largest Change" to count the number of cycle that has occurred. However, with fast rotation the program was not able to detect the change.

```
void loop(){

unsigned long currentMillis = millis();
pos = encoder.ReadAngle();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    pos2 = encoder.ReadAngle();
    }
int change = pos2-pos;
if (change > 200){
  cycle--;
}
if (change < -200){
  cycle++;
}
if(change > 1){
  motor.Forward();
}
if(change < -1){
  motor.Reverse();
}
if(change <= 1 && change >= -1){
  motor.Stop();
}
Serial.print(pos);
Serial.print(" ");
Serial.println(cycle);
}

```

# Answer
> 3 votes
The encoder attaches to the motor (or other) shaft and sends a 10-bit rotational position for a precision of 0.35 deg, and a claimed accuracy of +/- 0.7 degrees. It will be up to the application to keep track of number of rotations, detecting when the shaft has completed a rotation in either direction.

In a lead-screw application there will always be a little bit of backlash or "play". The leadscrew and nut cannot be perfect and must have a little bit of slop (technical term!) to keep the rotational friction low. This means that the nut will have some linear play, leaving that much uncertainty in the linear postion, even if the leadscrew angular position is perfectly known. Most applications manage this by turning the leadscrew back, to behind the target position, and then approaching the target in the forward direction. The leadscrew and nut position will have been calibrated for this direction. Of course it could be calibrated separately for each direction. The key is that the nut must be driven "behind" (for the particular direction) the target by more than the known linear play, to be sure the play will be entirely taken up during the approach to the target.

---
Tags: motor, robotics, rotary-encoder
---


# Question
Title: Remote Controlled Self-Balancing Robot - how to mix control input with IMU input?
I'm building a two-wheeled, self-balancing, remote-controlled robot. I'm familiar enough with the IMU and PID to get it working to just stand up but I need to drive it via remote control.

I've got no code written yet; trying to understand the concepts before diving in.

This much I understand: `[IMU] -> [Kalman filter] -> [PID] -> [Motors]`

Where I'm getting tripped up is where to mix the RC component into that control chain?

# Answer
> 1 votes
The PID get's a set point from you. For a standing still robot this a basically an angle of zero in respect to the gravity direction (which variable you use for the PID depends on your actal implementation, but it always be something derived from the angle to gravity direction). For driving forward, the robot must lean forward. So you set the new angle set point to let's say 2 degrees. The PID will try to hold that value by driving forward constantly, with a speed depending on the set angle.

So, via the remote control you simply change the angle setpoint.

---
Tags: robotics, remote-control, pid, imu
---


# Question
Title: Using software Serial for Adafruit Thermal library and more general cpp question
I'm working on a proof of concept for using the Adafruit\_Thermal printer library with an ATTiny85.

The ATTiny85 does not come with hardware serial capability, so I started looking into using SoftwareSerial to create the serial port necessary. I started down this path and ran into an error in the thermal library's constructor:

```
// thermal-printer.ino example file

#include "SoftwareSerial.h"
#define TX_PIN 3
#define RX_PIN 4

SoftwareSerial mySerial(RX_PIN, TX_PIN);

#include "Adafruit_Thermal.h"

Adafruit_Thermal printer(&mySerial); // Pass addr to printer constructor

```

```
// Adafruit_Thermal.h

class Adafruit_Thermal : public Print
{

public:
    // IMPORTANT: constructor syntax has changed from prior versions
    // of this library.  Please see notes in the example code!

    Adafruit_Thermal(Stream *s = &Serial, uint8_t dtr = 255);

```

> Documents/Arduino/libraries/Adafruit\_Thermal\_Printer\_Library/Adafruit\_Thermal.h:125:33: error: 'Serial' was not declared in this scope Adafruit\_Thermal(Stream \*s = &Serial, uint8\_t dtr = 255);

If I understand correctly, the verification process is failing because the compiler is looking for a global `Serial` value in the `Adafruit_Thermal.h`file that doesn't exist because the ATTiny85 does not have HardwareSerial.

But, going by the Adafruit\_Thermal class' constructor signature the reference passing of `Serial` is just a default value (right?) so I should be able to remove it and pass in my software serial reference. The `SoftwareSerial` class inherits from `Stream`, so it should still be a valid reference pass:

```
// this:
Adafruit_Thermal(Stream *s = &Serial, uint8_t dtr = 255);

// changes to this:
Adafruit_Thermal(Stream *s, uint8_t dtr = 255);

```

But when I do that, I start getting verification errors that make it look like the thermal instance wasn't constructed, like:

> undefined reference to \`Adafruit\_Thermal::begin(unsigned char)'

and

> undefined reference to \`Adafruit\_Thermal::Adafruit\_Thermal(Stream\*, unsigned char)'

Does this mean the class isn't getting constructed?

I looked at the underlying constructor definition to see if something was blowing up in there, but there doesn't seem to be anything fancy at the constructor level:

```
// Constructor
Adafruit_Thermal::Adafruit_Thermal(Stream *s, uint8_t dtr) :
  stream(s), dtrPin(dtr) {
  dtrEnabled = false;
}

```

This should still work with the software serial reference pass, right?

I'm a bit lost on how to debug this now. Any ideas?

# Update

After a reply from Majenko I pulled up the cpp file and looked at the header reference:

So this means the cpp file was still referring to the include path header file instead of the `lib` version?

I updated my cpp file to use:

```
#include "lib/Adafruit_Thermal.h"

```

and I still get undefined reference errors, so it may still be something else, but I wanted to share this additional info.

# Answer
:'( it's a bitter sweet solution.

After @majenko's last comment:

> Ah. So is there something you have to do in that IDE to say "Include the files in lib in the compilation\`?

I remembered that this issue has bitten me before. Specifically, the issue of including subfolders into a sketch.

Normally in programming languages (at least all of the ones I work in normally), you can use relative paths or namespaces to include files from subfolders, but for some reason with Arduino if you want to include files from subfolders **you have to put the files in a directory named `src`**.

And it specifically needs to be `src`. You can't use `lib` or `libs` or `source` or `whatevernameyouwant`, it needs to be src.

I can't find a spot in the arduino reference docs or the IDE's github repository that explains that you need to use `src` for the subfolder name, but you can find various mentions in the forums. E.g.

https://arduino.stackexchange.com/a/54655/35534

So yeah, the solution to my problem was three parts.

1. Adopting the `Adafruit_Thermal` library into my codebase so that I could edit the source code without worrying about those changes polluting the orginal.
2. Removing the `&Serial` reference pass in the constructor declaration of `Adafruit_Thermal.h`
3. using the `src` directory name to include things from a subfolder.

After doing this, the sketch passes verification.

But here's the bittersweet part. After getting past all of this and seeing the compiler get past the sketch verification the bombshell dropped; the sketch is too big for the attiny:

I guess it was not meant to be :'(

Well, at least I know what was causing the linker/compiler errors and I'll be able to sleep at night :P

Thanks for your help Majenko :bows:.
> 2 votes

---
Tags: softwareserial, adafruit, attiny85
---


# Question
Title: Error: "'lcd' does not name a type" using LiquidCrystal library
I'm following an online Arduino tutorial/course and trying to make a simple moving character on an LCD screen, but for some reason I get the following error: "error: 'lcd' does not name a type". I'm using the Tinkercad simulator because my PC's USB ports died recently. Here's my code:

```
#include <LiquidCrystal.h>

byte character[8] {
   B01111,
   B01111,
   B01111,
   B00110,
   B01111,
   B01111,
   B01001,

} ;

  LiquidCrystal lcd(12, 11, 2, 3, 4, 5);

  lcd.createChar(0, character); //error is on this line

const int Lbtnpin = 6;
const int Rbtnpin = 7;
int Lbtnprev = HIGH;
int Rbtnprev = HIGH;
int pos = 0;

void setup(){
  lcd.begin(16, 2);
  lcd.clear();
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
}

void loop(){
  lcd.clear();
  int Lbtnstate;
  Lbtnstate = digitalRead(6);
  int Rbtnstate;
  Rbtnstate = digitalRead(7);

  if ((Lbtnprev == HIGH) && (Lbtnstate == LOW) && (pos > 0)) {
     pos--;
  }
  if ((Rbtnprev == HIGH) && (Rbtnstate == LOW) && (pos < 16)) {
     pos++;
  }
  lcd.setCursor(pos, 1);
  lcd.write(byte(0));
  Lbtnprev = Lbtnstate;
  Rbtnprev = Rbtnstate;
}

```

# Answer
You cannot call methods outside of a function.
Move `lcd.createChar(0, character);` into `setup`.
> 1 votes

---
Tags: arduino-uno, programming, lcd, library, compilation-errors
---


# Question
Title: Use Arduino as transmitter and receiver UART
I know UART and serial communication model and data frame. But I want to ask about something else, when I searched in internet just found examples of one Arduino as (receiver) and another Arduino as (transmitter). So my question is how can I implement two Arduino and both of arduinos can communicate each other when after transferring data from one to another (example A-\>B). If the interpretation of the received data has to be forwarded to the first sender again(B-\>A).

# Answer
> 0 votes
You sure now `Serial.write()` and `Serial.read()`. That's already what you want. A hint to make it clear to you: When using the common `Serial.print()` function only the RxD line is in charge an thus only "half" of the serial interface is used. If you connect TxD of arduino A to RxD of another arduino B and RxD to TxD respectively you have full-duplex communication which is what you're asking.

---
Tags: arduino-uno, communication, uart
---


# Question
Title: Waking Arduino from sleep with an ultrasonic sensor
I have a parking guide using an ultrasonic sensor (HC-SR04), based on the instructions here. I'm trying to modify the code so that the Arduino goes to sleep after a certain period of inactivity (say, 30 seconds), and wake again when the sensor 'sees' a car drive into the garage. The code here shows how to wake it with a solar panel.

However, the way I understand it, the solar panel is able to wake the Arduino because it doesn't need external power to work (because it's a solar panel). Would it be possible to do the same with an ultrasonic sensor (HC-SR04), which does need power?

It'll be running off mains power, but I don't want it to be drawing power when it's not needed.

# Answer
In order to make the ultrasonic sensor work, the Arduino has to run some code to control it. So it won't do anything while the Arduino is asleep.

What you can do is have the Arduino sleep for some reasonable amount of time, wake up and read the sensor, and then go back to sleep. Maybe wake it up once every few seconds. Do you really need to react to a car in the lot the millisecond it pulls in?
> 3 votes

---
Tags: programming, sleep, hc-sr04
---


title: CHSV arguments with FastLED

text:
# Question
Title: CHSV arguments with FastLED
I'm trying to use CHSV with FastLED library and as I understand hue, value and saturation in the CHSV type are of type uint8\_t, or 1 byte.

My problem is with using variables:

```
CHSV led = (hue, sat, val);

```

with:

```
uint8_t hue;
uint8_t sat;
uint8_t val;

```
1. Is there a difference between uint8\_t and byte data types? what is it and how does one use it with the context of arduino and FastLED library?
2. Am I getting the syntax wrong? I get an error - convertion from 'uint8\_t' to non scalar type 'CHSV' requasted. I thought the library does that on its own, do I need to add more code? If yes, what code?

Thank you

# Answer
> Is there a difference between uint8\_t and byte data types?

There is no difference in the datatype. `byte` is defined in Arduino.h:

```
typedef uint8_t byte;

```

So, `uint8_t` and `byte` are exactly the same. The `uintX_t` types and their siblings are specifically meant for having the same size on every platform (in difference to for example `double` which is only 16 bits on Arduino Uno, but can be 32 bits on bigger chips). But `byte` will also be 8 bits on every platform, so there is really no difference.

> Am I getting the syntax wrong? I get an error - convertion from 'uint8\_t' to non scalar type 'CHSV' requasted. I thought the library does that on its own, do I need to add more code? If yes, what code?

You get the error, because you use the wrong syntax here. A `CHSV` color is not just 3 byte values, it is a class with member variables and methods. So you cannot simply assign 3 byte values directly to the object. You need to actually create the object, using the values as parameters for the constructor:

```
CHSV led = CHSV( hue, sat, val);

```

This creates a `CHSV` object, executes it's constructor, which uses the values from the parameters to set the internal values. That is the context, how this is used in the FastLED library. You can also find such lines in the examples of the library (I found such use in line 15 of the example `ColorPalette`, but there might be more). Also this is the same principle, as with the other color classes, like `CRGB`.
> 2 votes

---
Tags: led, ws2812
---


title: Have I damaged my arduino?

text:
# Question
Title: Have I damaged my arduino?
I was trying to build a finger print lock system.. While my arduino was connected with my pc, I mistakenly plugged the adapter and turned it on. I immediately switched it off. It was working fine (port 3?) Now suddenly port 3 disappeared and the only available option I have is port 1, which is not working! My window is also alerting me that it didn't recognize the device. I searched for it in device manger but no others devices option is available

# Answer
Which model of Arduino?

The design of most models has circuitry that handles getting power from both the barrel connector and the USB port, and switches between them intelligently.

Thus the answer should be "no, no problem." However, what else does your 12 adapter power? You might want to post a full circuit diagram of your project.

Also, as Juraj says, Arduino brand microcontrollers are designed to handle this situation. Knockoff models may cut corners.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: What can I do to increase the amount of LEDs I can power with a pro micro?
I am new to arduino and have a sparkfun pro micro that I'm using to power a one meter (60 pixels) APA 102 strip. I currently power it via USB and have a program that sends lighting instructions to it. I can only seem to power ~15 pixels with full range of brightness and ~30 if I keep the brightness at about half.

Anything more and the pro micro will stop recieving data and either freeze at the last color it's recieved or turn a bright red (which I assume is a visual indication of the fail because I didn't code that). At this point, the COM port will also become inaccessible until the code is either re-uploaded or in some cases, I simply disconnect the strip. This leads me to believe that the amount of power that I am demanding is too much for the board to put out.

So am I right in this assumption? and If so, what can I do to increase the amount of pixels I can power at full range?

I'll also post my code below in case there is something I can do there to increase the pixel amount:

```
#include <Adafruit_DotStar.h>
#include <SPI.h>

#define NUMPIXELS 60
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R;
int G;
int B;
int Bright;

void setup() {

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif

  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP
}

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFFFFFF;      // 'On' color (starts red)

void loop() {

  //strip.setPixelColor(head, color); // 'On' pixel at head
  //strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  getData();

  if (mode == 1)
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, G, R, B);
    }
    strip.setBrightness(Bright);
    strip.show();
  }
  else
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, 150, 200, 40);
    }
    strip.setBrightness(255);
    strip.show();
  }
}

int readLine(int readch, char * buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0)
  {
    switch(readch)
    {
      case '\r':
      {
        break;
      }
      case '\n':
      {
        rpos = pos;
        pos = 0;
        return rpos;
      }
      default:
      {
        if (pos < len-1)
        {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
      }
  }

  return 0;
}
}

void getData()
{
  char buf[80];
  bool redo = true;

  if(readLine(Serial.read(), buf, 80) > 0)
  {
    int i = 0;
    int j = 0;
    bool skip = false;
    char fin[3];
    if (skip == false)
    {
    do//                                mode
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          mode = atoi(fin);
          //Serial.print(mode);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do//                     number of colors
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          numColors = atoi(fin);
          //Serial.print(numColors);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do//
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          fadeSpeed = atoi(fin);
          //Serial.print(fadeSpeed);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          BBCC = atoi(fin);
          //Serial.print(BBCC);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          R = atoi(fin);
          //Serial.print(R);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          G = atoi(fin);
          //Serial.print(G);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          B = atoi(fin);
          //Serial.print(B);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          Bright = atoi(fin);
          //Serial.println(Bright);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }
  }
}

```

# Answer
As Majenko already mention, use a separate power supply.

* Use that power to power the LED strip(s).
* Use the MCU to control the data and clock lines.
* Connect grounds together.
> 4 votes

# Answer
Managing your power budget is a normal part of electronics projects. You can only draw about 500 mA total from the USB port, and less than that from the 5V line if your Arduino is powered from USB. If you drive your Arduino with ≈7V into the barrel connector you might be able to pull a full amp from the 5V rail, but it depends on how hot the voltage regulator gets. The higher the input voltage into the regulator, the more heat you generate for a given amount of current. On a genuine Arduino board the voltage regulator should have an overheat protection circuit, which will cause it to shut off when it gets too hot. Cheap knockoffs may just burn out.

When you start using higher current devices like motors or LED strips, it's usually a good idea to switch to a separate (regulated) power supply for those devices. Tie the ground lines together, and since you use separate power supplies for the Arduino and your other devices, they don't affect each other's supply voltages.
> 3 votes

# Answer
> So am I right in this assumption?

Yep.

> and If so, what can I do to increase the amount of pixels I can power at full range?

Simple: don't power it from the Arduino. Add a proper external power supply that is capable of providing the current you require.
> 2 votes

---
Tags: rgb-led, arduino-pro-micro, led-strip
---


title: Two Arduino boards with I2C sensors

text:
# Question
Title: Two Arduino boards with I2C sensors
I have been searching the internet about how to transfer data from multiple sensors from one Arduino to another using I2C, but no luck. All the code and tutorials online focus on multiple slaves with one sensor.

The attached Fritzing is not my project, but my project involves 22 pressure sensors and I need to log their readings in Excel using plx, so the picture is just for demonstrating the idea.

The main idea is to transfer the sensors' data from the slave to the master over I2C.

Is this doable?

# Answer
> 0 votes
There's two basic ways of doing it.

1. Send a byte from the master to the slave *first* to select which sensor you want, then request the data for the currently selected sensor, or
2. Request lots of bytes from the slave and fill them in one at a time as the requests arrive.

The first way is the slow, but "I2C" way of doing it - basically each sensor is its own register in the slave, and you select which register you want to read from.

The second way is faster, but you have to keep track internally of where you are.

A good compromise is to implement "auto increment" which does both scenarios: if you send a byte it sets the current sensor to read from. Then each read returns the current sensor and increments the sensor number internally in the slave, so the next read will get the next sensor.

That way you have a way to "reset" the sensor index that you are reading from, and it's reasonably quick to get all the sensors, since you just need to do multiple reads after a single write.

---
Tags: arduino-mega, i2c, datalogging
---


# Question
Title: Is the arduino nano 33 IOT schematic wrong?
As am i was copying the schematics of the arduino nano 33 IOT from the Official arduino schematic i noticed something was wrong in the schematic, specifically in the PRTV5V component

Here is a snip on the schematic

It would seems that the pin numbering on the PRTR5V is wrong. Here are snippits from the PRTR5V Datasheet

The sample schematic does look like the same of the arduino but if you look at it using the pin number it is different.For example on the arduino schematic pin 2 is at the middle of the two diodes, while on the datasheed pin 2 is before the diodes.

Now which one should i follow? Did arduino intentionally pin it that way ?

# Answer
It is correct. You are looking at the wrong datasheet.

This is the correct one:
> 0 votes

---
Tags: arduino-nano
---


# Question
Title: Forward kinematics of a differential drive robot
I've been braking my head over this for the past few days and can't make it work.. So, I have a small robot with a rotary encoder on each wheel and i want to track its position (in x and y) on a flat plane. I know it's called forward kinematics, but i can't seem to get it working. I found a lot of great public sheets, but i think, out of all of them, this is the best one It had the equations of how to calculate the X and Y on page 74:

> Vicc=L * (Din / (Dout–Din) + ½) (page 73) //Din is the inner wheel of the turn traveled distance, Dout is the outer wheel
>
> Xtδ=Xt+Vicc\*(sin(θt+θΔ) – sinθt)
>
> Ytδ=Yt+Vicc\*(cosθt - cos(θt+θΔ))
>
> θtδ=θt+θΔ //angle measurement

Where Xtδ and Ytδ are the position of the robot (x, y); Xt/Yt/θt is the position of the robot when the counting of the position has been started; θΔ is the angle of the robot now;

. Here's The code that I tried to write using the equations. I expected it to write my coordinates in x and y, but when i moved the wheels, it sent me big, random numbers, which are fluctuating up and down, which looks like a sine wave. What am I doing wrong? Could you guide me to the right path? My end result, that I want to reach is controlling 2 both motor speeds and knowing the robots position (doesn't need to be very precise though). Thanks in advance!

EDIT: Added code from PasteBin

```
#include <Encoder.h>

Encoder Left(3, 2);
Encoder Right(0, 1);

float R = 385; //mm
float r = 12.5; //Wheel diameter in mm
float L = 8; //Distance between the wheels in cm

double LeftDist = 0;
long LOldPos  = -999;
float LNewPos;
int Correction;

double RightDist = 0;
long ROldPos  = -999;
float RNewPos;

int angle= 0; // Robots current angle
unsigned long t;

int Xold= 0; //position at the start of the calculation
int Xnew= 0; //new, calculated position
int Ystart= 0; //position at the start of the calculation
int Ynew= 0;//new, calculated position
int OldAngle= 0; //angle at the start of the calculation
int NewAngle= 0;// new angle at the end of the calculation
int Vicc;

void setup() {
  Serial.begin(9600);
  t = millis();
}

void loop() {
  Encoders();
  if ((millis() - t) >= 100) {
    Xold= Ynew; //setting the new position to old
    Yold= Ynew; // setting the new position to old
    OldAngle= NewAngle; //Setting the new angle to old

    Vicc = (L * (LeftDist / (RightDist / LeftDist))) + 0.5;
    Xnew= Xold + (Vicc * (sin(OldAngle + Angle) - sin (OldAngle))); //Calculation of X
    Ynew= Yold+ (Vicc * (cos(OldAngle) - cos(OldAngle+ Angle))); //Calculation of Y
    NewAngle = OldAngle+ Angle;

    t = millis();
  }

  Serial.print(angle);
  Serial.print("        ");
  Serial.print(Xnew);
  Serial.print("        ");
  Serial.println(Ynew);
}

//0.9mm/1 deg
void Encoders() {
  LNewPos = Left.read();
  if (LNewPos != LOldPos) {
    LOldPos = LNewPos;
    LeftDist = ((LNewPos / 840) * (2 * r * 3.14)) / 10; //cm/ Rev
  }
  //-----------------------------------------------------
  RNewPos = Right.read();
  if (RNewPos != ROldPos) {
    ROldPos = RNewPos;
    RightDist = ((RNewPos / 840) * (2 * r * 3.14)) / 10; //cm/ Rev
  }
  angle= (abs(RightDist - LeftDist) * 0.9) - Correction; //calculate the angle the robot has turned
  if (fi >= 360) Correction += 360;
  else if (fi <= -360) Correction -= 360;
}

```

# Answer
> 1 votes
From your use of the number 360 at the end of the Encoders() function, I am thinking that you are using degrees for the angles. That won't work with sin and cos. The trig functions all expect angles in radians. To convert degrees to radians, multiply by PI/180.

---
Tags: programming, robotics, rotary-encoder
---


title: Wifi stopped connecting (Wemos D1 Mini)

text:
# Question
Title: Wifi stopped connecting (Wemos D1 Mini)
I am stumped. I have a few Wemos D1 Mini boards that were working on the local WiFi yesterday, yet today none of them will connect. More puzzling is that I can flash Tasmota on them and they all connect to the WiFi, but none with this code that was working yesterday. Any tips would be appreciated.

```
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  //Connect to WiFi network so we can reach the MQTT broker and publish messages to topics.
  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_password);

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

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

```

# Answer
> 1 votes
Fixed. My router is ancient and does not support WPA. As of ESP8266WiFi library Version 2.5.0, WPA is is the preferred mode. The solution is to get a better router, or add WiFi.enableInsecureWEP(); before calling WiFi.begin().

```
WiFi.enableInsecureWEP();
WiFi.begin(wifi_ssid, wifi_password);

```

# Answer
> 0 votes
Solved. (sort of). This is a working workaround.

I have determined that if I use ESP8266WiFi library Version 2.5.0 or later, all I get from WiFi.status() is WL\_NO\_SSID\_AVAIL.

By reverting to ESP8266WiFi library Version 2.4.2, I can get a connection with the same sketch.

(Juraj's comments pushed me in the direction of trying older library versions.)

# Answer
> 0 votes
Assuming that it's not something silly and accidental like the password or ssid being changed in your code, there are two things you may be running in to:

1. The WiFi.begin() function is technically not needed more than once. Values written with it are stored in a separate part of flash memory that is not overwritten by any sketch uploads. Since it's stored persistently, it may start connecting before your connection code is called. This causes a race condition that triggers a bug in the library that is, to my knowledge, still present, and can break the WiFi subsystem. If this has happened, the reason that the other firmware might work is if it fixes the error or somehow uses a different method. You can work around this by waiting a few seconds and then trying to connect if it's not currently connected. Try this fix: https://github.com/kentaylor/EraseEsp8266Flash to see if that's the problem. Alternatively, you can try some of the options in the first link of my next item to see if those work for this purpose.
2. Remember how I said that the functions persist data in flash? That has a limited write count, and no, that partition has no wear-leveling. After so many writes (and, since begin() is called in setup, it does so every time the device starts or wakes!) it will fail to hold the correct values. The endurance can be quite poor on some cheaper flash devices (and cheaper boards). But, if you want to keep using begin() to set up the WiFi (rather than set it once the normal way and then make sure begin() isn't called again by your code), delete the stored parameters (Does the ESP8266 somehow remember wifi access data?) and then turn off persistence (esp8266 advertising AP even when flashed with custom firmware). I also suggest running the following code fragment to turn off persistence and then **stop** turning it off (since THAT change persists too!):

if (WiFi.getPersistent()) { WiFi.persistent(false); }

This latter case is known to break Arduino projects, but NOT nodeMCU Lua ones. If the Tazmota firmware uses a different method, it could also ignore this issue but your code might experience it. To test this, try running the code on a different board (can be the same type, just so long as it's not the same one).

---
Tags: wifi
---