message:
esp32 http client response only 200 didn't receive the data after that

i am using esp32 as a client and using following example. So here i am getting header response only that is 200. I am not getting any response after that. here is the example

```
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourPassword";

void setup() {

  Serial.begin(115200);
  delay(4000);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");

}

void loop() {

  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    HTTPClient http;

    http.begin("http://jsonplaceholder.typicode.com/comments?id=10"); //Specify the URL
    int httpCode = http.GET();                                        //Make the request

    if (httpCode > 0) { //Check for the returning code

        String payload = http.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }

    else {
      Serial.println("Error on HTTP request");
    }

    http.end(); //Free the resources
  }

  delay(10000);

}
```
given url works with me as well. but if i give other url then i am getting response as 200 only. but not receiving json data which is present on the request url.

body:
A 200 response doesn't guarantee that your `payload` will actually contain any data. It depends on the server. The server might determine to respond with a 200 code but still not return any JSON code for your request.

I am not at all sure, but the server may be rejecting your request because it doesn't like your user agent. I have seen my own ESP8266 supply ESP8266HTTPClient as its user agent for HTTP requests. You can see from the [source code](https://github.com/esp8266/Arduino/blob/52f4cc8de06671a44a27886f4df84777731cb4a6/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp) of the HttpClient class that this is the default:
```
HTTPClient::HTTPClient()
    : _client(nullptr), _userAgent(F("ESP8266HTTPClient"))
{
// etc...
}
```
You might consider setting the user agent for your http client object:
```
http.setUserAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0");
```

If you'd like to investigate a bit more, you might use curl from the command line (this works on linux) to emulate the http request being formulated by your ESP device:
```
curl -vA "ESP8266HTTPClient" http://jsonplaceholder.typicode.com/comments?id=10
```

On my linux machine, this returns all the HTTP header information, followed by some JSON for the url you've specified in your code:
```
[
  {
    "postId": 2,
    "id": 10,
    "name": "eaque et deleniti atque tenetur ut quo ut",
    "email": "REDACTED@EXAMPLE.COM",
    "body": "voluptate iusto quis nobis reprehenderit ipsum amet nulla\nquia quas dolores velit et non\naut quia necessitatibus\nnostrum quaerat nulla et accusamus nisi facilis"
  }
]
```

Maybe try that with the other url and see what comes out?

You might also modify your post with the Serial output of your sketch to provide more detail.


sender: user

message:
Arduino Joystick Library not Recognized by Games (Steam)

I have an Arduino Pro Micro running code that uses the Arduino joystick library to act as a gamepad.  I'm just doing testing right now so there's a single button wired up and configured in the code.

Windows recognizes the gamepad just fine and I can read button presses in the properties dialog for that controller.  However the gamepad doesn't work in games that work with a usb gamepad normally (I testing using Rocket League).

I would like to get my Arduino to act just like a normal gamepad (i.e. an xbox controller).

There is lots of discussion on the internet about making custom USB devices (which is what I'm trying to do) but they never seem to get answered very well or at all.  I want to achieve this on the hardware/firmware/driver side rather than having some windows application running on the computer.  If I have to write firmware on the Arduino, buy a USB PID, and/or write a USB driver for the computer, I'll do whatever it takes.

sender: assistant

body:
There is an Arduino Xbox 360 (XInput) library. But I do not use Steam so I have
no idea if this works.

https://github.com/dmadison/ArduinoXInput


message:
Recommendations For High Capacity Microcontrollers

For a new project I'm working on, I'm turning an old Casio Personal Mini into a Speak & Spell (with possibly other functions). However, the speech library I plan on using is Talkie, and it takes up quite a bit of program space. I've been trying to look around for some microcontrollers I could use that have high program storage capacity, but I really don't know much about what I should look for, nor how to find ones that are compatible with the Arduino boot loader. Would any of you have any good suggestions? I'd probably need one with over 256KB of program storage.

body:
In a comment, Juraj wrote:
> the ATmega MCUs are similar so a port to Arduino Mega should be
> possible

This seems indeed to be very much the case.

Looking at the source code of the library, it appears it uses
timer 2 for generating the PWM signal and timer 1 for
scheduling the samples. These timers are almost identical between the
ATmega328P of the Uno and the ATmega2560 used in the Arduino
Mega 2560. The only relevant difference between these boards, as
far as the library is concerned, is the output pin, which is the “OC2B”
pin of the microcontroller:

* on the Uno, OC2B is digital pin 3
* on the Mega, OC2B is digital pin 9

So my guess is that the library should work on the Mega with just this
tiny change:

```diff
--- a/Talkie/talkie.cpp
+++ b/Talkie/talkie.cpp
@@ -71,7 +71,7 @@ void Talkie::say(uint8_t* addr) {
   //
   // Enable the speech system whenever say() is called.

-  pinMode(3,OUTPUT);
+  pinMode(9,OUTPUT);
   // Timer 2 set up as a 62500Hz PWM.
   //
   // The PWM 'buzz' is well above human hearing range and is
```

Also, make sure you plug your headphones on pin 9 rather than
pin 3.

If you try this and it works, please report that either here or directly
to the author of the library. It should then be easy to modify the
library to support both boards out of the box.

------------------------------------------------------------------------

**Edit**: If you download Talkie through the Arduino library manager,
you will get [this version][ArminJo], which does supports the Arduino
Mega 2560.

[ArminJo]: https://github.com/ArminJo/Talkie


message:
Problem with STM32 and SDFat lib on other SPI port

I am using STM32F103C8 and I am triing to compile a code with SDFat library. The problem is I need to use the second channel of the SPI1 (pins PB5,PB4,PB3, PA15):

[![enter image description here][1]][1]

I found out that is possible to use SDFat lib and include SPIClass inside its constructor. Then I could use this code:

    SPIClass SPI_1(PB5,PB4,PB3, PA15);
    SdFat sd(&SPI_1);

The problem is this compliation error:

    no matching function for call to 'SdFat::SdFat(SPIClass*)'

Do you have any idea how to solve this error or how to work with SD card on different pins?

Here is source code of this library:
https://github.com/greiman/SdFat/blob/master/src/SdFat.h

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/OcNO1.jpg
  [2]: https://i.stack.imgur.com/3mcwO.png

body:
Ok, I found out that the sdFat library is not supported on stm32 bluepill (sd card HAL peripherals are not enabled), so I decided to use basic Arduino SD library (it uses SPI commands, not HAL).

Also I have to change pins (from SPI1_1 to SPI1_2) in variant.h and PeripheralPins.c files of bluepill board. - And finally it works (SPI1_2).


message:
I am tying to split a float variable into bytes and then re combine to the original float

Here is the code I am currently using, there have been many and various alternatives I have tried all so far without success, this being the latest incarnation sitting within my main program loop (void loop)...

    // get temperature from Dallas Temperature Sensor
      sensors.requestTemperatures();
      sen0_data = sensors.getTempC(sensor_0_address);             // read temperature sensor0

    // split float
      float f1 = sen0_data;
      byte* fb = (byte*) &f1;

      Serial.println(f1);
      Serial.println(fb[0]);    // Take a look at the bytes
      Serial.println(fb[1]);
      Serial.println(fb[2]);
      Serial.println(fb[3]);

    // rebuild float
      temp = (fb[0] << 24) + (fb[1] << 16) + (fb[2] << 8) + (fb[3]);
      Serial.println(temp);

Now for the result as seen in the serial monitor - original float, split byte 0, byte 1, byte 2, byte 3, and finally rebuilt float. What am I doing wrong? as no doubt can be seen from the dirty coding I am a relative newbe
The starting float value -127.00 is because I currently have no temperature sensor connected to the Arduino, but I would still expect the rebuilt float to be the same and not -318.00. Even if I connect a sensor the rebuilt float does not mirror the original...

    -127.00
    0
    0
    254
    194
    -318.00

I look forward to any advice...
Regards,
    Simon.

body:
I have been told to be careful about a simple casting of non-byte variables to an array of bytes because there's no guarantee that the memory allocated for certain data types will be *contiguous*. I.e., the bytes might be spread out to non-adjacent spots in memory. For example, I was encouraged to use a union to convert a unit64_t, which is 8 bytes, to a byte array on an ESP8266. This involves declaring a `union` type:

```cpp
union u64_bytes {
  uint64_t u64;
  uint8_t u8[sizeof(uint64_t)];
};
```
And then you can use this to convert either way, for example:
```cpp
  uint64_t myNum = 1;
  u64_bytes splitNum;
  splitNum.u64 = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(uint64_t); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  u64_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.u64);
```
EDIT: I added some code to show conversion the other way.

That said, it's probably pretty safe in your case to use the bitwise operators you are using. A float is in all likelihood 4 bytes on your hardware, and most hardware allocates memory these days in four-byte blocks.

HOWEVER you still have to take into account the [Endianness](https://en.wikipedia.org/wiki/Endianness) of the system when it stores values. The basic idea is that if you have four bytes that represent one number, are the **most** significant bytes first or are the **least** significant bytes first?

For example, if you are talking about a four byte unsigned integer the number **1**, aka 0x00000001, it would be stored like this in Big-Endian hexadecimal:
```
0x00 0x00 0x00 0x01
```
But on little endian hardware (like mine) the order is different. They put the *least significant bytes first* in memory like so:
```
0x01 0x00 0x00 0x00
```

This might be very confusing, but the bottom line is you might have to think twice about what the byte order is for your data. I'd add that floats and signed integers might have some aspects that surprise you, and when you try and communicate any information over a serial line (SPI, I2C, etc.) or over a network then you might have to worry about what sort of conversions are happening. You must have to make sure that you know what order your bytes are and you unpack them in a way that's appropriate to the way you packed them.

Lastly, I would encourage you maybe think about (and possibly elaborate) what you are hoping to accomplish by taking apart a float into bytes? If you don't know about the structure of bits inside a float, you would need to get better acquainted with that before you start monkeying with the bytes inside it.

EDIT 2: here's an example where I use a struct to convert a float:
```cpp
  union float_bytes {
    float flt;
    uint8_t u8[sizeof(float)];
  };

  float myNum = -127.0;
  float_bytes splitNum;
  splitNum.flt = myNum;
  // now i can loop thru the bytes
  for(int i=0; i<sizeof(splitNum); i++) {
      uint8_t myByte = splitNum.u8[i];
      Serial.print("byte ");
      Serial.print(i);
      Serial.print(" is ");
      Serial.println(myByte);
  }
  // or just refer to individual bytes
  uint8_t oneByte = splitNum.u8[0];

  // you can also take bytes and convert the other way
  float_bytes rebuilt;
  for(int i=0; i<sizeof(splitNum); i++) {
      rebuilt.u8[i] = splitNum.u8[i];
  }

  Serial.print("The rebuilt value is ");
  Serial.println(rebuilt.flt);
```


message:
Can't read PWM signal from 2-pin fan header

I'm trying to get PWM values from a 2-pin fan header on DuetWifi board (it is a 3D Printer Controller Board). Here is [some info about the fan connection][1] on that board.

  [1]: https://duet3d.dozuki.com/Wiki/Connecting_and_configuring_fans

From their forum, I got to know that fan output is open-drain and can operate with frequency up to 65535 Hz (frequency for each fan is configurable).

First of all, I connected Duet FAN- to Arduino D7 and tried that code:

    int pin = 7;
    unsigned long duration;

    void setup() {
      Serial.begin(9600);
      pinMode(pin, INPUT_PULLUP);
    }

    void loop() {
      duration = pulseIn(pin, HIGH);
      Serial.println(duration);
    }

But it shows constant readings between 6-7 in Serial Monitor:

    7
    6
    7
    7
    7
    7
    7
    6
    6
    7

Also, any fan speed adjustment in the Duet UI doesn't affect those readings as well.

After that, I have tried a lot of different libraries and codding approaches from Arduino forum to get suitable PWM readings from FAN- pin, but have no luck.

body:
Your picture shows that you have only connected one line to the Arduino.  You do not have a common ground between the Arduino and the fan controller.  You need to connect the grounds together.

Voltage is like height, it requires two points to measure.  If I point at a hill and I say, "How high is that hill?" that seems like a pretty easy question to answer at first.  But it becomes ambiguous quickly.  Do we want to say how high it is compared to the ground around it?  Or how high from sea level?  Or how high from where we are standing?  You simply can't say how high a hill is unless you agree on where to measure from.

It's the same with voltage.  You can't measure a voltage unless you have a potential that you can consider the 0 point to measure from.  That 0 point is the ground wire.  And as you have drawn the circuit the two boards don't agree on where they will consider 0 volts.


message:
Can I use a MCP23017 to connect multiple RC522 modules?

I want to connect multiple (exactly 64) RFID-RC522 modules to one Nodemcu ESP8266.
I already know, that it is possible to connect multiple RC522's by just using different pins for the SDA pin, while the rest of the RC522 pins can be connected to the same pins on the ESP8266. But not that many, of course.

My research on "how do I get more pins", got me to the MCP23017 port expander.
Further research is not exactly clear, if I can use these pins as ChipSelect/SlaveSelect pins for the RC522.
The two libaries I found for MCP23017 ([blemasle/arduino-mcp23017](https://github.com/blemasle/arduino-mcp23017) and [Adafruit-MCP23017](https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library) seem not to support this, when I use [miguelbalboa/rfid](https://github.com/miguelbalboa/rfid) (which I have to use, as there seems to be no alternative), because the MCP-Libs do not provide a "Pin Number" for the MFRC522 constructor(?).

So, is this just a "software" thing, or a technical limitation, and what I want is simply not possible? My research was not exactly clear about this, but I'm also very new to electronics and might be researching in the wrong direction.

body:
Sure, you can use IO expanders for the chip-select pins of SPI devices. You *will* have to modify the device libraries to support them, though, because no one is going to do that by default unless it's a very very specific library.

However you will probably not have much luck with your project anyway, since you will more than likely run into problems with fan-out and bus capacitance before you even remotely approach 64 devices on your bus.

You would need to be adding extra bus drivers and partition your bus to reduce and spread the load - at which point it would be simpler and cheaper to just use multiple microcontrollers with just a few RC522s one each.


message:
Is there any way or command to do the double reset of the esp8266 through CODE(sketch)?

I just want to do the double reset of the ESP8266 through code (sketch) .Is there any command or function for this ?is it possible??

body:
There are not enough details in the question so we need to guess the goal of the project.  Assuming the goal is to have alternative behaviors depending on pressing the reset button once or twice with in a given span of time.

[This project at github][1] likely uses the RTC and some of the RTC flash memory in an ESP8266 to determine if the reset button has been pressed once or twice in a given span of time.

From that project:

> PURPOSE: Detects a double reset so that an alternative start-up mode
> can be used. One example use is to allow re-configuration of a
> device's wifi.

  [1]: https://github.com/datacute/DoubleResetDetector


message:
Displayng 2 error messages on a 16x02 display

I am trying to display on a 16x02 LCD display 2 error codes. The error message is when one or both thermocouple wires get disconnected and the second error message is when the soldering iron temp goes higher than 432 C. I am using MAX6675 module.
The problem is that when I disconnect one thermocouple wire (the + or the -) sometimes the displayed message is "Overheating !!!" instead of "No tc conn !!!".

Is there any way to display the correct error ?

```
heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;
   //No TC connection
  if (isnan(Input)) // No TC Connection
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("NO TC CONN !!!");
      delay(1000);
    }
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OVERHEATING !!!");
      delay(1000);
    }
  }
```

Edit: I finally decided to use the same message for both errors - no TC connection and overheating. I used the code below:
```
heaterTemp = thermocouple.readCelsius();
  Input = 0.779828 * heaterTemp - 10.3427;
  if (isnan(heaterTemp) or Input >= 432) // No TC Connection OR over-temperature
  {
    while (true) {
      digitalWrite(relay_pin, LOW);
      digitalWrite(11, LOW);
      for (int i=0; i<=1; i++){
      lcd.clear();
      lcd.setCursor(0, i);
      lcd.write((byte)0);
      lcd.setCursor(1, i);
      lcd.write((byte)0);
      lcd.setCursor(5, i);
      lcd.print("ERROR!");
      lcd.setCursor(14, i);
      lcd.write((byte)0);
      lcd.setCursor(15, i);
      lcd.write((byte)0);
      delay(1000);
      }
    }
  }
```
and
```
byte thermometer[8] = //icon for termometer
{
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110
};
```
The code displays the thermometer symbol at the beginning and at the end of the row and the text (including the symbols) are moving from one to another row.

Now it is sufficiently to display a error message when the thermocouple gets disconnected or when the iron temperature goes above 432 *C.

I have also left the 2 while(true) loops because I need the program to stay in the loop and display the error message until I turn off the power and start again the soldering station.

body:
I think before the disconnection is detected, it goes into overheating (maybe just for some milliseconds).

However, because there is a `while (true)` loop within the overheating part, it will never show the `NO TC CONN` error.

If you consider the `NO TC CONN` error to be higher than the `OVERHEATING` error, than check within the `while` loop of the `OVERHEATING` error also for the `NO TC CONN` error and display `NO TC CONN` when it is detected.


body:
I'd reserve line #1 for one message, line #2 for the other

      heaterTemp = thermocouple.readCelsius();
      Input = heaterTemp - 100;
      lcd.clear();
      //No TC connection
      if (isnan(Input)) // No TC Connection
      {
        while (true) {
          digitalWrite(relay_pin, LOW);
          digitalWrite(11, LOW);
          // lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("NO TC CONN !!!");
          delay(1000);
        }
      }

      //Soldering Iron overtemperature
      if (Input >= 432)
      {
        while (true) {
          digitalWrite(relay_pin, LOW);
          digitalWrite(11, LOW);
          // lcd.clear();
          // lcd.setCursor(0, 0);
          lcd.setCursor(1, 0);
          lcd.print("OVERHEATING !!!");
          delay(1000);
        }
      }


body:
According to [MAX6675 datasheet](https://datasheets.maximintegrated.com/en/ds/MAX6675.pdf) page 5, it will set Bit 2 of SPI register to HIGH when the thermocouple is open. Adafruit's MAX6675 library however changed this to return a NAN when Bit 2 is set when you call the [`readCelsius()`](https://github.com/adafruit/MAX6675-library/blob/master/max6675.cpp#L46-L48) method of the library, so what you should do is to check is `isnan(heaterTemp)` instead of `innan(Input)`.

    heaterTemp = thermocouple.readCelsius();
    if (isnan(heaterTemp)) // No TC Connection
    {
        while (true) {
          digitalWrite(relay_pin, LOW);
          digitalWrite(11, LOW);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("NO TC CONN !!!");
          delay(1000);
        }
    }
    else
    {
      Input = heaterTemp - 100;
      //Soldering Iron over-temperature
      if (Input >= 432)
      {
        while (true) {
          digitalWrite(relay_pin, LOW);
          digitalWrite(11, LOW);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("OVERHEATING !!!");
          delay(1000);
        }
      }
    }


body:
You should get rid of the `while(true)` loops, because when you enter one of them, you'll never get out.

 void loop()
 {
  heaterTemp = thermocouple.readCelsius();
  Input = heaterTemp - 100;

  //No TC connection
  if (isnan(Input)) // No TC Connection
  {
   digitalWrite(relay_pin, LOW);
   digitalWrite(11, LOW);
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("NO TC CONN !!!");
  }

  //Soldering Iron overtemperature
  if (Input >= 432)
  {
   digitalWrite(relay_pin, LOW);
   digitalWrite(11, LOW);
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("OVERHEATING !!!");
  }

  delay(1000);
 }

EDIT: code below is needed to cut of the power

<strike>
Don't know the purpose of

    digitalWrite(relay_pin, LOW);
    digitalWrite(11, LOW);

Maybe it's better to move these lines to `setup()`
</strike>


message:
Setup of Arduino Uno as ArduinoISP for programming attiny45

I have an Arduino Uno SMD and an attiny45, which I want to use as a sensor communicating via i2c. For a first step in finding out how to work with the attiny45 I just want to use the attiny as controller for a blinking led.

When first setting up the Arduino as "Arduino as ISP" some questions came up:

1) I found a lot of different information about wheter or not to use a capacitor between RESET and GND on the Arduino. Also the capacity differs between 0.1uF and 10uF. Unfornately, I found not a single comment on why this capacitor is needed (or not) and which capacities are suitable. All tutorials used electrolytic capacitors (which I only have in 100uF at hand). I have 10nF and 0.1uF at hand but only the film capacitor type. It would be brilliant if some could help me with deciding if I should use a capacitor, which one is suitable and what's the reason for using it.

2) My second question is about the clock rate I should set in the Arduino IDE. I added the board package from https://github.com/SpenceKonde/ATTinyCore to my Arduino IDE, which offers a large variety of clock rates in the tools dropdown menu. In some tutorials they mentioned that it's crucial to pick the correct clock speed to avoid wrecking the attiny. But, unfortunately, the mentioned clock speeds vary between "1 MHz (internal)" and "8 MHz (internal)". In the attiny45 datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf) I found the "Calibrated Internal Oscillator" to be the clock set up in freshly shipped chips, which I understand to operate at 8 MHz. But, the datasheet also says, that the CKDIV8 fuse is set on shipment, which leads to a clock prescale value of 8 and to a clock rate of 1 MHz. I'm highly confused... Maybe someone here can help me to find the correct clock rate to set.

I hope I didn't forget any important information. If so, please let me know.

Kind regards and thank you in advance,
Matthias

body:
1. The capacitor is meant to prevent the programming Arduino from being reset. Normally, when you open the serial connection, the Arduino gets reset and first starts into the bootloader (which would be used to program it). But when using the Arduino as ISP programmer, you don't want to run the bootloader of the programmer. You want to let the programmer sketch work as intended. Thus you want to prevent the programmer from resetting on serial connection. The capacitor between Reset and ground holds the 5V level of the reset pin for the time, that the reset pulse from the USB Serial chip is trying to pull the pin to low. So it prevents the reset from happening.

    The value and type of the capacitor is not critical here. I always use a 47uF bipolar electrolyte capacitor, because I have a bunch of them just laying around. The value just shouldn't be unreasonable small or big. The mentioned range of yours is just giving you a hint in which order the value should be. Also you can simply test, if the reset happens with your capacitor. You cannot break things with a wrong value here.

2. Which clock frequency to use is up to your exact requirements. There is no "this is the best for all occasions"-frequency. Also you are not wrecking the Attiny with any of the clock speeds. Though you should note, that choosing an external clock source means, that you actually need to provide that clock source for the ATTiny to work. The fuses can be reprogrammed, if you have chosen a wrong frequency by accident.

    The datasheet states just as you wrote. The interal oscillator is by default set to 8MHz, while the prescaler divides that down to 1MHz as the main CPU clock. So by default the ATTiny runs on 1MHz. You can change that, if you like.

    For my Attiny85s I always used internal 8MHz as the setting (the option, that appears in the IDE menu). That is the easiest way (internal means you need no external components for the clock), while being the fastest speed you can get with the internal clock, I think.


message:
Program Nano Every using UPDI port

I have and Arduino Nano and an Arduino Nano Every. I'm doing some experiments and trying to program the Nano Every from the Nano, using the UPDI port.

I'm using tutorials like [this][1] one that does the same thing but instead of Arduino Nano Every he wants to program an ATtiny.

What I did so far:

**1. Transform Arduino Nano into a UPDI programer:**

1.1 Clone [jtag2updi][2] and open `jtag2updi.ino`. Connect Arduino Nano through USB to my computer and compile and upload jtag2updi with Arduino IDE just like any other sketch.

1.2 Connect a capacitor of 10uF between RST and GND pins of Arduino Nano

1.3 Install [MegaCoreX][3] into Arduino IDE.

**2. Program  Arduino Nano Every from a UPDI:**

2.1 Connect UPDI pin from Arduino Nano Every to pin D6 of Arduino Nano with a 4.7k resistor. Connect 5V and GND of both boards.

2.2 In Arduino IDE open the Blink example and chose from the `Tools` menu the following configuration:

[![enter image description here][4]][4]

2.3 Compile and upload sketch.

**Error:**

And the problem is that it gives this error:

    Arduino: 1.8.12 (Mac OS X), Board: "ATmega4809, Nano Every, Reset, BOD 2.6V, Internal 20 MHz, No bootloader"

    /Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
    /Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
    Using board '4809' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
    Using core 'coreX-corefiles' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
    Detecting libraries used...
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /dev/null
    Generating function prototypes...
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
    /Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
    Compiling sketch...
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o
    Compiling libraries...
    Compiling core...
    Using precompiled core: /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a
    Linking everything together...
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--section-start=.text=0x0 -mmcu=atmega4809 -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/../arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a -L/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -lm
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.eep
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -R .eeprom /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex
    chmod +x /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh
    /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objdump "--disassemble --source --line-numbers --demangle --section=.text" /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.lst
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-size -A /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf
    Sketch uses 814 bytes (1%) of program storage space. Maximum is 49152 bytes.
    Global variables use 4 bytes (0%) of dynamic memory, leaving 6140 bytes for local variables. Maximum is 6144 bytes.
    Forcing reset using 1200bps open/close on port /dev/cu.usbserial-1440
    /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf -v -patmega4809 -cjtag2updi -P/dev/cu.usbserial-1440 -e -Uflash:w:/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex:i -Ufuse0:w:0x00:m -Ufuse1:w:0x54:m -Ufuse2:w:0x02:m -Ufuse4:w:0x00:m -Ufuse5:w:0xC9:m -Ufuse6:w:0x06:m -Ufuse7:w:0x00:m -Ufuse8:w:0x00:m -Ulock:w:0xC5:m

    avrdude: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf"
             User configuration file is "/Users/miguelwon/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : /dev/cu.usbserial-1440
             Using Programmer              : jtag2updi
    JTAG ICE mkII sign-on message:
    Communications protocol version: 1
    M_MCU:
      boot-loader FW version:        1
      firmware version:              6.00
      hardware version:              1
    S_MCU:
      boot-loader FW version:        1
      firmware version:              6.00
      hardware version:              1
    Serial number:                   00:00:00:00:00:00
    Device ID:                       JTAGICE mkII
             AVR Part                      : ATmega4809
             Chip Erase delay              : 0 us
             PAGEL                         : P00
             BS2                           : P00
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 0
             StabDelay                     : 0
             CmdexeDelay                   : 0
             SyncLoops                     : 0
             ByteDelay                     : 0
             PollIndex                     : 0
             PollValue                     : 0x00
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
               prodsig        0     0     0    0 no         61   61      0     0     0 0x00 0x00
               fuses          0     0     0    0 no          9    0      0     0     0 0x00 0x00
               fuse0          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse1          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse2          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse4          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse5          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse6          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse7          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               fuse8          0     0     0    0 no          1    0      0     0     0 0x00 0x00
               lock           0     0     0    0 no          1    0      0     0     0 0x00 0x00
               data           0     0     0    0 no          0    0      0     0     0 0x00 0x00
               usersig        0     0     0    0 no         64   64      0     0     0 0x00 0x00
               flash          0     0     0    0 no      49152  128      0     0     0 0x00 0x00
               eeprom         0     0     0    0 no        256   64      0     0     0 0x00 0x00

             Programmer Type : JTAGMKII_PDI
             Description     : JTAGv2 to UPDI bridge
             M_MCU hardware version: 1
             M_MCU firmware version: 6.00
             S_MCU hardware version: 1
             S_MCU firmware version: 6.00
             Serial number:          00:00:00:00:00:00
             Vtarget         : 5.0 V

    avrdude: jtagmkII_set_devdescr(): bad response to set device descriptor command: RSP_NO_TARGET_POWER
    avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
    avrdude: AVR device initialized and ready to accept instructions

    Reading | avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
    avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
    avrdude: jtagmkII_read_byte(): bad response to read memory command: RSP_NO_TARGET_POWER
    avr_read(): error reading address 0x0000
        read operation not supported for memory "signature"
    avrdude: error reading signature data for part "ATmega4809", rc=-2
    avrdude: error reading signature data, rc=-2
    avrdude: jtagmkII_program_disable(): bad response to leave progmode command: RSP_NO_TARGET_POWER

    avrdude done.  Thank you.

    the selected serial port
     does not exist or your board is not connected

  [1]: https://www.youtube.com/watch?v=AL9vK_xMt4E
  [2]: https://github.com/SpenceKonde/jtag2updi
  [3]: https://github.com/MCUdude/MegaCoreX#how-to-install
  [4]: https://i.stack.imgur.com/LSJY1.png

body:
I'm not sure if you ever solved this issue but for me this error was occurring because the ATmega4809 chip was not powered on. By adjusting the wiring I managed to get rid of the "RSP_NO_TARGET_POWER" error.

So I would suggest double checking wiring and then use the "Upload using programmer" (in "Sketch" tool-bar menu) to upload as suggested by Juraj.


message:
How to specify a timer's name depending on the chip it will be compiled to?

I need to enable a timer interrupt for a chip, and in the mean time, I am testing the code on Arduino Nano rather than `(feed the chip, test the chip)++`.

So as part of the code I have to `TIMSK0 |= (1 << OCIE0A);` which works great on the Arduino Nano, but has to be changed to `TIMSK` (without the 0) for the ATtiny45.

I was planning to go for something along the line of

    #define NANO//Put // in front for the AtTiny45
    #ifdef NANO
      const char in  = A0;
      const char out = 3;
      const char pwr = 10;
      char *timer = &TIMSK0;
    #else
      const char in  = 3;
      const char out = 0;
      const char pwr = 1;
      char *timer = &TIMSK;
    #endif
    //...
    *timer  |= (1 << OCIE0A);

So here are my three questions:

 - Do #these commands take space on a chip?
 - Is a pointer the way to go for this kind of things?
 - Am, am I doing it right?

body:
Just as a complement to Delta\_G's answer:

2. The names `TIMSK0`, `OCIE0A`, etc. are already preprocessor macros
   so, for consistency, it makes sense to define your own preprocessor
   macros for them. I tend to be lazy and use one of the already defined
   names, like

   ```cpp
   #ifdef TIMSK0  // support both ATtiny{25,45,85} and ATmega328P
   # define TIMSK TIMSK0
   #endif
   ```

   A `const` pointer for `&TIMSK0` is fine though.

3. The macros identifying the MCU are defined to the value 1. Thus you
   have the choice between these three idioms:

   ```cpp
   #ifdef __AVR_ATtiny45__
   ...
   #endif

   #if defined(__AVR_ATtiny45__)
   ...
   #endif

   #if __AVR_ATtiny45__
   ...
   #endif
   ```

   The third one is convenient when you want to address several MCU
   models with the same code:

   ```cpp
   #if __AVR_ATtiny25__ || __AVR_ATtiny45__ || __AVR_ATtiny85__
   ...
   #endif


message:
DH11 and uno relay controle fridge

I want to control my bar fridge with temp sensor and relay,

This is my first project with code, i copied this:
https://robojax.com/learn/arduino/?vid=robojax-DHT22_11_TM1637_relay

But

I want some extra code that will prevent the fridge (ie relay) from going on too often.

For my purposes I want the relay to close if the temp is above 4c, but only if the relay has been off for say 20min or more.  FYI this is because my power source does not like to start the compressor when it is hot, so i don't want it cycling if it was just on.

body:
Cool question! ;-) Instead of a fixed timer, I would build in some (so-called) [hysteresis](https://en.wikipedia.org/wiki/Hysteresis), which means turning refrigeration on above a certain temperature (say 4 °C) but only turning off when the temperature has dropped again to a temperature well below that (say 3 °C). This ensures the temperature stays within set limits while at the same time preventing fast cycling. You don’t need any timers for this and it will work in any situation (even when it’s very hot or very cold outside of the fridge). This is how commercial thermostats work.

If you really need to ensure the compressor cools enough between cycles, you just need to start a timer when it turns off, and not turn on again before it expires. Look at examples like [BlinkWithoutDelay](https://www.arduino.cc/en/tutorial/BlinkWithoutDelay) for some coding ideas.


message:
I want to program multiple arduino at once

I am aware that using a USB Hub you can attach multiple arduino to one computer and either upload code one by one or use bash script to upload code on all arduinos together. But you can attach only as many arduino to a computer. I need to prgram around 100 arduinos/atmega ICs at once. Is there a way to do so?
There are other methods that I found online like programming ICs over Wifi network. But that require a lot of WiFi chips connected to arduino. I cant setup that. Also that doesn't seems cost effective.
Also Arduino sells their uno and other boards with pre-installed blink program. They must be doing batch programming only (multiple ICs at once). Any idea how they do this?

body:
Arduino, the company, may sell on enough volume to make it worthwhile to get the microcontroller manufacturer to program the microcontrollers durin the production process
 This wouldn't cost them extra if they already get the bootloader pre-programmed. I've read programming ICs is a service available to high volume customers.

I guess low volume makers use fixtures that use the ICSP headers, pogo sticks or IC clips and which trigger the programming on contact using a microswitch etc.

I suspect Adafruit do something of this sort, see GIFs and video discussing testing at

https://www.adafruit.com/product/2458


body: I recommend using optiloader, which uses a standalone arduino to program an arduino connected to it.  You can therefore create as many arduino programmers as you want, each of which can run without connecting to a host computer.  This is how firmware is loaded for high volume production.


body:
> Any idea how they do this?

You can buy gadgets that let you upload code in a second or so. For example, [here](http://www.crossroadsfencing.com/BobuinoRev17/Programmer.html). You plug in the target board, press a button, and it's done.

These program a board in a couple of seconds. While this is hardly literally "at once" it would take time anyway to connect 100 Arduinos to "something" so connecting and disconnecting every couple of seconds is roughly the same thing.

That board mentioned above uses [code I wrote](http://www.gammon.com.au/forum/?id=11638) which can run on an ordinary Arduino. In other words, use one to program another, where the code to be uploaded is stored on a micro-SD card.


message:
Arduino Micro: Why am I getting 6.00 as a result instead of 6.66?

Basically, on the TWR calculator page, when I entered 20 as the initial value and 3 as the value that comes after, I somehow get 6.00 as a result instead of 6.66 in the computeTWR() function. How can I fix this?

    // ------------------- DIVIDER ---------------------
    /*
       Jebediah's Launch Control System for Kerbal Space Program
       Alpha Build 1.1
       An Open-Source Project by John Seong
    */

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <Keypad.h>

    const byte ROWS = 4;
    const byte COLS = 3;

    char keys[ROWS][COLS] = {
      {'1', '2', '3'},
      {'4', '5', '6'},
      {'7', '8', '9'},
      {'*', '0', '#'}
    };

    byte rowPins[ROWS] = {12, 11, 10, 9};
    byte colPins[COLS] = {8, 7, 6};

    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

    // Show a two-line message on the LCD.
    void lcdShow(const char *line0, const char *line1) {
      lcd.clear();
      lcd.print(line0);
      lcd.setCursor(0, 1);
      lcd.print(line1);
    }

    void computeTWR(int thrustR, int weightR) {
      float result = thrustR / weightR;
      lcd.print(result);
    }

    void setup() {
      Serial.begin(9600);
      lcd.begin(16, 2);
      lcdShow("Jeb's Launch", "Control System");
      delay(3000);
      lcdShow("Alpha Build 1.1", " STUDIO HORIZON");
      delay(3000);
      lcdShow("Welcome, Kerman", "Press any key...");
      while (!keypad.getKey()) ;  // wait for key press
    }

    void loop() {
      static enum {START, MENU, SET_COUNT, COUNT_DOWN, SET_THRUST, SET_WEIGHT, TWR_COMPUTE} state = START;
      static uint32_t last_second;  // millis() value on last full second
      static int count, thrust, weight;             // countdown, thrust, weight value
      static float ratio;

      char key = keypad.getKey();

      switch (state) {
        case START:  // transitional state
          lcdShow("1. Countdown", "2. TWR");
          state = MENU;
        /* fallthrough */
        case MENU:
          if (key == '1') {  // Countdown
            lcdShow("Countdown Timer", "Seconds: ");
            count = 0;
            state = SET_COUNT;
          } else if (key == '2') {  // TWR
            lcdShow("TWR Calculator", "Thrust: ");
            thrust = 0, weight = 0, ratio = 0;
            state = SET_THRUST;
          }
          break;
        case SET_COUNT:
          if (key >= '0' && key <= '9' && count <= 99) {
            lcd.print(key);
            count = 10 * count + (key - '0');
          } else if (key == '#') {
            lcdShow("Lift off in", "     seconds");
            // Force a refresh on entering COUNT_DOWN:
            last_second = millis() - 1000;
            count++;
            state = COUNT_DOWN;
          } else if (key == '*') {
            state = START;
          }
          break;
        case COUNT_DOWN:
          if (millis() - last_second >= 1000) {
            last_second += 1000;
            count--;
            if (count == 0) {
              Serial.println("Lift off!");
            } else if (count < 0) {
              state = START;
              break;
            }
            lcd.setCursor(1, 1);
            lcd.print(count < 10 ? "  " : count < 100 ? " " : ""); // pad
            lcd.print(count);
          } else if (key == '*') {
            state = START;
          }
          break;
        case SET_THRUST:
          if (key >= '0' && key <= '9' && thrust <= 9999) {
            lcd.print(key);
            thrust = 10 * thrust + (key - '0');
          } else if (key == '#') {
            lcdShow("TWR Calculator", "Weight: ");
            state = SET_WEIGHT;
          } else if (key == '*') {
            state = START;
          }
          break;
        case SET_WEIGHT:
          if (key >= '0' && key <= '9' && weight <= 9999) {
            lcd.print(key);
            weight = 10 * weight + (key - '0');
          } else if (key == '#') {
            lcdShow("Thrust-to-weight", "ratio: ");
            computeTWR(thrust, weight);
          } else if (key == '*') {
            state = START;
          }
          break;
      }
    }

body:
(community wiki answer derived from comments - takes Q off unanswered list)

> Why am I getting 6.00 as a result instead of 6.66?

because integer arithmetic discards fractional parts of results, including intermediate results

    static int count, thrust, weight;             // countdown, thrust, weight value

If some of these are intended to have decimal values you need to use a more suitable data type (e.g. `float`)


message:
Run a part of a code only 4 second

I have two different programs written for my Arduino. One control the rockets thrust vector. The other one is for parachute.

I need to first run rotationmatrices() for a 4 second and then parachute.

How could i do that?

Here is my code:

```
//Libraries
#include <Servo.h>
#include <Wire.h>
#include <MPU6050_tockn.h>
#include <AFMotor.h>
#include <I2Cdev.h>

MPU6050 mpu6050(Wire);

const int MPU = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyroY, GyroZ;
double PIDX, PIDY, errorX, errorY, previous_errorX, previous_errorY,
       pwmX, pwmY, previouslog, OutX, OutY, OutZ, OreX, OreY, OreZ;
double PreviousGyroX, PreviousGyroY, PreviousGyroZ, IntGyroX,
       IntGyroY, IntGyroZ, DifferenceGyroX, DifferenceGyroY,
       DifferenceGyroZ, matrix1, matrix2, matrix3;
double matrix4, matrix5, matrix6, matrix7, matrix8, matrix9, Ax, Ay;

//Upright Angle of the Flight Computer-Dik durum açısı
int desired_angleX = 0;

//Offsets for tuning
int servoX_offset = 100;

//Position of servos through the startup function
int servoXstart = 80;

//The amount the servo moves by in the startup function
int servo_start_offset = 20;

//Ratio between servo gear and tvc mount
float servo_gear_ratio = 5.8;

double OrientationX = 0;
double OrientationY = 0;
double OrientationZ = 1;
double accAngleX;
double accAngleY;
double yaw;
double GyroX;
double gyroAngleX;
double gyroAngleY;
double pitch;

Servo servoX;

AF_DCMotor motor1(1); // create motor #1
AF_DCMotor motor2(2); // create motor #2
AF_DCMotor motor3(3); // create motor #1
AF_DCMotor motor4(4); // create motor #2

int buzzer = 3;

double dt, currentTime, previousTime, s, p;

//"P" Constants-Orantısal Değişken
float pidX_p = 0;
float pidY_p = 0;

//"I" Constants-Integral Değişken
float pidY_i = 0;
float pidX_i = 0;

//"D" Constants-Türevsel Değişken
float pidX_d = 0;
float pidY_d = 0;

int pos;

//PID Gains
double kp = 0.2;
double ki = 0.0;
double kd = 0.05;

int state = 0;

void setup() {
    Serial.begin(9600);
    Wire.begin();
    mpu6050.begin();
    gyrocalibrate();

    servoX.attach(10);

    motor1.setSpeed(255);
    motor2.setSpeed(255);
    motor3.setSpeed(255);
    motor4.setSpeed(255);

    pinMode(buzzer, OUTPUT);
}

void loop() {
    mpu6050.update();
    //Defining Time Variables-Zaman değişkeni tanımlanması
    previousTime = currentTime;
    currentTime = millis();
    dt = (currentTime - previousTime) / 1000;
    launchdetect();
    rotationmatrices();
    parachute();
}

void parachute() {
    motor1.run(BACKWARD);
    delay(1500);
    motor1.run(RELEASE);
    delay(20000);
}

void gyrocalibrate() {
    mpu6050.calcGyroOffsets(true);
}

void rotationmatrices(x) {
    mpu6050.update();
    PreviousGyroX = IntGyroX;
    PreviousGyroY = IntGyroY;
    PreviousGyroZ = IntGyroZ;

    IntGyroX = mpu6050.getGyroAngleX() * (PI / 180);
    IntGyroY = mpu6050.getGyroAngleY() * (PI / 180);
    IntGyroZ = mpu6050.getGyroAngleZ() * (PI / 180);

    DifferenceGyroX = (IntGyroX - PreviousGyroX);
    DifferenceGyroY = (IntGyroY - PreviousGyroY);
    DifferenceGyroZ = (IntGyroZ - PreviousGyroZ);

    OreX = OrientationX;
    OreY = OrientationY;
    OreZ = OrientationZ;

    //X Matrices
    matrix1 = (cos(DifferenceGyroZ) * cos(DifferenceGyroY));
    matrix2 = (((sin(DifferenceGyroZ) * -1) * cos(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix3 = ((sin(DifferenceGyroZ) * sin(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Y Matrices
    matrix4 = sin(DifferenceGyroZ) * cos(DifferenceGyroY);
    matrix5 = ((cos(DifferenceGyroZ) * cos(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix6 = (((cos(DifferenceGyroZ) * -1) * sin(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Z Matrices
    matrix7 = (sin(DifferenceGyroY)) * -1;
    matrix8 = cos(DifferenceGyroY) * sin(DifferenceGyroX);
    matrix9 = cos(DifferenceGyroY) * cos(DifferenceGyroX);

    OrientationX = ((OreX * matrix1)) + ((OreY * matrix2))
                 + ((OreZ * matrix3));
    OrientationY = ((OreX * matrix4)) + ((OreY * matrix5))
                 + ((OreZ * matrix6));
    OrientationZ = ((OreX * matrix7)) + ((OreY * matrix8))
                 + ((OreZ * matrix9));

    Serial.println(Ax);
    OutX = OrientationX * 60;
    Ax = asin(OrientationX) * (-180 / PI);
    pidcompute();
}

void servowrite() {
    servoX.write(pwmX);
}

void pidcompute() {
    previous_errorX = errorX;
    errorX = Ax - desired_angleX;

    //Defining "P"
    pidX_p = kp*errorX;

    //Defining "D"
    pidX_d = kd*((errorX - previous_errorX)/dt);

    //Defining "I"
    pidX_i = ki * (pidX_i + errorX * dt);

    PIDX = pidX_p + pidX_i + pidX_d;
    pwmX = ((PIDX * servo_gear_ratio) + servoX_offset);
    servowrite();
}

void launchdetect() {
    if (mpu6050.getAccZ() > 1) {
        state = 1;
    }
    if (state == 1) {
    }
}

void abortstart() {
    if (OrientationX > 40 || OrientationY > 40) {
        digitalWrite(buzzer, HIGH);
    }
    else if (OrientationX < 40 || OrientationY < 40) {
    }
}
```

body:
you can do it like this using millis it's just an small portion of code just for your understanding you will require some editing for your code.

```
unsigned long milli1;
void setup()
{
}
void loop()
{
     // code before rotationmatrices() function to be active.
     milli1= millis();
     while(millis()-milli1 <= 4000)  //4000milli sec = 4 sec
     {
      rotationmatrices();
     }
     parachute();

}

```


message:
ESP32 - DeepSleep loop or not?

I'm trying to create a battery & solarpowered ESP32 for future use with sensors.
It connects to Wifi, MQTT, publishes some readings and status messages and go back to sleep. From time to time (can happen after few sleep cycles and sometimes after few hunderds cycles )I get 2 unexplained behaviours : 1) fail to connect to MQTT at boot, 2) fail to sleep.

Sometimes those behaviours happen simultaneously.

Is there a known issue with `deepsleep` and MQTT (using `PubSubClient` ) ? Most deepsleep example I see online, all code is outside `loop()`section - is it mandatory to be like that ?

I don't share code, since it is more a general question.

Guy

**EDIT1**

1) most of `callback` was commented out, remaining only printing incoming message.

2) LED was attached to a GPIO, generating a blink on `loop()` - when sleep succeeds - it goes off, when it fails, it stays on. This test shows that when this "error" happens, code actually stop running, but does not enters deep sleep ( power-wise )

body:
> Is there a known issue with deepsleep and MQTT ?

No. There may be a specific problem with the specific library you are using, but the concept of there being an issue with MQTT in general is nonsense.

> Most deepsleep example I see online, all code is outside loop()section - is it mandatory to be like that ?

No, that's just being structured and tidy with your code. Whether code is in loop or in functions that are called by loop makes no difference. It can be a lot easier to manage your code if you structure it in functions rather than dumping it all in loop.


message:
PubSubClient - MQTT_MAX_PACKET_SIZE How is it calculated

I'm using an ESP32, and I want to rule out a probable MQTT error. In `PubSubClient` , `MQTT_MAX_PACKET_SIZE` is set to 256. Is 256 the size for message only ? if not, what is left for message only ?

body:
It is the maximum size of an entire packet.  In `publish()` this check is done:

    if (MQTT_MAX_PACKET_SIZE < MQTT_MAX_HEADER_SIZE + 2+strlen(topic) + plength) {

So the maximum length of a message payload will be

    MQTT_MAX_PACKET_SIZE - MQTT_MAX_HEADER_SIZE - 2 - strlen(topic)

`MQTT_MAX_HEADER_SIZE` is defined as 5, so if you have, for example, a 20 character topic you would have `256 - 5 - 2 - 20 = 229` bytes left for your payload.


message:
How do I set up an Arduino to be a wireless HID?

The question below describes how to set up an Arduino as an HID (Human Input Device -- like a keyboard, mouse, etc.).  How can I set up an Arduino as a wireless HID?

I'm flexible as to the wireless format.  Bluetooth, USB receiver, or any other format is acceptable.

https://arduino.stackexchange.com/questions/484/arduino-as-usb-hid

body:
I'm not sure for Arduino, but [it has been done with ESP32](https://hackaday.com/2020/02/13/emulating-a-bluetooth-keyboard-with-the-esp32/). If you have not yet spent the money into a Bluetooth module for Arduino, you'll find that the ESP32 is not expensive either.

You can [find the code on Github](https://github.com/witnessmenow/arduino-switcheroonie/blob/master/BLE-switcheroonie/BLE-switcheroonie.ino). The author uses a TinyPico because it's pin compatible with one of his earlier projects. IMHO, any ESP32 should do as well.

The key thing is to

    #include <BleKeyboard.h>

[the ESP32 BLE Keyboard library](https://github.com/T-vK/ESP32-BLE-Keyboard/releases) that you need to download and install. That library comes with example code that should be easy to adapt to your needs.

You can program the ESP32 in Arduino IDE, but you need to add support for the boards by [adding a URL to the board manager](https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md).

Have fun with the project. It sounds very interesting. Maybe I try that myself.


message:
Arduino Micro: Button inputs are not working!

I have no clue why this is happening to me but the buttons (in this case, buttonAbort and buttonStage) are not working whatsoever.

Edit:
Basically the LEDs are placed right next to the button,(e.g. ledStage -> placed next to the buttonStage) they start to blink when the timer hits zero with a buzzer noise, and if the user presses one of the buttons, the buzzer noise stops and the LED placed next to the button they pressed turns on whereas the other turns off. I also connected the buttons without resistors. (directly to the pins)

```
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 2.00
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

const int buzzer = A3;
const int ledAbort = 5;
const int ledStage = A5;
const int buttonAbort = 4;
const int buttonStage = A4;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void lcdShowResult(float result) {
  lcd.print(result);
}

void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(ledAbort, OUTPUT);
  pinMode(ledStage, OUTPUT);
  pinMode(buttonAbort, INPUT_PULLUP);
  pinMode(buttonStage, INPUT_PULLUP);

  Serial.begin(9600);
  lcd.begin(16, 2);
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, LAUNCH, SET_THRUST, SET_WEIGHT} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count;
  static float thrust, weight, ratio;

  int stageConfirm = digitalRead(buttonStage);
  int abortConfirm = digitalRead(buttonAbort);

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. LAUNCH SEQ", "2. TWR CALC");
      state = MENU;
    /* fallthrough */

    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("COUNTDOWN TIMER", "SECONDS: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("TWR CALCULATOR", "THRUST: ");
        thrust = 0, weight = 0, ratio = 0;
        state = SET_THRUST;
      }
      break;

    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("    T-MINUS", "     SECONDS");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;

    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count <= 10) {
          tone(buzzer, 500);
          delay(500);
          noTone(buzzer);
        }
        if (count == 0) {
          Serial.println("Lift off!");
        } else if (count < 0) {
          state = LAUNCH;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count < 10 ? "  " : count < 100 ? " " : ""); // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;

    case LAUNCH:
      tone(buzzer, 3000);
      digitalWrite(ledAbort, HIGH);
      digitalWrite(ledStage, HIGH);
      lcdShow(" T-ZERO WARNING", "CONFIRM IGNITION");
      delay(1000);
      lcd.clear();
      digitalWrite(ledAbort, LOW);
      digitalWrite(ledStage, LOW);
      delay(500);

      stageConfirm = digitalRead(buttonStage);
      abortConfirm = digitalRead(buttonAbort);

      if (stageConfirm == LOW) {
        noTone(buzzer);
        digitalWrite(ledStage, HIGH);
        digitalWrite(ledAbort, LOW);
        lcdShow("  LIFT OFF", "HAVE A SAFE FLIGHT");
        break;

      } else if (abortConfirm == LOW) {

        break;
      }
      Serial.println(stageConfirm);
      Serial.println(abortConfirm);

      break;

    case SET_THRUST:
      if (key >= '0' && key <= '9' && thrust <= 9999) {
        lcd.print(key);
        thrust = 10 * thrust + (key - '0');
      } else if (key == '#') {
        lcdShow("TWR CALCULATOR", "WEIGHT: ");
        state = SET_WEIGHT;
      } else if (key == '*') {
        state = START;
      }
      break;

    case SET_WEIGHT:
      if (key >= '0' && key <= '9' && weight <= 9999) {
        lcd.print(key);
        weight = 10 * weight + (key - '0');
      } else if (key == '#') {
        lcdShow("THRUST-TO-WEIGHT", "RATIO: ");
        if (thrust != 0 || weight != 0) {
          ratio = thrust / weight;
          lcdShowResult(ratio);
        }
      } else if (key == '*') {
        state = START;
      }
      break;
  }
}
```

body:
This code is reading the buttons at two places in `loop()`, but the
first time the results are ignored. Only the readings done in the LAUNCH
state can have any effect. The problem is that the reading is done only
at one very specific time, 1.5 seconds after displaying “CONFIRM
IGNITION”. If you press the button before or after this moment, it has
no effect.

Reading only once per loop iteration is fine, as long as the loop turns
fast enough, without getting stuck in a `delay()`. As a general rule,
you try to avoid `delay()` whenever you want to write a program that
should react to external events such as button presses. See the Arduino
example [Blink without delay][] for a technique for achieving that. A
_finite state machine_ is a good way to program without delays, and
fortunately you are already working with one. To detect a button press,
you typically use two distinct states:

* a “wait for button press” state that is sensitive to the button
* a “button has been pressed” state that is reached when the user
  presses the button.

There can be multiple “button pressed” states if there are multiple
buttons to wait for. The transition from the “waiting” state to the
others is then conditioned on the button presses:

```cpp
case WAIT_FOR_BUTTON_PRESS:
    if (digitalRead(button_1_pin) == LOW) {
        do_the_action_relevant_to_button_1();
        state = BUTTON_1_HAS_BEEN_PRESSED;
    } else if (digitalRead(button_2_pin) == LOW) {
        do_the_action_relevant_to_button_2();
        state = BUTTON_2_HAS_BEEN_PRESSED;
    }
    break;
```

Obviously you would choose state names that are more relevant for your
specific project.

[Blink without delay]: https://www.arduino.cc/en/tutorial/BlinkWithoutDelay


message:
How to make Serial.read() return an integer instead of an ascii value?

I want Serial.read() to return an integer instead of an ASCII value. For example, in the below code if I input 2, I want the output as 2 instead of 50

```cpp
void setup(){
    Serial.begin();
}

void loop(){
    if(Serial.available()){
    int t = Serial.read();
    Serial.println(t);
}
```

body:
If it's a single digit:

```cpp
if (t >= '0' && t <= '9') {
    int numeric_value = t - '0';
} else {
    // Handle the input error.
}
```


body:
You can use an alternate method like this
```
void setup()
{
Serial.begin(9600);
}
void loop()
{
 if(Serial.available()){
    String a = Serial.read();
    int b = a.toInt();
    Serial.println(b);
}
```


message:
.toFloat() giving incorrect anwsers

I am broadcasting a fixed value float over a HC-12 radio which is then received by another HC-12 radio. I am then trying to convert that String to a Float which requires 6 decimal places. However, when I print the String value out and then the Float value out, I get two different answers.

Code:
```
    String lat=getValue(_msg, '|', 6); // Function to get lat value from incoming message
    Serial.println(lat);
    Serial.println(lat.toFloat(), 6);
```
This then results in the following values being displayed to the user:
```
51.507401
51.507396
```
The value 51.507401 is the correct value, so I would ideally like the float value to be the same.

body:
It seems the `toFloat()` method is being a bit sloppy in its conversion.
The float closest to 51.507401 is 51.5074005126953125, which is only
0.13 ulps off. The number you got is the float right before it,
namely 51.507396697998046875, which is 1.13 ulps off. Alas, the
avr-libc functions `atof()` and `strtod()` make the same error.

I would suggest first considering whether the error is really
significant for your application: it is only about 48 cm on the
surface of the Earth. If this level of accuracy is relevant for you,
then follow Majenko's suggestion and use an integer count of
microdegrees.


message:
Is there a variable type of half byte? Is there a workaround?

I have this long array of 64 values going from 0 to 15, values which only cost 8 bits, for a pulse width modulation.

So I made a test to see its cost in space, commenting one of the two arrays.

    const byte wave[64] = {8,9,9,10,11,11,12,12,13,13,14,14,14,15,15,15,15,15,15,15,14,14,14,13,13,12,12,11,11,10,9,9,8,7,7,6,5,5,4,4,3,3,2,2,2,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,7,7};
    //const byte wave[2] = {8,9};
    byte i = 0;
    void setup() {pinMode(1,OUTPUT);}
    void loop() {            //(Don't worry about the code in here,
      analogWrite(1,wave[i]);//it's just to get the program
      i++;delay(1);          //to hold on to the data)
    }

The compiler said `Sketch uses 1112` and `1050 bytes (3%) of program storage space.` or a difference of 62 bytes.

This tells me that one could save a lot of memory by keeping them in a 4-bit or what I'd like to call half byte, going from `0` to `f` rather than from `00` to `ff`.

How could I do so without turning the code to unreadable bit mush?

body:
If the point is to save program storage space, you're probably going to have to live with some unreadable bit mush or do bit-swapping in your head. Here's a code example that encodes your same array as a 32-byte array, but you have to combine pairs of your original numbers into bytes. It's not especially difficult because each hex digit represents one of your original numbers.

I.e., `8,9` becomes `0x89`. Likewise, A is 10, B is 11, etc. Then you can iterate 1 thru 64 and do some division and bit-shifting to pull out the original value you wanted. This will iterate through your 32-byte array and pull out 64 half-byte values.

```
    const byte wave[32] = {0x89,0x9A,0xBB,0xCC,0xDD,0xEE,0xEF,0xFF,0xFF,0xFF,0xEE,0xED,0xDC,0xCB,0xBA,0x99,0x87,0x76,0x55,0x44,0x33,0x22,0x21,0x11,0x11,0x11,0x22,0x23,0x34,0x45,0x56,0x77};
    for(int i=0; i<64; i++) {
        byte val;
        if (i % 2) {
            // the little byte is first (LITTLE ENDIAN)
            val = wave[i/2] & 0x0F;
        } else {
            // the BIG byte is second
            val = (wave[i/2] >> 4) & 0x0F;
        }
        Serial.printf("%i=%i\n", i, val);
    }
```

NOTE: that the [Endianness](https://en.wikipedia.org/wiki/Endianness) if your system may be different than mine. Most systems are little-endian these days, but you never know.


body:
Keeping your 4-bit values in half-bytes is doable using structs and bitfields. You'll want an access function to separate the "array index" into a byte-index and a nibble selector (the LSb of the "array index") and return or store the appropriate nibble.

This [related question on StackOverflow][1] has some answers showing ways to do this. There will be obviously be some overhead to unpacking 4-bit nibbles since they can't be addressed directly, but it will be minor and is the trade-off for saving memory when memory is scarce.

  [1]: https://stackoverflow.com/questions/41918433/is-it-possible-to-use-array-of-bit-fields#41918448


message:
Using Arduino to control a high voltage DC device

I am an amateur hobby electronics enthusiast , and given the situation , I too am trying to make a contactless hand Sanitizing system like everyone else. My project requires a 36V DC solenoid valve to be actuated through the arduino momentarily for the sanitizer to drop. Obviously I will be using a relay module to electrically isolate both the circuits. But I don't have a 36 V DC adapter . So what is the best way to power up the solenoid valve? Batteries are available to me right now? How do I calculate how many 9v batteries do I need ? How many AH would they require ? Would they get drained too fast?

body:
Batteries are going to be annoying because they're run out and have to be recharged/replaced. A mains power supply would be easier to "set and forget.

I did a google search on "36V DC power supply" and found a 4A power supply from "Alitove" on Amazon for $22.99 US. That should be fine. (Assuming you are somewhere with 120VAC mains power. If you live somewhere with 240VAC mains power you would need a different unit, but since I found one, I would expect a google search in your region would find one for your area.)

I would suggest using a logic-level MOSFET transistor + flyback diode to switch your DC power. That's easier to do than a relay (That would require another power supply.)


message:
How to convert Unicode char to “Unicode HEX Position” in Arduino

How to convert Unicode char to "Unicode HEX Position" in Arduino or C

i will share a picture here :

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/YCKAH.png

for example in JavaScript you can do that with `charCodeAt();` ! this function will return exactly the char-code and then you can convert it to hex!

for example in JavaScript i can do that like this to return exact table value

```
 var inpString = 'س';
    var myChar=0;
    var output = 0;
    myChar = inpString.charCodeAt(0);
    output = (ToHex((myChar&0xff00)>>8 )) + (ToHex( myChar&0xff ));

    function ToHex(i)
    {
        var sHex = "0123456789ABCDEF";
        var Out = "";
        Out = sHex.charAt(i&0xf);
        i>>=4;
        Out = sHex.charAt(i&0xf) + Out;
        return Out;
    }
 alert(output);

```

So how can i do that in Arduino ? its using to send unicode char in PDU mode in Arduino
i just need to convert unicode char like this -> 'س' to correct Unicode HEX Position that i shared in the picture above

for example 'س' is 0633 or 'A' is 0041 or 'ب' is 067E

body:
This will read and print unicode characters from/to Serial Monitor and print their HEX codes. Please set the line ending in Serial Monitor to NL and confirm the entered character with Enter.
```
void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available()) {
    char buff[4];
    int l = Serial.readBytesUntil('\n', buff, sizeof(buff) - 1);
    if (l > 0) {
      buff[l] = 0;
      Serial.println(buff);
      Serial.print(buff[0], HEX);
      if (l > 1) {
        Serial.print(buff[1], HEX);
      }
      Serial.println();
    }
  }
}
```


body:
Unlike JavaScript, C++ makes no difference between a character and its
code point. Thus, `'A'`, `0x41` and `65` are just different ways of
writing the same number.

Note, however, that the `char` type is intended to hold ASCII only. For
everything else, you may try using [wide characters][]. For example, the
program

```cpp
void setup() {
    Serial.begin(9600);
    wchar_t c = L'س';
    Serial.println(c, 16);
}

void loop() {}
```

outputs `633` on the serial port. Note the second argument to
`Serial.println()` which specifies base 16. Default is to print
numbers in decimal.

Beware that the representation of wide characters is implementation
defined, and the avr-libc doesn't provide support for manipulating them
or strings made with them. If you want to transmit them, you will also
have to decide for yourself how to break them down into a sequence of
bytes, as that's the only thing a serial port (or I2C, or SPI for that
matter) can transmit. UTF-8 is the most popular choice. I doubt wide
characters are popular in embedded systems at all.

[wide characters]: https://en.wikipedia.org/wiki/Wide_character


body:
A reliable way to output Unicode chars is to use Octal equivalents in the string you are printing.
e.g.

    Serial.print("\342\204\211");

will output ℉ provided the receiver has  font for that unicode.

[Using Non-ASCII chars in Arduino][1]
has a .jar file that converts between Unicode chars, \u... strings and Octal

Hex \x.. is not used because C compilers can get confused if the next character after the two hex digits is 'a' to 'f'. Using octal avoids this problem. The GCC compiler used by Arduino also does not accept all unicode sequences such as \u0020
[![enter image description here][2]][2]

  [1]: https://www.forward.com.au/pfod/ArduinoProgramming/Languages/index.html
  [2]: https://i.stack.imgur.com/rGRFi.jpg


message:
Trying to understand AccelStepper constant speed

I'm starting to learn the AccelStepper library for controlling stepper motors for a project I'm working on. I'm able to get the stepper motors running with the basic examples that use acceleration.

I know for parts or all of project I'll want to use constant speed, so I popped up the constant speed demo: https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library/blob/master/examples/Accel_ConstantSpeed/Accel_ConstantSpeed.ino

```
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myStepper1 = AFMS.getStepper(200, 2);

void forwardstep1() {
  myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper1->onestep(BACKWARD, SINGLE);
}

AccelStepper Astepper1(forwardstep1, backwardstep1);

void setup()
{
   Serial.begin(9600);
   Serial.println("Stepper test!");

  AFMS.begin();  // create with the default frequency 1.6KHz

  Astepper1.setSpeed(50);
}

void loop()
{
   Astepper1.runSpeed();
}
```

(I'm using the adafruit stepper motor wing)

I uploaded it to my arduino and it's working, the shaft is rotating, but it's doing it really slow. I figured this made sense because it's set at a speed of 50, so I tried turning up the speed:

```
Astepper1.setSpeed(200);
```

But the speed still seems to be the same speed. Considering this is a 200 step motor and `setSpeed` is steps per second you'd think this would whip the motor around fairly quick.

I'm positive that this is due to my misunderstanding of how the library works, but I'm having a hard time trying to figure out how to properly use the constant speed methods.

body:
So I ended up doing some source code diving for the AccelStepper library to figure out what the problem was and it turns out there was a missing method call in their example code, specifically a call to `setMaxSpeed` in the setup function:

```
void setup()
{
 Serial.begin(9600); // set up Serial library at 9600 bps
 Serial.println("Stepper test!");

 AFMS.begin(); // create with the default frequency 1.6KHz

 // ! Note that you need to set the max speed, otherwise the stepper motor will
 // ! only step once per interval regardless of what `setSpeed` value you give
 Astepper1.setMaxSpeed(1000);

 Astepper1.moveTo(targetDistance);
 Astepper1.setSpeed(targetSpeed);
}
```

If you look at the `setSpeed` method in the library you'll notice a constraint of the speed value:

[![constraining the speed][1]][1]

The `constrain` method takes in a speed value and then a low and high, which the accelstepper library sets to the private `_maxSpeed` variable. If the speed is outside of that range it will set the value to the low or high value passed in.

[![constrain code][2]][2]

This means, if you don't call `setMaxSpeed` the library will use the default `_maxSpeed` value assigned during construction which issss `1.0`:

[![default max speed][3]][3]

So, to correctly use the constant speed methods, you need to be sure to include a call to `setMaxSpeed` in your code before calling `setSpeed`, likely in the `setup` function.

I also shot a video explanation to share with my co-workers. You can see it here: https://vimeo.com/438272826

  [1]: https://i.stack.imgur.com/2aLkC.png
  [2]: https://i.stack.imgur.com/8MNoN.png
  [3]: https://i.stack.imgur.com/tPfHa.png


message:
How do I generate a graph from Arduino sensor data?

I used a DHT 11 sensor with an Arduino Uno to measure temperature and humidity. I used the following code to print the temperature and relative humidity in Serial Monitor.
```
dht DHT;

#define DHT11_PIN 7

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

void loop()
{
  int chk = DHT.read11(DHT11_PIN);
  delay(1000);
  Serial.print(DHT.temperature);
  Serial.print(" , ");
  Serial.println(DHT.humidity);
  delay(1000);
}
```
The Serial monitor printed the following data values in a list in the order of: time, temperature (Celsius), humidity (percentage).
```
22:17:55.686 -> 25.00 , 55.00
22:17:57.713 -> 25.00 , 55.00
22:17:59.741 -> 25.00 , 54.00
22:18:01.769 -> 25.00 , 54.00
22:18:03.793 -> 25.00 , 55.00
22:18:05.813 -> 25.00 , 54.00
22:18:07.837 -> 25.00 , 54.00
22:18:09.868 -> 25.00 , 55.00
22:18:11.880 -> 25.00 , 55.00
22:18:13.900 -> 25.00 , 55.00
22:18:15.915 -> 25.00 , 56.00
22:18:17.950 -> 25.00 , 56.00
22:18:19.972 -> 25.00 , 56.00
22:18:21.994 -> 25.00 , 56.00
22:18:24.024 -> 25.00 , 56.00
22:18:26.043 -> 25.00 , 56.00
22:18:28.093 -> 25.00 , 55.00
22:18:30.122 -> 25.00 , 55.00
22:18:32.141 -> 25.00 , 55.00
22:18:34.142 -> 25.00 , 55.00
```
I used the PuTTY software to save the sensor data to a CSV file. However, I end up with a few strange numbers at the top before the values start printing properly.
```
25.25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
```
Also, when I open the CSV file in Excel, the time values have disappeared, even though they were there in the serial monitor.
[![Excel Spreadsheet][1]][1]

  [1]: https://i.stack.imgur.com/HTuOI.png

What can I do to get the time stamps to show up in my spreadsheet? Additionally, is there a way I can have the graph automatically update as more data is read?

body:
Perhaps the built-in Arduino Serial Plotter is all you need to visualize your data.  I wrote a [tutorial][1] a while back that might help you.

  [1]: https://www.woolseyworkshop.com/2019/05/03/using-the-arduino-serial-plotter-to-visualize-real-time-data/