title: What's wrong with this code..?

text:
# Question
Title: What's wrong with this code..?
I want to make an 8\*8 led matrix. I found this code on the web:

```
    int latchPin = 12;  //Pin connected to ST_CP of 1st 74595
    int clockPin = 13;  //Pin connected to SH_CP of 1st 74595
    int dataPin = 11;   //Pin connected to DS of 1st 74595

    int latchPin2 = 6;  //Pin connected to ST_CP of 2nd 74595
    int clockPin2 = 7;  //Pin connected to SH_CP of 2nd 74595
    int dataPin2 = 5;   //Pin connected to DS of 2nd 74595

    void setup() {
      //set pins to output so you can control the shift register
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);

      pinMode(latchPin2, OUTPUT);
      pinMode(clockPin2, OUTPUT);
      pinMode(dataPin2, OUTPUT);
    }

    void loop() {
      /************** Send HIGH to first Anode pin (16th pin) and LOW to all
      other anode pins (15, 11, 3, 10, 5, 6, 13) of LED matrix *************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin, LOW);
      //Send 0 0 0 0 0 0 0 1 (1) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
      shiftOut(dataPin, clockPin, MSBFIRST, 1);
      // shift out the bits:
      digitalWrite(latchPin, HIGH);

      /**************** Send LOW to the first cathode pin (4th pin) and HIGH to all
        other cathode pins (7, 2, 8, 12, 1, 14 and 9) of LED matrix *****************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin2, LOW);
      // Send 1 1 1 1 1 1 1 0 (254) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
      shiftOut(dataPin2, clockPin2, MSBFIRST, 254);
      // shift out the bits:
      digitalWrite(latchPin2, HIGH);
    }

```

I expected this code to turn on the first LED, but when I uploaded this code nothing lights up. I checked my rows and colum connections.

Also, I want to ask if a 74hc595 can output sink current?

# Answer
I can't add comment to your question so I post as an answer even though this is not much an answer. This is just a hint to solve your problem.

8x8 led matrix and 595s are pretty *low-level* stuff, so I assume you have some knowledge about electronics and programming in general.

I think your wiring is OK but I also think you misunderstand how 595 works.

Here is the flow taken from a library (ESP32) for 64x64 RBG LED panel using bunch of 595s:

```
uint8_t data[8]; // data for one row

digitalWrite(OE_PIN, HIGH); // disable output, 595 outputs go into high impedance state

for (int i=0; i<8; i++)
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data[i]);  // dump data out

digitalWrite(LATCH_PIN, LOW);  // pulse 1 clock
delayMicroseconds(1); // note 2*
digitalWrite(LATCH_PIN, HIGH); // latch is active high

digitalWrite(OE_PIN, LOW); // Enable output

```

I think now you know how to fix your code.

Note 1: I find those names ***SER, SRCLK, RCLK*** (on TI's datasheet) are confusing. I prefer the names ***SERIAL DATA INPUT, SHIFT CLOCK, LATCH CLOCK*** (on ONSEMI MC74HC595 datasheet) or better ***DATA, CLK, LATCH, OE, RESET***.

Note 2: Check 74HC595 datasheet to see clock pulse width limit and speed limit. And if you are using UNO or MEGA (@16MHz), you are good without stretching the clock (data clock and latch clock). If you use higher speed MCU, e.g: ESP32@240MHz or STM32@72MHz, you have to consider clock stretching there and also inside shiftOut() function.

To improve your circuit, you should wire both OE of 595s to a Digital pin. You can also connect both latch pin into one digital pin. Every time you latch, botch 595 latch, and every time you enable output, both enable output.

So with your configuration, just shiftOut data normally for the 595 on the left and invert data for the 595 on the right, like this

```
#define DATA_COL_PIN 11
#define DATA_ROW_PIN 5
#define CLOCK_COL_PIN 13
#define CLOCK_ROW_PIN 7

#define OE_PIN 4 //use digital pin 4 to enable output on both 595s
#define LATCH_PIN 6 // or 12, but you must connect both latch inputs of both 595s together

uint8_t col = 0b00000001; // for the left 595
uint8_t row = 0b00000001; // for the right 595

digitalWrite(OE_PIN, HIGH);
shiftOut(DATA_COL_PIN, CLOCK_COL_PIN, MSBFIRST, col);
shiftOut(DATA_ROW_PIN, CLOCK_ROW_PIN, MSBFIRST, ~row); // ~row = 0b11111110 = invert_bits(row)
digitalWrite(LATCH_PIN, LOW);
digitalWrite(LATCH_PIN, HIGH);
digitalWrite(OE_PIN, LOW);

```

The code above is just for you to understand how it works. Normally, they would work on a buffer such as

```
uint8_t row[8]; // each byte is one row

```

And they do row scanning, turn one row ON at a time and just flip each column ON and OFF following the byte data of that row.

I stop here as this is going off-topic. You just ask what is wrong with your code right?

BTW, 595 can sink/source 35mA on each pin (70mA in total). So if you want to light up one row at a time with your setup, you should choose each current limiter carefully so that not to exceed 70mA in total.

> 70mA / 8xLED = 8.75mA for each LED (assume red LED)
>
> (5v - 1v7) / 8.75mA = 377R

It's likely the resistors should be at least 377 ohm or 470 ohm for safety.
> 3 votes

---
Tags: arduino-mega, programming, shift-register
---


title: How do I get an HTTP_POST response?

text:
# Question
Title: How do I get an HTTP_POST response?
I have a function for HTTP\_POST responses but it is never called when I post to it. I get the webpage instead.

I call on it with

```
server.on("/",HTTP_POST,response);

```

But I only get the url in response.

```
void setup() {
    pinMode(led_pin, OUTPUT);

    Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL)
    delay(2000); // To be able to connect Serial monitor after reset and before first printout
#endif
    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__));
    Serial.print(F("Ready to send IR signals at pin "));
    Serial.println(IR_SEND_PIN);

    pinMode(led_pin, OUTPUT);
    digitalWrite(led_pin, 0);
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    Serial.println("");

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

    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());

    if (MDNS.begin("esp32")) {
      Serial.println("MDNS responder started");
    }

    server.on("/", handleRoot);
    server.on("/test.svg", drawGraph);
    server.on("/",HTTP_POST,response);
    server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
    });
    server.onNotFound(handleNotFound);
    server.begin();
    Serial.println("HTTP server started");

}

void response(){
  //int khz = 38; // 38kHz carrier frequency for the NEC protocol

  if(server.hasArg("on") && (server.arg("on").length()>0)){ // TODO check that it's not longer than 31 characters
      Serial.print("Server was turned on:\t");
      Serial.println(server.arg("on"));

      ++CYCLE0;
      server.sendHeader("Location", String("/"), true); //how to do a redirect, next two lines
      server.send ( 302, "text/plain", "");
  } else if (server.hasArg("off") && (server.arg("off").length()>0)){
      Serial.print("Server was turned off:\t");
      Serial.println(server.arg("off"));

      ++CYCLE1;
      server.sendHeader("Location", String("/"), true);
      server.send ( 302, "text/plain", "");

   } else if (server.hasArg("up") && (server.arg("up").length()>0)){
      Serial.print("Server temp was turned up:\t");
      Serial.println(server.arg("up"));

      ++CYCLE2;
      server.sendHeader("Location", String("/"), true);
      server.send ( 302, "text/plain", "");

  } else if (server.hasArg("down") && (server.arg("down").length()>0)){
      Serial.print("Server temp was turned down:\t");
      Serial.println(server.arg("down"));

      ++CYCLE3;
      server.sendHeader("Location", String("/"), true);
      server.send ( 302, "text/plain", "");

  } else {
    server.send(400, "text/html", "<html><body><h1>HTTP Error 400</h1><p>Bad request. Please enter a value.</p></body></html>");
  }
}

```

How do you get an http post response back instead of a webpage?

POST response:

```
<html>

<head>
    <meta http-equiv='refresh' content='5' />
    <title>ESP32 Demo</title>
    <style>
        body {
            background-color: #cccccc;
            font-family: Arial, Helvetica, Sans-Serif;
            Color: #000088;
        }
    </style>
</head>

<body>
    <h1>Hello from ESP32!</h1>
    <p>Uptime: 00:05:32</p> <img src="/test.svg" />
    <h2>Turn air condistioner on</h2>
    <p>AC has been cycled 0 times</p>
    <form name='frm0' method='post'> <input type='text' name='on' value=8000>
        <input type='submit' value='Submit'>     </form>
        <p>Turn air conditioner off 0 times</p>
        <form name='frm1' method='post'> <input type='text' name='off' value=8000>
            <input type='submit' value='Submit'>     </form>
            <p>Turn temperature up 0 times</p>
            <form name='frm2' method='post'> <input type='text' name='up' value=8000>
                <input type='submit' value='Submit'>     </form>
                <p>Turn temperature down 0 times</p>
                <form name='frm3' method='post'> <input type='text' name='down' value=8000>
                    <input type='submit' value='Submit'>     </form>
</body>

</html>

```

Complete code

long version

# Answer
You have:

```
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
server.on("/",HTTP_POST,response);

```

The first call using `handleRoot` species no particular method, and in this case it seems any method is acceptable. You later specify `server.on("/",HTTP_POST,response);` specifically for POST requests. These are added to a request handler list in the order given. And apparently consulted in the order given.

In short, you need to specify `HTTP_GET` for `handleRoot` or just specify your `HTTP_POST` for `response` first and let `handleRoot` catch non-`HTTP_POST` requests afterwards:

```
server.on("/",HTTP_POST,response);
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);

```
> 2 votes

---
Tags: esp32, web-server, networking, web, web-service
---


# Question
Title: Access serial monitor on linux cli? Using arduino-cli?
I have an arduino uno connected via USB to a raspberry pi, the raspi is accessible via ssh only.

Just started a bit with arduino-cli ; I upload a sketch which reads my analog pins. How can I access the serial monitor to get the data??

# Answer
Programs such as `screen`, `minicom` or (my favorite) `picocom` are useful if you want bidirectional communication between the Arduino and the host computer. If you only want to *read* what the Arduino sends, that can be done with `cat`:

```
stty -F /dev/ttyACM0 raw 115200
cat /dev/ttyACM0

```
> 13 votes

# Answer
I use `minicom`.

```
$ sudo apt-get install minicom
... blah blah blah ...
$ minicom -D /dev/ttyACM0 -b 115200

```

Minicom can take a bit of getting used to. Use `CTRL-A` to initiate a command sequence. `CTRL-A X` is exit. `CTRL-A O` is configuration ("*O*ptions") where you can configure flow control and such.

Many people also use `screen` to do the same job, but I like the interface that `minicom` gives - it's more terminal-like.
> 8 votes

# Answer
I also had the problem that arduino-cli includes no serial monitor. I tried out screen, minicom and other but they are a bit difficult to get used with them. So I created a small python script which works as an serial monitor in the command line: https://github.com/PBahner/Serial-Monitor
> 1 votes

---
Tags: serial, arduino-cli
---


title: Arduino vs Old Computers

text:
# Question
Title: Arduino vs Old Computers
How does an arduino microprocessor compare to some of the older computers in RAM, and computational speed? Like how does it compare to the Intel 400 or the original IBM PC. I'm interested in both the Atmega328 and the 2560. Just how much better/worse is the arduino compared to an old computer?

# Answer
> 1 votes
Similar capability in turns of processing power if you compare back 10 -20 years.

arduino is a micrcontroller not a microprocessor.

A good example is the pdp11 minicomputer and the ti msp430 micro controllers. They share the same instruction set (approx 90%) . Both can (or could) do realtime event handling but pdp11 was more for data processing. Though pdp11 didn't have integrated peripherals

see bottom of this page http://www.cpushack.com/CPU/cpu4.html

# Answer
> 1 votes
The Arduino chip (usually Atmega328p-pu) is an AVR (Advanced Virtual RISC\*)!!! It doesn't processor but a "full functional nano computer" a Microcontroller! The characteristics of Atmega328P-PU is an 8bit CPU with 2Kb RAM\**, 1Kb ROM\*** and 32Kb Flash. The CPU's max speed is 20 MIPS @ 20 ΜHz, double of Motorola 68020 (1988) and the half of ARM7 (1994) more fast than Intel i486DX (1991). \***electrically erasable Programmable ROM \**synchronous RAM or SRAM yes! is a type of RAM \*RISC=Reduced instruction set computer https://www.microchip.com/wwwproducts/en/ATmega328P https://en.wikipedia.org/wiki/Instructions\_per\_second

---
Tags: atmega328
---


title: Incorrect DateTime value constructed

text:
# Question
Title: Incorrect DateTime value constructed
I'm working on alarm clock project using Arduino Nano (v 3.0, clone) and RTC module ZS-042 (containing DS3231 and EEPROM AT24C32).

The intention is to load the hours and minutes from EEPROM on start-up, use current date (to avoid zero-date problems) and compose DateTime object in order to utilize the TimeSpan object, making time calculations easier than using plain integer math. The issue is, the value in DateTime object seems not constructed correctly, although all the components used for its construction seem OK.

With the following code

```
/* Hardware definitions */
//RTC using I2C, pins 4,5
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;

#include <extEEPROM.h>
extEEPROM e2p(kbits_32, 1, 32, 0x57);

DateTime  alarm1Time;

void setup(){
  Wire.begin();
  rtc.begin();
  Serial.begin(115200);
  uint8_t e2pStatus = e2p.begin(extEEPROM::twiClock400kHz);      //go fast!
  DateTime t = rtc.now(); //get current time from RTC
  Serial.print("t.year: ");  Serial.print(t.year());
  Serial.print(" t.month: ");  Serial.print(t.month());
  Serial.print(" t.day: ");  Serial.println(t.day());
  alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
  Serial.print("E2P : ");
  Serial.print(e2p.read(1));
  Serial.print(":");
  Serial.println(e2p.read(2));
  char buf1[] = "YYMMDD-hh:mm:ss";
  Serial.println(alarm1Time.toString(buf1));
}

```

I get on the serial monitor the following:

```
t.year: 2021 t.month: 1 t.day: 31
E2P : 7:15
060206-06:28:16

```

The date components (year, month, date) correspond to current date. As the bytes on address 1 and 2 in EEPROM read 7 and 15, I'd expect the Alarm1Time be 2021-01-31, 07:15, which isn't. The output is constant, whatever the current date and the EEPROM stored time. Later in my code the alarm1Time parses into 6 hours and 28 minutes, in accordance with last line of the serial monitor output.

What could be (or better - where I'm) wrong? Thanks.

Libraries used:

**RTClib** (https://github.com/adafruit/RTClib)

**extEEPROM** (https://github.com/JChristensen/extEEPROM/blob/master/extEEPROM.h)

# Answer
Here:

```
alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);

```

you are repeatedly using the comma operator, which essentially means “discard all the values but the last one”. If you want to invoke the `DateTime` constructor that takes these arguments, you should call it explicitly:

```
alarm1Time = DateTime(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);

```

or, better yet, you can declare and initialize `alarm1Time` at the same time:

```
DateTime alarm1Time(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);

```
> 1 votes

---
Tags: arduino-nano, rtc
---


# Question
Title: Cant find Sdl and Sca pins in lcd display
My project is of non contact temperature sensor.I am using RG1602A lcd display and mlx90164 temperature sensor. But the problem is, there's no sdl , sca pins in my lcd display.

Is there any way, to overcome?

# Answer
You will need an I2C adapter board like this to interface your LCD 1602 via I2C.
> 1 votes

---
Tags: arduino-uno, lcd, pins
---


# Question
Title: I'm trying to upload a sketch to my arduino uno, but I get the Error-Message "avrdude: stk500_recv(): programmer is not responding"
```
    Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```
* I selected the right board (Arduino Uno)
* I selected the right port
* I selected "USBasp" as programmer
* I reset the board multiple times
* I have uploaded to the same port multiple times before without getting an Error
* I disconnected the USB-cable multiple times and used a different one
* I don't get the Error Message on a different board (also Arduino Uno)
* When I'm trying to upload with the serial Monitor open i see an orange lamp (RX lamp) blinking in the same speed the Errors are given
* When I'm trying to "Burn Bootloader" I get following Error:

```
Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp'
Error while burning bootloader.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

# Answer
> 2 votes
The problem was an Bluetooth extension I connected to the board. I removed it, uploaded the program, reconnected it, and that worked!

---
Tags: arduino-uno, uploading, upload
---


# Question
Title: Understanding ArduinoJson capacity calculation assistant
I am trying to figure out how `ArduinoJson` capacity can be calculated, therefore I came by the Assistant web application developed by the developer of the library https://arduinojson.org/v6/assistant/

Here what I do not understand is, why when I use either of the following two JSON strings, the helper shows me the same capacity? I would expect that the longer JSON values will result in a bigger capacity, but this does not seem to be the case.

```
{
  "wifi": {
    "ssid": "S",
    "password": "P",
    "hostname": "H"
  },
  "administration": {
    "username": "U",
    "password": "P"
  }
}

{
  "wifi": {
    "ssid": "SSSSSSSSSSSSSSSSSSSSSSSSSSS",
    "password": "PPPPPPPPPPPPPPPPPPPPPPPPPP",
    "hostname": "HHHHHHHHHHHHHHHHHHHHHHHHHHHH"
  },
  "administration": {
    "username": "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
    "password": "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"
  }
}

```

I am trying to calculate the capacity using the assistant using the following configuration:

*ESP8266 / **Deserialize** / char**

Could you anyone explain this to me? Apparently I understand the "reason" behind the capacity wrong?

# Answer
> 4 votes
If you look at the details of the numbers reported, you should see:

```
Data structures     112
Strings             0
Total (minimum)     112
Total (recommended) 128

```

As you see, there are exactly zero bytes allocated for the strings. This means that the library does not copy the strings, and instead references them from the character array you provide as an input.

If you instead configure the library for `Stream` input, it will have to store the strings, and the capacity is then very different for these two documents.

# Answer
> 2 votes
I found what the real problem is. In the assistant tool, when choosing `const char *` as the input type, it shows that the size of the string is 0, which is **wrong** according to the documentation of the library.

https://arduinojson.org/v6/api/json/deserializejson/

> // writable input =\> zero-copy
> DeserializationError deserializeJson(JsonDocument& doc, char\* input);
> // read-only input =\> duplication
> DeserializationError deserializeJson(JsonDocument& doc, const char\* input);

The assistant, if I see correctly, does **not** distinguish between these two cases, and thus gives the wrong capacity for this `const` case.

Accordingly, **in `const char *` it is not enough to only take the size of the structure, but also we need to consider the data stored in it.**

According to the documentation, the reason why `const char *` cannot be a zero-copy is:

> 3.9.2 Duplication is required As we saw in the previous section, in the zero-copy mode, ArduinoJson stores pointers pointing inside the input buffer. We saw that it has to replace some characters of the input with null-terminators. With a read-only input, ArduinoJson cannot do that anymore, so it needs to make copies of "hip" and "hop". Where do you think the copies would go? In the JsonDocument, of course!

### UPDATE

After reporting this bug (see the link below), it has been quickly fixed!

https://github.com/bblanchon/ArduinoJson/issues/1488

---
Tags: esp8266, json
---


# Question
Title: How to get a specific value from an unknown number of JSON representations?
I am using ArduinoJson and ESP8266HTTPClient.

Say I have a DynamicJsonDocument that has an unknown number of entries with information on different persons:

```
[
    {
        "ID": "12345",
        "name": "John Smith",
        "Address": "Street 1"
    },

    .
    .
    .

    {
        "ID": "00345",
        "name": "Paul Anderson",
        "Address": "Street 2"
    }
]

```

I would like to somehow store the values associated with the key "name" for all the different persons. For example, have something like:

```
String name1 = "";
...
String nameN = "";

.
.
.

Serial.println(name1);
...
Serial.println(nameN);

```

To print a list of all the names:

```
John Smith
Paul Anderson

```

The only information of the JSON I have beforehand is the keys each entry will have. I do not know how many entries there will be.

How can I go about this?

EDIT: Why I want to do this:

I am using the ESP as a client to get information from a server in the form of a JSON similar to what I wrote above. At the same time, I am serving a simple HTML website by doing `server.send(200, "text/html", HTML_code);` using the ESP as an AP. I was able to just cram the whole JSON into the HTML as text, but I would like to just have specific information from the JSON, as explained above.

I am aware what I am doing is far from elegant or the "correct way to do it", but I am learning all of this, so any criticism and help is more than welcome :)

# Answer
Directly from the ArduinoJson Assistant:

```
// Stream& input;

StaticJsonDocument<384> doc;
deserializeJson(doc, input);

for (JsonObject elem : doc.as<JsonArray>()) {
  const char* ID = elem["ID"]; // "12345", "13244", "00345"
  const char* name = elem["name"]; // "John Smith", "Jason Statham", "Paul Anderson"
  const char* Address = elem["Address"]; // "Street 1", "Street 2", "Street 3"
}

```

See also:
> 1 votes

---
Tags: esp8266, json
---


# Question
Title: Reverse engineering LIN bus on E-bike system
As a project I am trying to 'hack' an old E-bike. The electronic system of the bike consists of:

* A torque sensor measuring deformation of the rear.
* A 'spin' sensor measuring if the person is pedeling.
* A battery pack with BMS
* A speed controller inside the hub motor.
* A display to control speed, lights and display distance information etc.

From researching I concluded that the sensors, dislay and speed controller are communicating over LIN because they have a ATA6661 LIN transceiver and they are all connected parallel over the VS, LIN and GND wire. When I power up the speed controller on its own I can see some LIN communication on my oscilloscope:

I do not have a LIN transceiver to log the data but I attached a USB-TTL transceiver to the uart-side of the LINtransceiver. From my oscilloscope a deduced that the baud rate was 9600. I used termite to listen on my serial port and set it to hex view. This is what I got:

I'm not sure if I should change the amount of bits or parity bits.

My goal is to understand the frames that are send and to deduce which frame holds which sensordata or results in a certain activity. When I compare this to an CANbus project I was doing it was fairly easy to for example deduce which command was controlling my car's left window because with can-utils (candump) I could see every packet. I could filter unchanged packets and it colorcoded which bit(s) in each packet recently changed.

Any advice/ideas on how to do this for LINbus?

# Answer
As a starter point I would hookup your rigol ds1054z via usb to sigrok https://sigrok.org/wiki/PulseView this will enable you to log dump and analyze your lin frames . It has a frame decoder for LIN protocol. This should give you a great view of what is transiting over the lin bus and which slave PID to call . From there you may use a macchina.cc to comunicate over lin or use https://github.com/macchina/LIN with a arduino due and a lin tranceiver. Cheerz
> 2 votes

# Answer
If you are using "go swissdrive" controller (I'm looking at the picture) the bikebus protocol (bulls green mover) was used and in later, linbus (e-technology, Alber etc.) Display is master, motor and bms as slave .. Good luck :)
> 2 votes

---
Tags: serial, hardware
---


# Question
Title: Float to int conversion not working right in method using varargs
I am trying to convert a floating point number to an integer, but it seems like the conversion is not working properly.

I am using the math library to calculate the power of 10 based on the number of varargs, where the first argument is the number of arguments followed by the varargs.

```
int charsToIntValue(int argc, ...) {
  int multiplier = (int) pow(10, argc - 1);
  va_list argp;
  va_start(argp, argc);
  Serial.println(multiplier);
  ...
  va_end(argp);
}

```

For some reason, `multiplier` is always stored as 1 less than the actual result. e.g. If `charsToIntValue(4, 1, 2, 3, 4)` is executed, the multiplier is stored as 999 rather than 1000. However, when it is printed as a float, it does show 1000.00. And whenever I change it to a constant (`(int) pow(10, 3)`) it works fine, returning 1000.

I've tired storing the value of argc into a local variable but that didn't seem to change anything.

Full project is here for context: https://github.com/Pyrodron/charger-destination-board

File in question is charger-destination-board.ino; lines 32 to 51

# Answer
With some inspiration from timemage's comment, I decided in the long run to implement my own power function that takes two `int` arguments and returns an `int`. Rather than use the `pow` function in the `<math.h>` library which returns a `double` when I only need an `int`.

```
int power(int x, int y) {
  return y == 0 ? 1 : x * power(x, y - 1);
}

```

Now the program works as intended!
> 2 votes

# Answer
As explained by @chrisl in a comment, the issue is that `pow()` does not return an exact result, only an approximation. It works fine with compile-time constants because in this case it is evaluated at compile time, by the compiler, on you PC.

Simple solution: replace the cast to int with `round()`:

```
int multiplier = round(pow(10, argc - 1));

```

This works, but is awfully inefficient, as `pow()` involves the computation of both an exponential and a logarithm, both very expensive on an AVR-based Arduino. The int-only function in your own answer is certainly better. However, it is generally advised to avoid recursion on low-memory Arduinos like the Uno. Prefer an iterative algorithm if you can.

Also, the complexity of you int-only function is O(y). There is a well-known algorithm for integer powers that goes like O(log(y)):

```
int power(int x, int y)
{
    int z = 1;  // Invariant: result = x^y * z
    while (y) {
        if (y & 1) z *= x;
        y >>= 1;
        x *= x;
    }
    return z;
}

```

Maybe I am nitpicking, as your `y` cannot go beyond 5 without overflowing the result...
> 0 votes

---
Tags: arduino-uno, power, float, convert
---


title: Using Arduino as a standalone compiler

text:
# Question
Title: Using Arduino as a standalone compiler
I mostly program in C/C++ so I conviniently have a GCC compiler for all my compilations. I was wondering if there is a special compiler for Arduino that can be used just like the GCC Compiler? Because just taking a .ino sketch and passing it to the comiler with a few arguments will be a lot easier for me that all those things in the IDE, and furthermore I use Sublime Text as my text editor. And making a C program work in Sublime is as simple as providing it a path to the compiler. So I would like a portable smaller version of the Arduino Compiler that is NOT the whole IDE folder. Hope I get nice answers!! Thanks in advance.

# Answer
> 7 votes
First of all: The Arduino IDE brings its own GCC compiler. It is a version, that can compile for the AVR platform (don't know, if the standard version is capable of that).

When you activate verbose output for compilation in the preferences of your Arduino IDE, you can actually see, what calls to GCC the IDE is doing. You could use that to replicate it.

If you only want to use the sublime text editor for programming and not rebuilding the compilation environment of Arduino for fun (which I wouldn't able to help with), you might wanna have a look at the Arduino-cli. It gives you a tool to invoke important function, that normally the IDE does, via commandline (like installing cores and libraries, compiling and uploading). Thats what I'm currently using with sublime for programming in Arduino. It allows me to invoke building an uploading from sublime without having the Arduino IDE open.

If you want to go that way, here are the sublime-build files, that I use for my Arduino Nanos and ATtiny84s. Maybe you can adapt them for your needs. (Note: I omitted multiple variants, that I use to upload on different com ports, because the com port is the only thing, that changes there. Also I'm on Ubuntu, so on Windows or Mac it might look a bit different)

For the Nano:

```
{
    "cmd" : ["arduino-cli compile --fqbn arduino:avr:nano"],
    "working_dir": "$file_path",
    "shell":true,
    "file_patterns":["*.ino"],
    "variants": [
        {
            "cmd" : ["arduino-cli compile --fqbn arduino:avr:nano && arduino-cli upload -v --fqbn arduino:avr:nano:cpu=atmega328old --port /dev/ttyUSB0"],
            "working_dir": "$file_path",
            "shell":true,
            "name": "Compile & Upload ttyUSB0"
        }
    ]
}

```

For the ATtiny84:

```
{
    "cmd" : ["arduino-cli compile --fqbn ATTinyCore:avr:attinyx4:chip=84"],
    "working_dir": "$file_path",
    "shell":true,
    "file_patterns":["*.ino"],
    "variants": [
        {
            "cmd" : ["arduino-cli compile --fqbn ATTinyCore:avr:attinyx4:chip=84 && arduino-cli upload -v --fqbn ATTinyCore:avr:attinyx4:chip=84 --programmer arduinoasisp --port /dev/ttyUSB0"],
            "working_dir": "$file_path",
            "shell":true,
            "name": "ATtiny84: Compile & Upload ttyUSB0"
        }
    ]
}

```

# Answer
> 2 votes
This is not an answer that fully meets what you ask, but it is too big for a comment, and it helps you somewhat, at least using your Sublime editor.

What annoys me most in the Arduino IDE is the lack of supporting multiple files (having horizontal tabs make the number of files to see max 6 or 7, and using .h/.cpp files easily goes most beyond that number).

My preference is using Visual Studio as editor and I do. In your case you can use Sublime editor. Make sure that the .ino file doesn't change (i.e. only make a forward to your C++ classes or code in other classes). This is to prevent synchronization problems between the Arduino IDE and Visual Studio.

Simultaneously start up the Arduino IDE, and do the compilation from here. Only read the .ino file, while the other files are in the same directory (structure), and can be edited by Sublime editor.

So it doesn't use GCC, but the Arduino IDE is only used for compiling/running, and all editing work is done on your editor.

Besides that, in Visual Studio I created (at least for one project) stubs so I can run it on the PC as well as 'test' project. For this you can use your gcc compiler.

# Answer
> 0 votes
If you are working in Windows, I recommend VS2019 Community Edition (free) plus the Visual Micro extension. Gives you all the intellisense features of VS, tabbed edit windows, the works. I came to the Arduino world from Windows programming with C++ & C#, so I was already familiar with the Visual Studio line of IDE's, but I wouldn't have it any other way now.

---
Tags: programming, sketch, compile, compiler, arduino-cli
---


title: Code exceeds Uno board memory

text:
# Question
Title: Code exceeds Uno board memory
I have been stuck for a long time on a piece of Arduino code that performs an FFT on a Photoplethysmogram signal and decides signal quality after that.

```
#include <math.h>
#include "arduinoFFT.h"
#include <EEPROM.h>

//N=10 pt moving average
//For bidmc data of first 10 patients, MA = 0.4613849
double baseline=0.4613849;
float lm=1.0; //amplitude threshold
float ref_voltage=1.0; //saturation reference voltage
float cutoff=4.0;
float fs=0.02;
float zero_amp=0.015;

float pi=3.14159265;  //Universal Constants
float e=2.71828;
const int flen=61;

#define SAMPLES 128           //Must be a power of 2
#define SAMPLING_FREQUENCY 50 //Hz, must be less than 10000 due to ADC

arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(9600);
  sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop() {
  //float arr[]={0.43597,0.43206,0.42815,0.42424,0.42131,0.41838,0.4174,0.41642,0.41544,0.41447,0.41251,0.41153,0.40958,0.40762,0.40665,0.40665,0.40665,0.40762,0.4086,0.4086,0.41056,0.41153,0.41153,0.41056,0.4086,0.40665,0.40469,0.40469,0.40567,0.4086,0.41251,0.42033,0.43206,0.45259,0.4741,0.4956,0.51808,0.5347,0.55034,0.56403,0.57576,0.58456,0.59238,0.59629,0.59922,0.60117,0.60215,0.60313,0.60313,0.60117,0.59824,0.59335,0.58553,0.57771,0.57185,0.56207,0.54741,0.53372,0.52102,0.50929,0.50244,0.49756,0.4956,0.49462,0.49365,0.49365,0.49365,0.49169,0.48876,0.4868,0.48387,0.48094,0.47801,0.47507,0.47116,0.46823,0.46334,0.45846,0.45357,0.44868,0.44379,0.43891,0.435,0.43109,0.4262,0.42326,0.42033,0.41838,0.41642,0.41447,0.41447,0.41349,0.41251,0.41251,0.41251,0.41251,0.41251,0.41349,0.41544,0.4174,0.41935,0.42033,0.42131,0.42131,0.42033,0.41935,0.41642,0.41447,0.41349,0.41349,0.41642,0.42131,0.42815,0.43695,0.45064,0.46823,0.4868,0.50538,0.52395,0.54154,0.55816,0.57185,0.58162,0.58749,0.59042,0.59042,0.5914,0.59042,0.58944,0.58651,0.5826,0.57771,0.57087,0.56305,0.5523,0.54057,0.52884,0.51711,0.50733,0.49756,0.48778,0.47996,0.4741,0.47019,0.46823,0.46725,0.46628,0.46432,0.46041,0.4565};
  float arr[]={0.30303,0.29814,0.29326,0.28837,0.28446,0.28152,0.27859,0.27468,0.26979,0.26393,0.25806,0.25611,0.25904,0.27175,0.29521,0.32942,0.37341,0.42522,0.47116,0.51417,0.55914,0.6002,0.63539,0.66373,0.68622,0.70381,0.71652,0.72532,0.73118,0.73314,0.73314,0.73021,0.7263,0.72043,0.71359,0.70479,0.69501,0.68524,0.67351,0.6608,0.64614,0.6305,0.61388,0.59726,0.58065,0.56207,0.54252,0.52395,0.50538,0.48778,0.47312,0.46041,0.44868,0.43988,0.43304,0.42815,0.42522,0.42229,0.41935,0.4174,0.41544,0.41349,0.41056,0.40762,0.40469,0.40176,0.39785,0.39394,0.39003,0.38612,0.38221,0.37634,0.37146,0.36559,0.35973,0.35386,0.348,0.34213,0.33627,0.3304,0.32551,0.32258,0.31769,0.31281,0.30792,0.30303,0.29814,0.29423,0.28935,0.28446,0.27957,0.2737,0.26784,0.26393,0.261,0.26197,0.26882,0.28446,0.31183,0.34897,0.39589,0.44868,0.50147,0.55132,0.59629,0.6305,0.65591,0.67937,0.69795,0.71261,0.72434,0.73216,0.73607,0.73803,0.73803,0.73509,0.73021,0.72434,0.7175,0.70968,0.6999,0.69013,0.6784,0.66569,0.65103,0.63441,0.61681,0.59824,0.57771,0.55718,0.53959,0.52297,0.50635,0.48974,0.47507,0.46334,0.45259,0.44379,0.43695,0.43206,0.42815,0.42522,0.42229,0.42033,0.41838,0.41642,0.41447,0.41153,0.4086,0.40469,0.40078,0.39687,0.39198,0.3871,0.38221,0.3783,0.37439,0.3695,0.36364,0.35875,0.35288,0.348,0.34213,0.33724,0.33236,0.32747,0.32258,0.31769,0.31378,0.31085,0.30792,0.30401,0.3001,0.29619,0.29032,0.28446,0.27859,0.2737,0.2737,0.28055,0.29423,0.31672,0.35191,0.39785,0.45161,0.50733,0.56109,0.60899,0.65005,0.68328,0.7087,0.72727,0.74096,0.74878,0.75367,0.75562,0.7566,0.75464,0.75171,0.74585};
  //float arr[]={0.30303,0.28446,0.26979,0.25904,0.37341,0.55914,0.68622,0.73118};
  int len=sizeof(arr)/sizeof(arr[0]);

  /*for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)  //ppg data Array display
  {
    Serial.println(arr[i]);
    delay(50);
  }*/

  //SAMPLES=len;
  for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
        vReal[i] = arr[SAMPLES];
        vImag[i] = 0;

        while(micros() < (microseconds + sampling_period_us)){
        }
    }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

  /*PRINT RESULTS*/
  //Serial.println(peak);     //Print out what frequency is the most dominant.

  for(int i=0; i<(SAMPLES/2); i++)
  {
       /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
       Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 2);
       Serial.print(" ");
       Serial.println(vReal[i], 1);  //View only this line in serial plotter to visualize the bins
       delay(50);
  }

  //delay(1000);  //Repeat the process every second OR:
  //while(1);       //Run code once
  Serial.println("Hello");
  //int freq_N=61;
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }

  /*double D[3][freq_N]; //1st row for frequencies, 2nd row for magnitude, 3rd row for phase
  for(int i=0;i<freq_N;i++)
  {
    D[0][i]=-(pi/2)+i*0.1;
    double *d=fourier_tran(arr,len,D[0][i]);
    D[1][i]=*(d+0);
    D[2][i]=*(d+1);
    Serial.println(i);
    delay(300);
  }*/

  int z_crsg=zero_cross(arr,len);
  //Serial.println(z_crsg);
  //delay(1000);
  float diff_arr[len-1];   //Differenced PPG signal
  for(int i=1;i<=len-1;i++)
  {
    diff_arr[i-1]=arr[i]-arr[i-1];
  }

  int rise=rise_count(arr,len);
  int fall=fall_count(arr,len);
  float fr=(float)fall/rise;      //fall/rise count ratio
  uint16_t m=max_amplitude(arr,len);   //maximum amplitude detection
  int sc[]={0,0,0};  //sensor connectivity vector
  if(fr>1.65 && fr<2.35)
  {
    sc[0]=1;
  }
  if(m<lm)
  {
    sc[1]=1;
  }
  if(m>zero_amp)
  {
    sc[2]=1;;
  }
  int sd=sig_saturation(arr,len);
  //Serial.println(sd);
  //Serial.print(sc[0]);
  //Serial.print(sc[1]);
  //Serial.print(sc[2]);

  if(sum(sc,3)>=2)
  {
    Serial.println("Sensor well connected");
  }
  else
  {
    Serial.println("Sensor not connected properly");
  }
  delay(500);
  if(base_drift(arr,len)>=0.4612 && base_drift(arr,len)<=0.4614)
  {
    Serial.println("Motion detected");
  }
  else
  {
    Serial.println("No motion artefacts problems");
  }
  delay(500);
  if(sd==0)
  {
    Serial.println("Saturated signal");
  }
  else
  {
    Serial.println("Non-saturated signal");
  }
  delay(500);

  int d_z_crsg=zero_cross(diff_arr,len-1);

}

//Sensor connectivity detection
int fall_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]>arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int rise_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int max_amplitude(float arr[],int l)
{
  float h=arr[0];
  for(int i=1;i<l;i=i+1)
  {
    if(arr[i]>h)
    {
      h=arr[i];
    }
  }
  if(h>lm)
  {
    return 0;
  }
  return 1;

}

//Noise segment detection
int zero_cross(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if((arr[i]==0.0) && arr[i+1]!=0.0)
    {
      c=c+1;
    }
  }
  return c;
}
int local_maxima(float arr[], int l)
{
  int frame_len=15;
  int a=0;
  int frames=l/frame_len;
  int maxima[frames];
  for(int k=0;k<frames;k++)
  {
    uint16_t h=0;
    for(int i=a;i<a+frame_len;i++)
    {
      if(arr[i]>h)
      {
        h=arr[i];
      }
    }
    maxima[k]=h;
    a=a+frame_len;
  }
  for(int i=0;i<frames-1;i++)
  {
    if(maxima[i]>lm && maxima[i+1]>lm)
    {
      return 1;
    }
    if(i<=frames-4)
    {
      if(maxima[i]<lm && maxima[i+1]<lm && maxima[i+2]<lm && maxima[i+3]<lm)
      {
        return 1;
      }
    }
    if(i<=frames-3)
    {
      if(maxima[i]<lm && maxima[i+2]<lm)
      {
        return 1;
      }
    }
  }
  return 0;
}

//Saturation detection
int sig_saturation(float arr[],int l)
{
  int c=0;
  //uint16_t lev=200000;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<10 && arr[i+1]<10)
    {
      c++;
    }

    if(arr[i]>lm && arr[i+1]>lm)
    {
      c++;
    }
  }
  if(c>=20)
  {
    return 0;
  }
  return 1;
}

//motion detection module
double base_drift(float arr[],int l)
{
  int N=10; //N pt moving average
  int frame=l-N+1; //number of frames
  float s=0;
  double sum=0;
  for(int i=0;i<frame;i++)
  {
   s=0;
   for(int j=i;j<N+i;i++)
   {
      s=s+arr[j];
   }
   sum=sum+(s/N);
  }
  double avg=sum/frame;
  return avg;
}

int sum(int n[],int l)
{
  float s=0;
  for(int i=0;i<l;i++)
  {
    s=s+n[i];
  }
  return s;
}

float butterworth(float f, float fc,int n)
{
  float h;
  h=1/sqrt(1+pow((fc/f),2*n));
  return h;
}

double *fourier_tran(float arr[],int n,float omega)
{
   double Xr=0.00;
   double Xi=0.00;
   double DTFT[2];
   for(int j=0;j<n;j++)
   {
     Xr=Xr+arr[j]*cos(omega*j);
     Xi=Xi+arr[j]*sin(omega*j);
   }
   float X=sqrt(pow(Xr,2)+pow(Xi,2));  //Fourier transform magnitude
   float ph=-atan(Xi/Xr);  //Fourier transform phase

   DTFT[0]=X;
   DTFT[1]=ph;
   double *p=DTFT;
   Serial.println(*p);
   delay(100);
   Serial.println(*(p+1));
   delay(100);
   return p;
}
float *inv_fourier(float DTFT[][flen],int l,int flen,int n) //n is the length of the time array
{
  float arr[n];
  for(int i=0;i<n;i++)
  {
    float X=0.000;
    for(int j=0;j<l;j++)
    {
      X=X+DTFT[1][j]*cos(DTFT[2][j]+DTFT[0][j]*n);
    }
    arr[i]=1/(2*pi) * X;
  }
  float *p=arr;
  return p;
}

```

When I upload the code, Right after performing the FFT, the code does not display anything more, implying it ceases to execute and shows an error message - `Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint. data section exceeds available space in board`

I cannot remove either section of the code, so what do I need to change with this?

# Answer
> 2 votes
Probably you use too much SRAM memory:

`float arr[]` seems to take 4 bytes (for float) * 128 = 512 bytes.

Then you have `vReal` and \`vImage which takes 4 (double, float/doubles are the same in Arduino) * 128 * 2 (vReal/vImage) = 1024 bytes.

```
double vReal[SAMPLES];
double vImag[SAMPLES];

```

This already is 1536 bytes. The Arduino only has 2048 bytes so high likely you exceed it (including arguments passed and other globals).

`arr` seems to be a readonly array, so check into the use of F/PROGMEM to store them in Flash instead of SRAM (see StarCat's comment). This might get you well under the 2 KB Arduino Uno memory. Other possibilities are using a Mega which has 8 KB or use external SRAM memory but this decreases performance and takes more programming effort.

See also my anser at Optimizing code to use less Flash Memory and SRAM

# Answer
> 0 votes
Consider using one of the Teensy family. The latest Teensy 4.0 has an onboard FPU and lots of other goodies, and runs at 600MHz. Why drive a VW when you can jump into a Ferrari for very little money?

I've been using the Teensy 3.2/3.5 modules for years, and have found them to be very stable and easy to use.

---
Tags: arduino-uno, signal-processing
---


# Question
Title: Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using 'localhost:1.0' as the value of the DISPLAY variable
I have tried everything on this url

https://stackoverflow.com/questions/10165761/java-cant-connect-to-x11-window-server-using-localhost10-0-as-the-value-of-t

session output:

```
root@whale:/home/kermit# echo $DISPLAY
localhost:1.0
root@whale:/home/kermit# cd dev/sht30/
root@whale:/home/kermit/dev/sht30# arduino --upload sht30v1.ino --port /dev/ttyUSB0
Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using 'localhost:1.0' as the value of the DISPLAY variable.
        at java.desktop/sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at java.desktop/sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:102)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.desktop/sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:61)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:315)
        at java.desktop/java.awt.GraphicsEnvironment$LocalGE.createGE(GraphicsEnvironment.java:101)
        at java.desktop/java.awt.GraphicsEnvironment$LocalGE.<clinit>(GraphicsEnvironment.java:83)
        at java.desktop/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:129)
        at java.desktop/sun.awt.X11.XToolkit.<clinit>(XToolkit.java:231)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:315)
        at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:588)
        at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:583)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.desktop/java.awt.Toolkit.getDefaultToolkit(Toolkit.java:582)
        at processing.core.PApplet.<clinit>(Unknown Source)
        at processing.app.Preferences.save(Preferences.java:735)
        at processing.app.Preferences.init(Preferences.java:249)
        at processing.app.Base.main(Base.java:117)

```

How do you run arduino in headless mode on a raspberry pi?

# Answer
It is probably a non-existant or stale auth cookie in your .Xauthority file. This sort of thing happens when you're running your X session with one user but trying to run your X application as different user. Doing sudo or su root (or really any other user) is a common way to get in that situation. Running the IDE as root usually mean something else has already gone sideways. The typical reason for that is you're running as root instead of fixing your permissions to the Arduino serial device file.

---

That said, if you want to run headless builds and uploads of Arduino projects, what you're looking for is arduino-cli.

```
cd /path/to/directory/containing/sht30v1.ino
arduino-cli -b arduino:avr:nano compile
arduino-cli -b arduino:avr:nano upload --port /dev/ttyUSB0

```
> 2 votes

---
Tags: arduino-nano, usb, raspberrypi
---


title: Mkr1000 Wifi Configuration

text:
# Question
Title: Mkr1000 Wifi Configuration
Is there a package similar to esp8266 WifiManager that supports wifi configuration for Arduino mkr1000? I have searched everywhere and I got nothing

# Answer
I'll release a new **WiFiManager\_Generic\_Lite**, with functionality similar to **WiFiManager\_NINA\_Lite**, to provide support specifically to **MKR1000 using WiFi101**, as well as other generic boards (nRF52, SAMD, SAM-DUE, STM32, Teensy, AVR, etc.) using generic WiFi Shields (AT-command, WiFiNINA, etc.) within several days.

Please hold on,

---

---

The new library has just been released : **WiFiManager\_Generic\_Lite** in GitHub as well as Platform.io **WiFiManager\_Generic\_Lite** in PIO.

The following 2 examples are created specially for you to use and test

1. MKR1000\_WiFi101
2. MKR1000\_WiFi101\_MQTT

Please test and post your feedback here. Post issues, certainly many with this new library, on **WiFiManager\_Generic\_Lite issues**

Cheers,
> 2 votes

---
Tags: mkr1000
---


# Question
Title: Arduino analog input to iphone notification
I need some help :)

1. Is it even doable?
2. Is there anyone who wants to help me program it?

My wish: I want to receive a iphone notification when 1 arduino analog input drop from 5 to 0 volt.

Then (later) when the voltage goes back to 5V i want another message.

It needs to be over Wifi (not BT).

Is there anyone that can help me with this?

Thanks in advance

# Answer
> 1 votes
It is totally doable, but we cannot give detailed tutorials here, since this is a simple Q&A site. So I will point you to a direction, that can lead you to the solution.

When building IOT devices with Arduino (and thats exactly, what you are doing) there are 2 internet services, that are commonly used for getting information from the device to other devices (like your phone):

* Blynk
* IFTTT (means If This Then That)

Both have apps and can be used to push notifications, when your IOT device does a webrequest to the service. There are also libraries for Arduino available (at least for Blynk). There are many tutorials out there, so I suggest, that you search for yourself and try some of them.

For the hardware of your IOT device, I would suggest an ESP board, because they already have Wifi build in, for example the ESP32 gives you great IO capabilities.

---
Tags: input, arduino-uno-wifi, analog
---


# Question
Title: ESP-01 not responding to serial data while programming with esptool.py
I have a Arduino uno board, ESP-01 board and a logic level shifter (bidirectional) and to program the esp module i wired my Arduino and esp like this

> **Arduino uno(atmega328p removed)** --\> **level shifter** --\> **ESP-01**
> 5v --\> highvolt
> 3v3 --\> lowvolt
> TX --\> ch1 --\> TX
> RX --\> ch2 --\> RX
> proper ground connections

but when i click upload the RX pin lights up indicating its receiving data but esp doesn't respond to that when i reset the module while its uploading the compiler throws this

```
Serial port COM3
Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):
  File "C:\Users\TRAJU\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4/tools/upload.py", line 65, in <module>
    esptool.main(cmdline)
  File "C:/Users/TRAJU/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 2890, in main
    esp.connect(args.before)
  File "C:/Users/TRAJU/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 483, in connect
    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
_
the selected serial port _
 does not exist or your board is not connected

```

It as working fine yesterday and it stopped today :(

Please help and thanks in advance.

# Answer
I found my problem.

esptool.py uploads the firmware at 115200 baud rate, which my logic level converter couldn't handle. I found this out after writing this question. I thought of connecting RX and RX directly to the ESP module's RX and TX and it uploaded the program. Maybe I am wrong. Please, if any one know why this happened I am curios to know. Thanks in advance. ;)
> 2 votes

---
Tags: arduino-uno, esp8266
---


# Question
Title: Programming 328PB from Arduino IDE using Atmel-ICE to ICSP port
Updated question. The original question was based on using 'Upload' from the Arduino IDE, instead of 'Upload Using Programmer' under 'Sketch'. The problem in getting the Atmel-ICE to work with Arduino IDE appears now to be one of incorrect ICE drivers loaded when I installed Atmel Studio.

Arduino requires libusb-win drivers, which can be checked with Zadig. Available here: https://zadig.akeo.ie/

This problem was 99% solved (with help) by selecting  and the libusb-win32 driver using Zadig. I say 99% solved, because *my program now loads and runs!* , but I do get the red 'X' there as the WCID status.

Apologies if this amendment to the original question is not in the correct context, this is new to me. Thank You. Jaco

# Answer
> 1 votes
Hello The 328 "PB" has major issues with running external clocks...(yes I have first hand experience with this PB model)... Try switching to the internal oscillator as I can testify first hand the the external clocks on the PB don't work correctly. They tend to sell the PB a few bucks cheaper because you will only buy them once and only once when you find out how bad the external crystal clock driver is. If you look at the latest datasheet for the PB they try and talk their way out of the bad driver by explaining how you need to match capacitors with the following snippet. I call BS as the 328p never needed such precision on it Xtal1 & 2 pins to run but to be fair they PB is meant to be low power.

This Crystal Oscillator is a low power oscillator, with reduced voltage swing on the XTAL2 output. It gives the lowest power consumption, but is not capable of driving other clock inputs, and may be **more susceptible to noise in noisy environments.** The crystal should be connected as described in Clock Source Connections. When selecting crystals, load capacitance must be taken into consideration. The capacitance (Ce+Ci) needed at each TOSC pin can be calculated by using: �� + �� = 2�� − �� where: • Ce - is optional external capacitors. (= C1, C2 as shown in Figure 11-2) • Ci - is the pin capacitance in Table 11-3. • CL - is the load capacitance specified by the crystal vendor. • CS - is the total stray capacitance for one XTAL pin. Table 11-

---
Tags: atmega328, isp
---


# Question
Title: How to you initialize a reset on a sht30 digital thermometer?
I have a sht30 that will output correct temperature readings for about 5 min and then will drift off.

So I'm trying to hit the reset every few seconds to keep the readings accurate.

I am on a nano connecting d4 to the sht30 reset pin, but I don't appear to be resetting. My temp still drifts.

How do you correctly hit the reset on a sht30?

code:

```
#include <Wire.h>

// SHT31 I2C address is 0x44(68)
#define Addr 0x45

int reset_pin = 3; // reset pin is set to d4 on board.
int counter = 0; //reset counter

void setup()
{
  // Initialise I2C communication as MASTER
  Wire.begin();
  // Initialise serial communication, set baud rate = 9600
  Serial.begin(115200);
  delay(300);
}

void loop()
{
  unsigned int data[6];

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Send 16-bit command byte
  Wire.write(0x2C);
  Wire.write(0x06);
  // Stop I2C transmission
  Wire.endTransmission();
  delay(300);

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Request 6 bytes of data
  Wire.requestFrom(Addr, 6);

  // Read 6 bytes of data
  // temp msb, temp lsb, temp crc, hum msb, hum lsb, hum crc
  if (Wire.available() == 6)
  {
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
  }
  // Convert the data
  int temp = (data[0] * 256) + data[1];
  float cTemp = -45.0 + (175.0 * temp / 65535.0);
  float fTemp = (cTemp * 1.8) + 32.0;
  float humidity = (100.0 * ((data[3] * 256.0) + data[4])) / 65535.0;

  // Output data to serial monitor
  Serial.print("Temperature in Celsius :");
  Serial.print(cTemp);
  Serial.println(" C");
  Serial.print("Temperature in Fahrenheit :");
  Serial.print(fTemp);
  Serial.println(" F");
  Serial.print("Relative Humidity :");
  Serial.print(humidity);
  Serial.println(" %RH");
  delay(500);
  if(counter == 25){
    digitalWrite(reset_pin, HIGH); // sets the digital pin 13 on
    delay(1000);            // waits for a second
    digitalWrite(reset_pin, LOW);  // sets the digital pin 13 off
    delay(1000);
    counter  = 0;

  }
  counter++;
  Serial.println(counter);
}

```

# Answer
> 2 votes
You need to give a brief LOW pulse, not a long HIGH pulse:

In setup:

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

```

When you want to reset:

```
digitalWrite(pin_reset, LOW);
delay(1);
digitalWrite(pin_reset, HIGH);

```

---
Tags: arduino-nano, i2c, temperature-sensor, reset, temperature
---


# Question
Title: Storing data from Arduino without Serial print- High Sample rate
For my work, I need to acquire data at a high sample rate (\>100kSa/sec) using Arduino Portenta H7, which has 3 X 16-bit ADCs. Portenta H7 has STM32H747XI microcontroller. I don't want to use Serial.print command as I came to know that this command takes much time to execute, which makes achieving the targeted sample rate impossible. What are the other possible ways to store the data from Arduino while maintaining this high sample rate? For example, saving the data and then printing them all at once at the end of testing( 3-5 second testing period). e.g. using an SD card or through saving in Arduino internal memory? Can you suggest techniques employed for high-sample rate data acquisition from Arduino?

# Answer
The Portenta has a beast of an STM32H7 Cortex M7 and a minimum of 8M bytes of external SDRAM in addition to the 1M on-chip.

You need to capture 2channels x 2 bytes x 100K/s x 5s = 2M bytes of data, so storing it on the on-board RAM and spitting it out later seems like a viable and low-risk approach.

A slow serial link might take a few minutes to transmit 2M bytes of data, but you have various other options if that is objectionable.
> 1 votes

---
Tags: adc, arduino-portenta-h7
---


title: NRF24 and usb digispark

text:
# Question
Title: NRF24 and usb digispark
I want to connect NRf24 module with digispark and use USB capabilities at same time. currently, i use this conexion diagram:

```
               NC      PB5  1|o   |8  Vcc --- nRF24L01  VCC, pin2 --- LED --- 5V
nRF24L01  CE, pin3 --- PB3  2|    |7  PB2 --- nRF24L01  SCK, pin5
nRF24L01 CSN, pin4 --- PB4  3|    |6  PB1 --- nRF24L01 MOSI, pin6
nRF24L01 GND, pin1 --- GND  4|    |5  PB0 --- nRF24L01 MISO, pin7

```

Bu my problem is that as you see in this diagram CE and CSN are in the USB + and - pins:  I just want that my module receive data so, i think that if i power up every time CE pin and i change CSN pin to PB5 this may work but, in fact this don't I can't use 3 pin connexion because i don't have capacitor and my project is for Wednesday Thanks in advance for your help

# Answer
> 1 votes
it is possible to use digispark with NRF24 and USB keyboard without use system that need capacitors as the tree cable solution? I just want to use the digispark as RX

# Answer
> 1 votes
As per https://digistump.com/wiki/digispark/tutorials/basics:

*Pin 3 and Pin 4 (P3 and P4) are used for USB communication and programming, while you can use them in your circuit if you are not using USB communication, you may have to unplug your circuit during programming if the circuit would impede the pin states or dramatically affect the voltage levels on these pins.*

---
Tags: nrf24l01+, digispark
---


title: How to close/end a Wire.begin()?

text:
# Question
Title: How to close/end a Wire.begin()?
I have an ESP32 cam, and I attached an i2c light sensor to it. I need to read the light level at startup, then I don't need the i2c connection again. The problem is, the board uses 2 i2c connections I think (for the camera and such). So I use my custom pins for the sensor (15 and 16). It works well, I can read the light just fine, but then the camera fails because (I believe) the Wire.begin(15,16) changes the default pins and the camera gets confused.

So I would like to do something like Wire.end() to forget that I started the Wire.begin(). Any idea on how I can do that?

Here is the relevant code:

```
#define I2C_SDA 16
#define I2C_SCL 15
BH1750 lightMeter (0x23);
TwoWire I2Clightmeter= TwoWire(1);

void setup()
{
  I2Clightmeter.begin(I2C_SDA, I2C_SCL);
  lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);

  delay(1000);
  uint16_t lux = lightMeter.readLightLevel();

//rest of the code

```

# Answer
> 3 votes
There is a way of doing it that's ESP32 specific. However it means changing how you define your I2C object.

The ESP32 system is set up so that if the TwoWire instance is destructed the I2C bus is released. But you can't do that with the way you normally define the object. So instead you have to use dynamic allocation to control it:

```
TwoWire *I2Clightmeter;

void setup() {
    I2Clightmeter = new TwoWire(1);
    I2Clightmeter->begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,I2Clightmeter);
    delay(1000);
    uint16_t lux = lightMeter.readLightLevel();
    delete I2Clightmeter;
    // rest of code
}

```

Another alternative is to keep the TwoWire object in a local scope so that it gets destroyed when you leave that scope - maybe with a special function for it:

```

uint16_t getLux() {
    TwoWire I2Clightmeter(1);
    I2Clightmeter.begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);
    delay(1000);
    return lightMeter.readLightLevel();
}

void setup() {
    uint16_t lux = getLux();
    // rest of code
}

```

---
Tags: i2c, esp32
---


title: DigiSpark AT Tiny85 compile problem?

text:
# Question
Title: DigiSpark AT Tiny85 compile problem?
Friend asked me to find problem with compilation for his DigiSpark AT Tiny85 board. We are trying to compile sketch from here: https://forum.arduino.cc/index.php?topic=314773.0

But with no luck - there is something mixed in headers or configuration and I do not know what exactly.

This ISR does not compile:

**ISR(TIMER1\_OVF\_vect)** { //timer1 overflow

First there were some errors like TCCR1 = 0; not defined in this sketch, then after playing with #define \__ AVR\_ATtiny85\__, #undef \_AVR\_IOXXX\_H\_ and replacing avr/io.h with iotn85.h errors like multiple definition of \__vector\_x(?) came. Commenting out this line:
*//attachInterrupt(0,zeroCrossingInterrupt, FALLING)*
helped, but now even this one works, but ISR not.

I know there is a lot of caches and you do not see what is going on behind curtains, but I am quite lost yet...

Maybe there is also problem I have multiple installs in different dirs, but do not know how to clean old ones (1.6.5-r2) and at the end both work same way now, my latest fresh installed is 1.8.9.

Does anyone have any experiences with or some working demo sketch using both compare match and overflow ISRs ?

**Edit**
*Setup info*
*This board selected (...\AppData\Roaming\Arduino15\packages\digistump\hardware\avr\1.6.7\boards.txt):*

```
digispark-tiny.name=Digispark (Default - 16.5mhz)
digispark-tiny.upload.using=micronucleusprog
digispark-tiny.upload.protocol=usb
digispark-tiny.upload.tool=micronucleus
digispark-tiny.upload.maximum_size=6012
digispark-tiny.build.mcu=attiny85
digispark-tiny.build.f_cpu=16500000L
digispark-tiny.build.board=AVR_DIGISPARK
digispark-tiny.build.core=tiny
digispark-tiny.build.variant=digispark
digispark-tiny.upload.wait_for_upload_port = false
digispark-tiny.upload.use_1200bps_touch = false
digispark-tiny.upload.disable_flushing = false

```

And these are available:

```
(...\AppData\Roaming\Arduino15\package_digistump_index.json)
...
"boards": [
  {
    "name": "Digispark (Default - 16.5mhz)"
  },
  {
    "name": "Digispark Pro (Default 16 Mhz)"
  },
  {
    "name": "Digispark Pro (16 Mhz) (32 byte buffer)"
  },
  {
    "name": "Digispark Pro (16 Mhz) (64 byte buffer)"
  },
  {
    "name": "Digispark (16mhz - No USB)"
  },
  {
    "name": "Digispark (8mhz - No USB)"
  },
  {
    "name": "Digispark (1mhz - No USB)"
  }
],
...

```

**Edit 2**
Fresh install attempt on W10
Few more links - 2nd manual here:
https://www.electronicshub.org/getting-started-with-attiny85/

http://digistump.com/package\_digistump\_index.json
have to be translated to
https://raw.githubusercontent.com/digistump/arduino-boards-index/master/package\_digistump\_index.json

https://downloads.arduino.cc/arduino-1.8.9-windows.zip
W10
When installing shows error downloading (timeout?):
http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-mingw32.zip

Downloaded by hand to (there was empty file of this name):
...\AppData\Local\Arduino15\staging\packages\
avr-gcc-4.8.1-arduino5-i686-mingw32.zip

...\AppData\Local\Temp\arduino\_build\_139604\core\core.a(wiring.c.o): In function \`\__vector\_4':

...\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\cores\tiny/wiring.c:93: multiple definition of \`\__vector\_4'

...\AppData\Local\Temp\arduino\_build\_139604\sketch\sketch\_jun28a.ino.cpp.o:...\arduino-1.8.9\SketchBook\sketch\_jun28a/sketch\_jun28a.ino:60: first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1 Error compiling for board Digispark (Default - 16.5mhz).

...\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\cores\tiny\core\_build\_options.h (not found that file in arduino dir):

```
/*=============================================================================
  Build options for the ATtiny85 processor
=============================================================================*/

#if defined( __AVR_ATtiny25__ ) || defined( __AVR_ATtiny45__ ) || defined( __AVR_ATtiny85__ )
#define __AVR_ATtinyX5__
#endif

#if defined( __AVR_ATtinyX5__ )

/*
  For various reasons, Timer 1 is a better choice for the millis timer on the
  '85 processor.
*/
#define TIMER_TO_USE_FOR_MILLIS                   1

```

# Answer
> 1 votes
The problem is the following:

The digispark core already implements the `TIMER1_OVF_vect` ISR (Timer1 Overflow Interrupt). Since you have a `1` for the `#define TIMER_TO_USE_FOR_MILLIS`, Timer1 will be used for counting the `millis()` value in the background. For this the Timer 1 Overflow interrupt is needed.

The code, that you copied from that site, does not anticipate, that you might use a core, that already implements the interrupts. It is written for a generic ATtiny85, not specifically for the Digispark version.

**What you can do to solve the problem:**

* You can use Timer0 for your code, keeping the Digispark core untouched. You can change all registers from Timer1 to Timer0 (by replacing the `1` with a `0`). Additionally you need to replace `TCCR1` with `TCCR0B`, because for Timer0 that's the register, that set's the prescaler (and turns the timer off if zero is written to it). Also you need to consider, that Timer0 has other prescaler settings. So the line `TCCR1 = B00001011;` in `zeroCrossingInterrupt()` must be changed to `TCCR0B = B00000101;`. That will set the prescaler to 1024 as mentioned in the comment. The resulting code compiles fine for me with the digispark core (though I have not tested it's functionality).
* You can set the Digispark core to use Timer0 for `millis()`, by changing the definition of `TIMER_TO_USE_FOR_MILLIS` in the Attiny85 section of the file `arduino_folder/packages/digistump/hardware/avr/1.6.7/cores/tiny/core_build_options.h` to the value `0` instead of `1`. If you do this, the original sketch compiles fine. Though the comment before that build options states, that Timer1 is better for `millis()` "for various reasons", which is not very specific. You can try, if it works good for you.
* You can use another Attiny core. Though you might have to change it too, to accomodate for the unusual clock frequency fo 16.5MHz (most cores I have seen have 16, 8 and 1MHz). That might be as easy as changing the value of the defined clock speed in the cores files, but I'm not sure about that.

# Answer
> 1 votes
Another simple option - rewrite or remove the ISR in wiring.c: ...\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\cores\tiny\wiring.c

For example after changing like this was able to compile without problems.

Simplest solution would be to put that code to my ISR too or call one from another.

```
#ifdef nothing
// bluebie changed isr to noblock so it wouldn't mess up USB libraries
ISR(MILLISTIMER_OVF_vect, ISR_NOBLOCK)
{
  // copy these to local variables so they can be stored in registers
  // (volatile variables must be read from memory on every access)
  unsigned long m = millis_timer_millis;
  unsigned char f = millis_timer_fract;

/* rmv: The code below generates considerably less code (emtpy Sketch is 326 versus 304)...

  m += MILLIS_INC;
  f += FRACT_INC;
  if (f >= FRACT_MAX) {
    f -= FRACT_MAX;
    m += 1;
  }
...rmv */

  f += FRACT_INC;

  if (f >= FRACT_MAX)
  {
    f -= FRACT_MAX;
    m = m + MILLIS_INC + 1;
  }
  else
  {
    m += MILLIS_INC;
  }

  millis_timer_fract = f;
  millis_timer_millis = m;
  millis_timer_overflow_count++;
}
#endif

```

If you rename wiring.c and restart editor, you get **main.cpp:5: undefined reference to \`init'** error, there is that "crappy" heart of arduino:

```
#include <WProgram.h>

int main(void)
{
    init();

    setup();

    for (;;)
        loop();

    return 0;
}

```

WProgram.h starts with:

```
#ifndef WProgram_h
#define WProgram_h

#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <avr/interrupt.h>

#include "core_build_options.h"
#include "core_pins.h"
#include "wiring.h"
...

```

And init of that ATtiny85 (inside **wiring.c**) evn looks like this:

```
void init(void)
{
  // clock calibration stuff
  // recalibrate clock if it was calibrated by bootloader (like micronucleus)
  #if F_CPU != 16500000L
    if (OSCCAL != read_factory_calibration()) {
      // adjust the calibration down from 16.5mhz to 16.0mhz
      if (OSCCAL >= 128) {
        // maybe 8 is better? oh well - only about 0.3% out anyway
        OSCCAL -= 7;
      } else {
        OSCCAL -= 5;
      }
    }
  #endif

  // TODO: detect if fuses set to PLL, regular internal oscillator or external and change behaviour in this next section...
  #if F_CPU < 16000000L
    cli();
    CLKPR = 0b10000000;
    #if F_CPU == 8000000L
      CLKPR = 1; // div 2
    #elif F_CPU == 4000000L
      CLKPR = 2 // div 4
    #elif F_CPU == 2000000L
      CLKPR = 3; // div 8
    #elif F_CPU == 1000000L
      CLKPR = 4; // div 16
    #elif F_CPU == 500000L
      CLKPR = 5; // div 32 = 500khz
    #elif F_CPU == 250000L
      CLKPR = 6; // div 64 = 250khz
    #elif F_CPU == 125000L
      CLKPR = 7; // div 128 = 125khz cpu clock
    #else
      #warning "Cannot prescale chip to specified F_CPU speed"
    #endif
  #endif

  // this needs to be called before setup() or some functions won't work there
  sei();

  // In case the bootloader left our millis timer in a bad way
  #if defined( HAVE_BOOTLOADER ) && HAVE_BOOTLOADER
    MillisTimer_SetToPowerup();
  #endif

  // Use the Millis Timer for fast PWM
  MillisTimer_SetWaveformGenerationMode( MillisTimer_(Fast_PWM_FF) );

  // Millis timer is always processor clock divided by MillisTimer_Prescale_Value (64)
  MillisTimer_ClockSelect( MillisTimer_Prescale_Index );

  // Enable the overlow interrupt (this is the basic system tic-toc for millis)
  MillisTimer_EnableOverflowInterrupt();

  // Initialize the timer used for Tone
  #if defined( INITIALIZE_SECONDARY_TIMERS ) && INITIALIZE_SECONDARY_TIMERS
    initToneTimerInternal();
  #endif

  // Initialize the ADC
  #if defined( INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER ) && INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER
    ADC_PrescalerSelect( ADC_ARDUINO_PRESCALER );
    ADC_Enable();
  #endif
}

```

# Answer
> 1 votes
I had similar problem. I removed functions loop() and setup() and I used classic C construction with main() function and it started to work. (I think loop() and setup() enables using of other functions like delay() - and it uses timer - only my hypothesis).

---
Tags: compilation-errors, attiny85, avr-gcc
---


# Question
Title: How to control MKR1000 from outside your local network
I want to send an HTTP command to MKR1000 from outside my local network.

So far, all the googled resources point to getting the local IP (example 192.168.0.10) of MKR1000 and sending a command like `http://192.168.0.10/H` to it and then parse it.

How do I send a command to MKR1000 from outside its local network?

I should clarify that I want this to be a consumer product and can't have the end-user fiddling with their routers for port forwarding etc.

# Answer
The only way I can think of to achieve this would be to port forward your router, and forward port 80 (http) to your MKR1000. You can check out https://portforward.com/ for instructions on that.

If you don't want to port-forward, you'd have to have the MKR1000 connect to a centralized IOT server somewhere, and have the user go through the server to access the MKR1000. That's how other iot devices such as nest cameras do it.
> 3 votes

# Answer
You **now** can try this **UPnP\_Generic library** to do the auto-portforwarding for you without manually touching the router.

---

---

Many of us are **manually port-forwarding** in Internet Gateway Device (IGD, Router) in order to provide access to local Web Services from the Internet.

This library provides the easier way to automatically port-forward by using the **Simple Service Discovery Protocol (SSDP)**, running on nRF52, SAMD21/SAMD51, STM32F/L/H/G/WB/MP1, Teensy, ESP8266/ESP32, using ESP WiFi, WiFiNINA, Ethernet W5x00, ESP8266/ESP32 AT-command WiFi supporting **UDP Multicast**.

The SSDP provides a mechanism whereby network clients, with little or no static configuration, can discover network services. SSDP accomplishes this by providing for multicast discovery support as well as server based notification and discovery routing.

The **SSDP** is used for **advertisement and discovery of network services and presence information**. It accomplishes the task without assistance of server-based configuration mechanisms, such as Dynamic Host Configuration Protocol (DHCP) or Domain Name System (DNS), and without special static configuration of a network host. SSDP is the basis of the discovery protocol of **Universal Plug and Play (UPnP)** and is intended for use in residential or small office environments.

This **UPnP\_Generic library** is created to automatically **update your IGDs with the requested port-forward information**, using one of the many available boards / shields. See **Currently Supported Boards**.

The time between checks to update the UPnP Port Mappings is **configurable** to match your use case, and is set in the examples at 10 minutes. The LEASE\_DURATION is also configurable and default to 10hrs (36000s). The Virtual Server Name can also be specified in the sketch and is shown in the IGD, e.g. `NRF52-W5X00` or `ESP8266-WIFI` as in the following picture:

The UPnP\_Generic code is very short, can be immersed in your Projects and to be called in the loop() code.
> 2 votes

---
Tags: http, mkr1000
---


# Question
Title: Switch on the piezo emitter for a short time
I need a short beep for every minute of change. I wrote a separate function. The signal duration should be 50 ms, the rest of the time the emitter connected to the A1 contact should be silent.

A really working sketch is shown below:

```
uint32_t mysound; // Variable for storing time (duration of the sound signal)
uint32_t myTimer1;
uint32_t t; //Time that always increases
byte seconds; // Seconds
byte minutes; // Minutes
int k = 1;
void setup()
{
  DDRC = B00000010; // Set pin A1 as output
  //      76543210
  Serial.begin(9600);
  myTimer1 = millis();
}

void loop()
{
  t = (millis() - myTimer1) / 1000; // Time in seconds
  seconds = t % 60; // when 60 seconds are reached, it is reset to zero
  minutes = t / 60 % 60; // Counts the minutes and drops to zero when 60 minutes are reached
  Serial.println(seconds);
  if (seconds == 0 && k)
  {
    sound();
  }
  if (seconds > 0) k = 1;
}

void sound()
{
  mysound = millis();
  while (millis() - mysound < 50)
  {
    PORTC = B00000010; // We set high voltage on pin A1 for a time of 50 ms
  }
  k = 0;
  PORTC = B00000000;
}

```

# Answer
> 4 votes
Your `myTimer1` in `t = (millis() - myTimer1) / 1000;` is not set

# Answer
> 3 votes
In addition to Qareke's answer, you also have a problem with the `mysound` variable. You only set this timestamp to `millis()` inside your `millis()` if statement. `mysound` is global and thus will be implicitly initialized with zero. So, by the time, that the code reaches the if statement, the difference between `millis()` and `mysound` is most likely already too big, thus the timestamp gets never set.

**Solution:** You need to move 2 lines around in your code:

* Move the `mysound = millis();` statement up into the `if (seconds == 0)` statement.
* Move the `sound();` statement outside of the if statement directly into the `void loop()` function (for example directly after the `if (seconds == 0)` statement).

Now the `sound()` function will always be executed, but it will only do a sound, if the timestamp was set to `millis()` previously, and then only for 50ms. Now we only need to make sure, that the timestamp variable `mysound` will only be set once, when the seconds get zero. You could either introduce a new flag variable for that, or you could just use the timestamp itself and check, if more than 1s passed since the last time the timestamp was set. So you need to change

```
if (seconds == 0)

```

to

```
if (seconds == 0 && millis() - mysound > 1100)

```

I used `1100` (1.1s) here, to make sure, that there is no bad edge case happening. Since `seconds` will only get zero every minute, that shouldn't be a problem.

---
Tags: pins, timers, millis, sound
---


# Question
Title: Firmata: strings sent from the computer become damaged after Arduino
I have a Python program that acts as a `Firmata` client. This program connects to the Arduino at a user-specified COM-port (with `Firmata` onboard, the sketch can be seen below), sends the user-requested string message to the Arduino, and awaits Arduino's reply. If the reply is present, the program prints it out as a list of ASCII symbol codes.

I expect the program and the sketch to work this way (block scheme is below), but the strings coming from the Arduino are damaged. They don't contain all symbols which were sent, but they contain only the first symbols in some random order, with a `\0` symbol present after each character in the string. For example,

| String sent to the Arduino | Received as ASCII symbol codes | Received as a string |
| --- | --- | --- |
| `A` | `(65, 0)` | `A\0` |
| `AB` | `(65, 0)` *where is the `B`?* | `A\0` |
| `ABC` | `(65, 0, 67, 0)` *the `B` lacks presence* | `A\0C\0` |
| `ABCD` | `(65, 0, 67, 0)` *the received data length remains the same, but `B` and `D` aren't present* | `A\0C\0` |
| `ABCD(10)` | `(65, 0, 67, 0, 40, 1, 48, 1)` *WHAT IS THIS?* | `A\0C\0(\10\1` |
| `DHTt(4)` | `(68, 0, 84, 0, 40, 0, 41, 1)` | `D\0T\0(\0)\1` |

Program's screenshot:

Awaited work algorithm block scheme:

Python program code:

```
import pyfirmata, time

class CustomArduino(pyfirmata.Arduino):
    def __init__(self, port: str):
        pyfirmata.Arduino.__init__(self, port)
        self.iterator = pyfirmata.util.Iterator(self)
        self.iterator.start()

        self.add_cmd_handler(0x71, self.receiveString)

    def receiveString(self, *args, **kwargs):
        print(f'Received: {args}')

    def sendString(self, data):
        self.send_sysex(0x71, bytearray(data, 'utf-8'))

    def send_sysex(self, sysex_cmd, data=[]):
        """
        Sends a SysEx msg.
        :arg sysex_cmd: A sysex command byte
        : arg data: a bytearray of 7-bit bytes of arbitrary data
        """
        msg = bytearray([pyfirmata.pyfirmata.START_SYSEX, sysex_cmd])
        msg.extend(data)
        msg.append(pyfirmata.pyfirmata.END_SYSEX)
        self.sp.write(msg)

print('STRING TESTER\nPlease input your COM port: ', end = '')
myCom = str(input())
device = CustomArduino(myCom)

while True:
    device.sendString(input('Send: '))
    time.sleep(1)

```

Arduino sketch:

```
#include <Firmata.h>

void stringCallback(char *myString)
{
  //The function accepts one charset.
  Firmata.sendString(myString); //send the *same* charset  back
}

void sysexCallback(byte command, byte argc, byte *argv)
{
  Firmata.sendSysex(command, argc, argv);
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback); //when there is a STRING incoming to the Arduino, call 'stringCallback'
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
  pinMode(13, OUTPUT);
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }
}

```

How I can deal with this?

# Answer
Instead of using the `UTF-8` encoding,

```
def receiveString(self, *args, **kwargs):
    print(f'Received: {args}')

def sendString(self, data):
    self.send_sysex(0x71, bytearray(data, 'utf-8'))

```

it is necessary to use the `pyfirmata` special bytearray manipulation methods: `two_byte_iter_to_str` and  `str_to_two_byte_iter`:

```
def receiveString(self, *args, **kwargs):
    print(f'Received: {pyfirmata.util.two_byte_iter_to_str(args)}')

def sendString(self, data):
    self.send_sysex(0x71, pyfirmata.util.str_to_two_byte_iter(data))

```
> 1 votes

# Answer
You have to understand the Firmata protocol to write your own client library. The spec is here: https://github.com/firmata/protocol.

In this particular case, you need to know that data that is sent (the string in this case) can never use bit 7 of the data, since these values have special meanings. Therefore, Firmata sends every byte as two bytes, first bits 0-6 and second bit 7 as bit 0 of the next byte. Therefore, the conversion to UTF-8 is not sufficient. You need to do a two-byte-per-8-bits encoding. The same applies for the reply.
> 3 votes

# Answer
Alternatively, if you want a system without Firmata's baggage of ancient MIDI constraints, like its bizarre 7-bit limit, you might consider DaqPort https://www.daqarta.com/dw\_rraa.htm
> 1 votes

---
Tags: firmata
---


title: Blink only one led in a led strip

text:
# Question
Title: Blink only one led in a led strip
I wish to blink only one led (number two in the strip) bit it does not do so, any idea why and how can I do it?

Code:

```
#include "FastLED.h"

//Number of LEDs
#define NUM_LEDS 9

//Define our clock and data lines
#define DATA_PIN 11
#define CLOCK_PIN 13

//Create the LED array
CRGB leds[NUM_LEDS];

void setup() {
      FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);
      FastLED.setBrightness(5);
}

void loop() {
  leds[0] = CRGB::Blue;
  leds[1] = CRGB::Green;

  //Blink this one only
  leds[2] = CRGB::Red;
  leds[2] = CRGB::Black;
  delay(500);
  leds[2] = CRGB::Red;

  leds[3] = CRGB::White;
  leds[4] = CRGB::Purple;
  leds[5] = CRGB::Green;
  leds[6] = CRGB::Blue;
  leds[7] = CRGB::Yellow;
  leds[8] = CRGB::Red;
  FastLED.show();
}

```

# Answer
> 2 votes
Everytime, that you want the LEDs to change, you need to call the `FastLED.show()` function. You are doing that only once after you set the values multiple times. Also you need 2 delays in total (1 for the LED being on, 1 for it being off).

The workflow for blinking an LED would be:

```
Set LED to on
Call show function
Delay
Set LED to off
Call show function
Delay

```

You need to translate that to code.

---
Tags: rgb-led
---


# Question
Title: Part of Board exploded when Peltier Plate was wired t(o Board
Photos and Screenshots: https://i.stack.imgur.com/NazA6.jpg

By the way, I used a screenshot that was originally from this post: Have I bricked my Arduino Uno? Problems with uploading to board

Hey guys,

I was trying to wire two TEC1-12706 Peltier plates to my breadboard, and I saw that using the USB connection for power was not enough for both plates. So, I found a 19v--3.9A DC/AC adapter/computer charger and plugged it in to my Uno via the Power Jack port. The Peltier plates were not wired to the board when I plugged it in and everything looked fine, all the normal LEDs on the UNO lit up, etc. Then, I wired a peltier plate to my breadboard. As soon as I did, a part exploded, and grey smoke come out of the "L" light area. I unplugged it immediately. The next day, I plugged the adapter back into the Power Jack port and a screenshot is attached of some observations I made by touching the board. Photos of my Uno are also attached. As you can see, the "Slightly less hot but still burning part" is pretty much destroyed. The "L" light will not light up and as of right now I can't upload any code to it. Might be an unrelated issue so I will continue troubleshooting that, but it is still another observation. The test LED I wired is lit up, so I guess the board can still kinda function? I'm high school student and obviously a complete beginner. Will continue to do research on this. I really want to know what happened. Please help? Thanks everyone.

# Answer
> 2 votes
You did a pretty good job of nuking your board. Gratz.

Basically what has happened: you connected 19V to the input of the 5V regulator (rated at 800mA max) and connected a 12V 50W device to the output.

I have no idea what a peltier will do when under powered, but at 12V it's going to want about 4A. That's 20x more than the 5V regulator can provide (also exacerbated by the massive amount of heat needed to be dissipated to drop 14V) - so it went *pop*.

In going pop it short circuited. That meant that 19V (or just short of) ended up going into the rest of your Arduino. The 3.3V regulator didn't like that (the bit that looks toasted), and neither will any of the rest of the components on the board.

In short: probably almost every component on the board has been nuked.

The moral of this story: don't connect high powered 12V devices direct to the Arduino. Things like peltier devices need their own dedicated power supply which can be controlled (as you would a motor or relay) through a power MOSFET.

---
Tags: arduino-uno, peltier
---


title: Asymmetric encryption on a Teensy?

text:
# Question
Title: Asymmetric encryption on a Teensy?
I want to monitor an input and then send the information in an encrypted way that can't be easily unlocked even if a malicious actor gets access to the device itself. I'm new to using the Teensy although I have done a few simple things with Arduino microcontrollers. I was hoping to find out if anyone has implemented RSA or other asymmetrical encryption on a Teensy or to figure out if it has enough processing power to make it feasible. I would also accept using other Arduinos (I have an MKR1000 as well), for this but I assume because the Teensy has much better performance it's more likely to be able to do computationally expensive encryption.

This won't need to decrypt anything, it will only be sending data encrypted using the public key of the receiving user.

# Answer
Teensy4.1 has 55 digital IO (serial) pins at up to 200MHz. The USB port supports 480mbps, and ethernet is 10/100mbps. You're limited to 32 DMA channels, though (complicated but these are used to access onboard peripherals/memory). You don't have much contiguous ram, either.

Now, you haven't explained what you're doing with this data. This matters because even though the CPU is running at 600MHz, asymmetric encryption is slow. Are you trying to perform real-time encrypted communication? Are you just sending or receiving data as well?

Nothing stopping you from asymmetrically encrypting on a Teensy. You can find the source code for the OpenSSL functions RSA\_public\_encrypt and RSA\_private\_decrypt. This question goes into calculating how many CPU cycles are needed to encrypt X bytes of data.

However, asymmetric encryption has problems: Like I said, it's slow - specifically RSA, and the size of the data you can encrypt depends on the size of your key and padding.

If you want to communicate in something resembling real-time, you want to use hybrid encryption. You should read about how TLS works; the short version is that an asymmetric handshake occurs where the two parties agree on a symmetric key. Once you decide what your data actually is, you can quantize it (eg. TLS 'chunks' are up to 16KB which are then sent as multiple TCP packets) then both parties use the symmetric key to send/receive - which can encrypt large data chunks without issue.
> 1 votes

---
Tags: serial, programming, teensy, mkr1000, performance
---


# Question
Title: Efficient workflow/tools for converting color images to hex arrays
I would like to display 65k color animated gifs on my oled. I'm using the adafruit library for https://learn.adafruit.com/096-mini-color-oled Now I need to convert a significant number of images to hex arrays. I found a couple of tools that can deal with monochrome images and I found this: https://www.digole.com/tools/PicturetoC\_Hex\_converter.php which might work for individual images, but is impractical for batch processing. I also found this, but it appears to also be intended for individual images and doesn't simply work in wine. So isn't there some linux commandline magic to do that?

# Answer
I found this plugin to be satisfactory: https://khalim19.github.io/gimp-plugin-export-layers/ It's not a single elegant command, but is quite fast and maybe can be optimized with some scripting.
> -1 votes

---
Tags: programming, c, display, linux, oled
---


# Question
Title: Can I run 3 motion sensors with a voltage regulator?
I want to power 3 hc-sr501 PIR motion sensors with a voltage regulator that can output 5v-1A. If I make such a system, will there be a noise?

# Answer
Many internet sources like this one claim the HC-SR501 requires less than 50uA (or 0.00005 Amps). Likely this is only in a quiet or quiescent state and current demand may increase initially when power is applied and when motion is detected. Regardless, this is an insignificant fraction of a 2 Amp power supply.

Likely the Atmel 328p will require several times the total current of the 3 PIR sensors added together. Still, the over all current of the described project (1 processor and 3 PIRs) is expected to be far less than half the capacity of a 2 Amp power supply.

It is suggested to keep the PIR to Arduino wires as short as possible to avoid noise. It would be preferable they only be several inches (10s of centimeters). And certainly not as long as several feet (a meter).
> 1 votes

---
Tags: arduino-uno, sensors, power, current, voltage
---


title: Reading I2C registers as slave device

text:
# Question
Title: Reading I2C registers as slave device
I need to read the registers of a message gotten from `onReceive()`. I read here that

> There's nothing "magic" about the register pointer: it's simply the first data byte in the packet. So just write your I2C slave code so it examines the first received byte and treats it as an "opcode" for deciding how to interpret the rest of the packet.

So I thought that since hosts set registers by calling `write()` twice, I could just make my `onReceive()` handler function twice, like this

```
byte CURRENT_REGISTER = 0x00;

void onMessage(int numBytes){
  if(CURRENT_REGISTER == 0x00 && numBytes == 1){
    CURRENT_REGISTER = Wire.read();
    return;
  }

  char msg[numBytes];
  for(int i = 0; i < numBytes; i++){
    msg[i] = Wire.read();
  }

  //logic function goes here

  CURRENT_REGISTER = 0x00;
}

```

But then i noticed here that

> This first byte written here 'r' moves the register pointer to the register with address 'r'. You can think of the pointer as a read/write head.
> Now that the pointer is 'pointing' at the specific register you wanted, this command will **replace the byte stored in that register** with the value 'v'.

which made me think after `endTransmission()`, it only sent one message, which would ruin this idea. Is this the case, and if so how can I obtain the registers as a slave?

# Answer
I just realized, what your actual question might be, so I'm prepending this to my answer:

With I2C and the typical register communication protocol, you have 3 communication patters:

* Master wants to write:
    + Master does transmission with first byte being the address of the register and following bytes being the data, that should be written to the addressed register (and following registers)
* Master wants to read:
    + Master does a 1 byte transmission with the address of the register, that is wants to read
    + Master starts a request for 1 or more bytes and the slave will send the previously requested register (and following registers, until no more bytes are available or requested)
* Some devices have sequential reads. For these devices the register address is not reset, when an operation is done. Thus the master could do more requests and read more data from the registers. Here the current register address is incremented on each read.

This means, that a master write cycle has only 1 transmission (only 1 `endTransmission()` in the master code), since every first byte in a master send transmission is handled as a register address. Your code snippet does not allow that. To solve that, just remove the check of `numBytes` and the return statement.

---

As mentioned in the comments, your question is really unclear. It seems you are asking things, that doesn't really make sense in the context of general I2C communication. So I will go over the basics and then point you in a good direction to solve your problem interfacing the Wiimote as peripheral.

**The I2C protocol:** This is the general communication protocol, that the Wiimote uses for its peripherals. It uses 2 lines and a master-slave structure. That means, that any communication is controlled by the master (the Wiimote in this case) and the slave (the peripheral, like a Motion+, a Nunchuk or your Arduino) cannot do anything by itself. The I2C protocol has markers for the start and end of a message and can address each slave on the bus with its specific address (which is send before the data). The protocol does **NOT** include any rules about the content of each message. So when writing code with the `Wire` library (the Arduinos library for interfacing the I2C hardware), you only get a buffer full of data bytes. It is up to you to interpret these bytes as needed for your application.

**Data structure protocol:** This protocol is imposed onto the data, that is end via I2C, so this is a higher level of abstraction and does not really have much to do with the I2C interface (you could use this data structure protocol with any binary communication interface, that has the concept of separated data packages). The data structure protocol defines the logic of the communication.

Here the registers come in. I2C is often used to interface simple sensor chips. These chips work by reading and writing to their internal memory. So the I2C interface exposes this internal memory to the master, who can now configure the sensor by writing data to the internal memory of the sensor, or read data from it.

An example: Lets imagine a simple distance sensor. It has 2 bytes/registers of internal memory. The first byte/register is for configuration of the sensor; the second byte/register represents the measured distance. The common communication protocol for such a chip can be:

```
Master sends the address of the register, that it wants to access
if Master wants to write to the register
    Master sends bytes to the slave
    Slave saves bytes into previously chosen register (and following registers)
if masters wants to read form the register
    Master requests X bytes from the slave
    Slave sends X bytes with the content of the previously chosen register (and following registers)

```

The I2C master now wants to configure the sensor (for example setting the measurement frequency), thus writing a corresponding byte to the first byte/register. It will first send the address of the configuration register to the slave, which is 0 (first byte/register). Then it will send another byte, which is the new value of the configuration register.

Then our I2C master wants to read the distance measurement the sensor. For this it first sends the address of the register, that holds the distance measurement (1 aka second byte/register). Then it will request 1 byte from the slave. The slave will then send the content of the previously chosen register (register 1 aka distance measurement register).

So for the slave, the first byte of a Master send transmission is to be handled as a register address. More complex slave classes might have a 16bit (2byte) register address or even more.

---

Now to your problem mimicking a Wii Motion+. The description on the site, that you linked to is rather difficult. Unfortunately I cannot help much with that. But you can try to use an already existing library, that mimics a Wiimote peripheral: Arduino-Wiimote

I cannot guarantee, that is will work, but it is definitely a good start. If you don't want to use a library, but implement this yourself, you can still learn from how the library does it.

With more searching (for term combinations like "github wiimote arduino") you might find more libraries for this. I have only invested a limited amount of time.
> 1 votes

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