body:
I have this code that is working perfectly but I want my device to start vibrating too (right now only the led is working)

On a Wemos Battery Module I have simply connected the vibration motor on the same PIN of the LED and it works perfectly.

Now I want to do the same on an **Beetle ESP32 Microcontroller DFR0575**. I used the same code But I can't make the module vibrating (The led light is working perfectly)

this is the code:

     #include <BLEAdvertisedDevice.h>
       #include <BLEDevice.h>
       #include <BLEScan.h>

       const int PIN = 2;
       const int CUTOFF = -50;

       void setup() {
         pinMode(PIN, OUTPUT);
         BLEDevice::init("tkr");
       }

       void loop() {
         BLEScan *scan = BLEDevice::getScan();
         scan->setActiveScan(true);
         BLEScanResults results = scan->start(1);
         int best = CUTOFF;
         for (int i = 0; i < results.getCount(); i++) {
           BLEAdvertisedDevice device = results.getDevice(i);
           int rssi = device.getRSSI();
           if (rssi > best) {
             best = rssi;
           }
         }
         digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
       }

title: LED and MOTOR "ON" when A BLE DEVICE APPROACH ESP32 MICROCONTROLLER DFR0575

Answers: 1

body:
It is generally very dangerous to drive any motor directly from a digital output pin. Motors often need way more current, than the digital pin can provide. Based on the answer to [this question][1], an ESP8266 can provide 20mA or 12mA depending on current direction (may be a bit different for an ESP32, but not substantially). Drawing more current, than the pin can provide, can lead to the destruction of the output hardware of the pin. It is not easy to say, when this will happen, because it depends not only on the current draw, but also on time and fabrication variation.

Also a motor is an inductive load, which means, that fast changes (for example turning on and off) will induce a reverse voltage in the motor coils. These can easily be very high relative to the supply voltage and thus destroy you output pin or even the complete microcontroller.

I cannot give you a full reasoning, why it works with the first board, but not with the second. I think, it has to do with the above.

You should always do 2 things, when driving motors with a microcontroller:

1. **Use a motor driver circuit:** You can either buy a ready to use motor driver or you can build one yourself. If you only want to turn the motor in one direction (as with a vibration motor), all you need is a MOSFET, which will act as a switch between the motor and the power supply. This switch get's controlled by the Arduino's output pin (which only needs to supply a very low current for switching). You can google "MOSFET as a switch". Be sure to use a MOSFET, that can provide the needed current and that is good in saturation for the used gate voltage (the working voltage of the microcontroller).

2. **Use a flyback diode:** The reverse induction voltage can also hurt MOSFETs. You want to let these voltage spikes quickly plenish by letting the current flow to ground. You can do this with a flyback diode. That is a diode, that bridges drain and source of the MOSFET. It is oriented so that block for normal operation (the normal positive supply voltage). When the MOSFET get's turned off, a great negative voltage will build up in the motor, but since the diode is conducting in this way, the voltage will safely flow to ground, so that the induction voltage cannot hurt the other electronic parts.

  [1]: https://arduino.stackexchange.com/questions/68880/nodemcu-max-draw


body: Im in college and our research is about a fingerprint based door lock system.  We really dont have any idea about arduino.  Now we bought arduino mega for our research but I dont know how to connect all 6 solenoid locks to an arduino.  Please help It would be very much appreciated if you answer and it will be very helpful to us. I know there are same research about this in the internet but  i cant find any of these.  If you have any website about this research it would be very helpful.  Thanks

title: How can I connect 6 solenoid locks to an arduino

Answers: 3

body:
Supposing the lock you use is a simple solenoid that works with 12V, you should connect them to the output of a relay module, and then connect the Arduino to the module. Like this example here: [link.][1]

You will probably want to connect each solenoid to an individual relay, so you can activate each one of them individually. With that in mind you might want to use an 8-channel relay module like [DataFiddler][2] recommended. [example][3]

You will need a 12V power supply, and be sure to check the current drawn from your solenoids and see if the power supply can handle it.

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

  [1]: http://www.arduinotutorialonline.com/2018/05/relay-module-solenoid-door-lock-how-to.html
  [2]: https://arduino.stackexchange.com/users/16780/datafiddler
  [3]: https://www.amazon.com/JBtek-Channel-Module-Arduino-Raspberry/dp/B00KTELP3I/ref=sr_1_3?__mk_pt_BR=ÅMÅŽÕÑ&keywords=8 channel relay module&qid=1569852488&sr=8-3
  [4]: https://i.stack.imgur.com/mo0ih.png

body: You aren't going anywhere without external drivers. The Arduino simply can't output that much current. 8 channel drivers are widely available. Remember to connect an external power source.

body:
To follow up on CrossRoads' suggestion of a power MOSFET circuit, there is more detail on how to do it in an answer over in the Electrical Engineering group. Digikey.com is a great source for components.

https://electronics.stackexchange.com/questions/29065/how-to-control-a-12v-solenoid-valve-with-a-mosfet


body:
I am currently doing a project for a class which uses a few other components such as an LCD, a servo, and such. I want to use a button which acts as a circuit breaker on the Vin of the servo in which the servo will only be powered when the switch is pressed. I wanted to implement something like this because I wanted to minimize the power consumption and also acts as a mechanical counter-measure in case the servo keeps on spinning in unwanted situations, such as having the servo entangled by hair or something like that.

I know that I can just connect the button to the I/O pins but I wanted to rely on a hardware solution for power minimization and safety reason.

The servo draws 170mA when idle and can draw a maximum of 1.2A, but I believe it will only draw about 500-600mA with the intended load. It can run between 4.8-6V.

So my question is, would my circuit configuration work for my application? Would it be safe? Do I need any other additional components? Thanks for anyone that can help!

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

  [1]: https://i.stack.imgur.com/OuiZ9.jpg

title: Push Button to Drive Power to Servo

Answers: 2

body:
Yes, that should be safe, as long as the button can conduct the needed current. That depends on the type of button. You can simply test this. If the button get's hot, it is too small for this.

If it should happen, that the button cannot conduct the needed current, you have 2 ways to go:

1. Just use a bigger button. You can buy buttons, that are meant for mains supply, which will be able to conduct way enough. Every button, that you buy (at least at electronics shops, maybe not on aliexpress or ebay), should have some kind of data sheet, which states the absolute maximums for the electrical characteristics. A maximum current can be found there.
2. You can use a MOSFET (that is capable of providing the needed current) and control it with your button. That would be the way to go, if you really need or want to use this specific button.

body:
There is a chance that this arrangement *could* damage the servo and possibly the Arduino.  The problem is that, depending on the internals of the servo, it could try and draw power for the servo through the data pin when the button is not pressed.  This would both over-stress the internals of the servo and the internals of the Arduino's GPIO pin.

What you could do to mitigate that is to connect the servo's switched power to another GPIO pin of the Arduino, which is set as INPUT.  That will then tell the Arduino when the button is pressed and when it's not pressed. Then you use that information to `attach` and `detach` the servo in your code so it is only being actively driven when the button is pressed.


body:
I am using Tinkercad simulator, but an unusual thing happened. When I connect one wire of dc motor to pin 9 with `digitalWrite(9,HIGH)` and other wire to ground, the motor runs with rpm of 5555.

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

    void loop()
    {
      digitalWrite(9, 1);
    }

 But instead if I connect the other wire to pin 13(say) and set `digitalWrite(13,LOW)` the motor runs at an rpm of 3846.

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

    void loop()
    {
      digitalWrite(9, 1);
      digitalWrite(13,0);
    }

Can anyone explain this?

title: Is digitalWrite(pinnumber,LOW) different from ground pin

Answers: 2

body:
In the real world, either pin sinks current to Gnd via an onchip N-channel MOSFET. They will safely sink 20, 25mA. If your motor allows more than 40mA to flow, you risk damaging the pin and likely the whole chip.

Similarly, either pin can source the same current to a load, likely via P-channel MOSFET, with the same current limitations.

Using both together, you have one transistor sourcing current, one transistor sinking current, so you have twice the Rds (MOSFET on-resistance) limiting current to the load, hence the simulator might have the motor going slower due to less current being available.

body:
Yes, it is different.

First: **Never run a motor directly from IO pins - you will damage your Arduino**. Not only can a real Arduino not supply enough current, but motors generate a lot of back-EMF that will kill an Arduino.

Secondly a pin doesn't connect direct to GND or VCC - it is connected through a MOSFET that performs the switching.  That MOSFET has an ON resistance, which causes a voltage drop across it determined by the current being sourced or sunk through the pin.

You can read more about GPIO pins [here](https://majenko.co.uk/blog/what-exactly-gpio-pin).


body:
Wondering if it's the sensor or the code?  can anyone help?

I've used the code here

    /*
    HC-SR04 Ultrasonic Sensor with LCD dispaly

    HC-SR04 Ultrasonic Sensor
      VCC to Arduino 5V
      GND to Arduino GND
      Echo to Arduino pin 12
      Trig to Arduino pin 13

    LCD Display (I used JHD162A)
      VSS to Arduino GND
      VCC to Arduino 5V
      VEE to Arduino GND
      RS to Arduino pin 11
      R/W to Arduino pin 10
      E to Arduino pin 9
      DB4 to Arduino pin 2
      DB5 to Arduino pin 3
      DB6 to Arduino pin 4
      DB7 to Arduino pin 5
      LED+ to Arduino 5V
      LED- to Arduino GND

    Modified by Ahmed Djebali (June 1, 2015).
    */
    #include <LiquidCrystal.h> //Load Liquid Crystal Library
    LiquidCrystal LCD(11,10,9,2,3,4,5);  //Create Liquid Crystal Object called LCD

    #define trigPin 13 //Sensor Echo pin connected to Arduino pin 13
    #define echoPin 12 //Sensor Trip pin connected to Arduino pin 12

    //Simple program just for testing the HC-SR04 Ultrasonic Sensor with LCD dispaly
    //URL:

    void setup()
    {
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);

      LCD.begin(16,2); //Tell Arduino to start your 16 column 2 row LCD
      LCD.setCursor(0,0);  //Set LCD cursor to upper left corner, column 0, row 0
      LCD.print("Target Distance:");  //Print Message on First Row
    }

    void loop() {
      long duration, distance;
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = (duration/2) / 29.1;

      LCD.setCursor(0,1);  //Set cursor to first column of second row
      LCD.print("                "); //Print blanks to clear the row
      LCD.setCursor(0,1);   //Set Cursor again to first column of second row
      LCD.print(distance); //Print measured distance
      LCD.print(" cm");  //Print your units.
      delay(250); //pause to let things settle
    }

title: HC-SRO4 always returns zero no matter what I do?

Answers: 0


body:
I am trying to connect Logitech F310 gamepad to Arduino Uno with ARDUINO USB HOST SHIELD https://store.arduino.cc/arduino-usb-host-shield using http://github.com/felis/USB_Host_Shield_2.0 library.

The closest is https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/HID/USBHIDJoystick example
After compiling there is no print output in serial window after "Start".
Tried keyboard sketch on same board - it worked.

There is "Mode" button on joystick - by pressing green led is switched ON and OFF.
Behind the joystick there is switch between "X" and "D" .
On "D" green led is working, on "X" - not.

Is this joystick even compatible with HID library? Is there other way how to configure it to USB shield?
Joystick is working on different other devices.

title: Connecting Logitech F310 gamepad to Arduino Uno and Arduino USB Shield

Answers: 1

body:
I found it here : https://github.com/AlanFord/Logitech_F310_and_Arduino
So there is a glitch in library and driver customization was necessary


body:
This question is related to [my other](https://arduino.stackexchange.com/questions/68963/where-is-tcp-h?noredirect=1#comment149299_68963) question, which I already answered.

I want to add modify tcp.c to include my own code. The problem is I can't find tcp.c. The first thing I tried was looking in the same directory as tcp.h (`C:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip\tcp.h`) but there is no tcp.c file there. So then I tried every tcp.h file on my c: drive.

    c:\>dir *tcp.c /s
    c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src
    c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src\SOFTWARE_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\core
    c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src
    c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src\SOFTWARE_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\core
    c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\src\app
    c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\src\core
    c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\builder\glue-lwip

and it's none of those. I assume this because I deleted everything in those files and my program still runs and builds. Now I don't know what to do. Am I right in assuming the file would be called tcp.c? If so why doesn't it seem to be any of the tcp.c files on my computer?

title: Where is tcp.c?

Answers: 0


body:
Disclaimer: It may be that this question belongs to a PHP forum instead of this one. However, this question is _also_ very ESP32/Arduino related. Please correct me if this is the case.

The scenario:

 - Implementing self-update routines for my ESP32 project, using HTTPUpdate
Using a server-side PHP script to decide which binary image to serve to the device, or return HTTP 304 return code if no updates available.
 - Using the sketch's MD5 **and** SHA-256 hashes provided by the HTTPUpdate library as request headers, server-side, to check binary version.

The problem:

 - The MD5 hash contained in the request header "x-ESP32-sketch-md5" _is the same_ as the MD5 hash calculated by a simple ```md5()``` call using the raw binary for the currently running version.
 - The SHA256 hash contained in the request header "x-ESP32-sketch-sha256" **is not the same** as the hash obtained by calling PHP's ```hash("sha256", $v)``` (where ```$v``` contains the same raw binary).

Example:

 - MD5 (HTTPUpdate): c93d814989b53a24a0164e561b6a8bf8
 - MD5 (PHP): c93d814989b53a24a0164e561b6a8bf8 (no difference)
 - SHA256 (HTTPUpdate): 5634674253E095600CD863A34287FCA742BCFCF9B5BF409870DD65AF0ADEF7A0
 - SHA256 (PHP): 1ECDDF3215520C79AAD13BBC1D116D9286910490DF316B9B203FCBFC89CBCCC2 (different)

Am I doing something wrong?

Note: The ```esp_partition_get_sha256()``` function is called internally by the ```update()``` method of the HTTPUpdate library.

PHP Code (for calculating the hashes):
```PHP
<?php

$v = file_get_contents("fw.bin");

print("MD5: ". md5($v)."\r\n");
print("SHA256: ".hash("sha256", $v)."\r\n");
```

Arduino code (the relevant part):
```Arduino
// Called once or twice a day
void update_fw()
{
    Serial.println("Checking for updates...");

    t_httpUpdate_return ret = httpUpdate.update(client, "http://my_server/fw/check_fw.php");  // For now it only logs the headers and returns HTTP 304 code

    switch (ret)
    {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
}
```

PHP code (logs headers and returns HTTP 304 code):
```PHP
<?php

$headers = getallheaders();

if (!file_exists("log.txt"))
{
 file_put_contents("log.txt", print_r($headers, true));
}

http_response_code(304);   // No updates.

exit;
```

Thanks in advance.

title: esp_partition_get_sha256() mismatches PHP's hash() function in HTTPUpdate

Answers: 1

body:
Your problem stems from a misunderstanding of what the functions are doing.

Your MD5 hashes are the hash of the binary file itself. And so they match.

Your PHP SHA256 is the hash of the binary file (like the MD5), but the ESP's SHA256 is not.

The file itself contains an SHA256 hash of the *content* of the file, not the whole file.  The function esp_partition_get_sha256 merely returns that SHA256 hash.

According to the [SDK documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/spi_flash.html):

> For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content. The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID. For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image. For other partition types, the result is the SHA-256 of the entire partition.

If you were to take the binary file and somehow strip off the extra sha256 information and then perform a hash of the results you should (theoretically) get the same hash, which would be the same has as is contained within the file itself.


body:
It's not often I ask a question. This one has me a little stumped though.

Scenario:

I have an 328PB (internal 8mhz), it speaks to a multiplexer on Wire1 (the PB's second IC2 - Minicore lib). The multiplexer speaks to many sensors. That is all working just fine.

I have a logic analyser hooked up to the key points so I can see what is going on.

I have a Nano (external 16mhz) hooked up to Wire (the PB's first I2C), it sends a master request.

The PB is master on Wire1 and slave on Wire.

For some reason the Nano's request on (address 8) is acknowledged by the PB but then the subsequent reads deliver a zero byte and an NACK.

I'm just asking for one byte to troubleshoot. Previous attempts at multiple bytes would deliver the expected bytes but all of them zero.

Strange thing I'm seeing on the logic analyser is that the PB to Multiplexer communication seems to be slower than the Nano to PB (much slower).

I've looked through the libraries and both Wire and Wire1 seem to calculate the speed down to 100khz. I'm using the standard Arduino Wire on the Nano. Given that the initial Address comms gets an ACK. I'm stumped why the subsequent read gets zero and a NACK.

Any help to restore my sanity is much appreciated.
Chances are I'm having a dumb moment. My suspicions are that the clock differences are to blame (but logically they shouldn't be).

----------
Edit:
This is the analyser recording. The dodgy byte is highlighted in Blue.
[![enter image description here][1]][1]

The communication from the Atmega328pb to the multiplexer and then on to the temperature sensor is working fine. Not all of the multiplexer channels have sensors at the moment hence the NACKs but you can see success on channel 1 to the right of the screenshot. The Nano to Atmega328pb communication starts off good but I'm expecting to see 0X41 in the blue box not 0x00.

This is going to end up being something simple, I'm going to kick myself.

Nano code:

```
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);             // start serial for output.
}

void loop() {
  Wire.requestFrom(8, 1);         // request 1 byte from slave device #8
  char c = Wire.read();           // receive a byte as character
  Serial.print("The character: ");
  Serial.println(c);              // print the character
  delay(1000);
}
```
Atmega328pb requestEvent code:

```
void requestEvent() {
  Wire.write("A");
}
```

Edit:
There are other wires for programming etc, but they are disconnected during test.
[![Schematic][2]][2]

  [1]: https://i.stack.imgur.com/AwKTe.png
  [2]: https://i.stack.imgur.com/g1rP4.png

Edit:
I commented out all the usage of Wire1 in the PB code. And the result was that the Nano got it's byte. I wove the usage of Wire1 back into the code. Right up until it was actually active i.e. communicating with the multiplexer. At that point the Nano started getting a zero byte again.

It seems to be when they are both active. Which suggests it is something in the Wire/Wire1 library by Minicore.

I suspect there is something in the registers but scanning the datasheet for the PB is not yielding any insights. Except for this:
26.1 - Device can Operate as Transmitter **or** Receiver

There is no elaboration in the document that I can see.

I've tried staggering the communication so that neither is active at the same time. Still the same result.

Still hoping that someone here has the answer ;-)

title: I2C - Confusion

Answers: 2

body:
I  got it to work ... sort of. I had to move some lines from init to the loop.
I found that by delaying the Wire1 communication (pb to multiplexer) I could get Wire (Nano to pb) to work. Then as soon as the Wire1 communication had *finished* Wire no longer worked. Interestingly Wire continued to work while Wire1 was also active.
This has lead me to believe the end of the Wire1 communication is leaving something in a conflicted state (the events on Wire were not connected any longer). The blunt answer was to re-initialise on each loop. This seems to work but is not particularly elegant.
```
void loop()
{
    Wire1.begin();
    getTemperatures();
    Wire1.end();
    Wire.begin(8);                                               // Join i2c bus 0 with address #8
    Wire.onReceive(receiveEvent);                                // Register event.
    Wire.onRequest(requestEvent);                                // Register event.
}
```
I'm going to continue with this and see if it offers an appropriate degree of reliability. I'm still hunting for the root issue though.

body:
I've been rebuilding using Atmel Studio. After a long time bringing my C++ skills up to scratch I've managed to get it to work very reliably. I like the greater level of control it brings. I suspect that I was trying to do something in Arduino IDE that cannot be done with the Wire library. I had to effectively rewrite the Atmel Start Slave driver  to get it to behave as I expected it to. I have no other experience of using I2C. So I cannot say whether it is the Atmega328pb that is different or not.<br/>
I'm going to stick to Atmel Studio for this project, thanks for all the responses.


body:
I know the title sounds stupid but I never found a question like mine so I wanted to be specific because I downloaded the Arduino IDE to start my first project and I never managed to boot it because nothing happens when I try and I also tried every kind of thing to make it work I could think of. I reinstalled it, downloaded from another link like the zip version and also tried the windows repairtool. I also tried to boot it as admin several times but nothing changed anything. I did all of that yesterday and today when I started the Pc and retried I atleast saw something of a bootingscreen of the app so I thought I just had to restart but then it just went off again and the pain from yesterday began once again.

´´
I own windows 7 64 bit
´´
and tried every download except the one for windows 8.1 and 10

I saw a question about Arduino IDE not starting but this person atleast got any response from the program and the tipp they suggested with the folder in

´´
AppData/Lokal where you delete broken data to reinstall doesnt work too because the arduino folder doesnt even excist in the whole appdata section.
´´

´´
Windows repair tool said the program is not compatible, only in Windows xp (service pack 2) version but in compatibility mode nothing changes
´´

Ok *thew* this question is really long but I gave my best to explain everything I could about my problem so I really hope somebody could help me on my problem so I didnt waste my 45 Euro and time on tech stuff that I cant use

one thing to meantion I have left is that i bought my stuff from a teacher (Erik Verbene) on the internet

but that doesnt matter because it is your program that is not working so
yeah
hope somebody can help me out on this dilemma

title: Arduino wont start up and it wasnt succesfully booted in any time it was downloaded

Answers: 1

body:
The Arduino IDE is written in Java. It's 100% platform independent, so the version that you download makes no real difference.

The most likely culprit is the version of Java that is installed in your computer.  I am not sure off hand what versions of Java the Arduino IDE works with, but for certain version 8 will be your best bet.  Make sure that you have the latest version of Java 8 installed.  If you have any older version installed you should uninstall it and replace it with Java 8.  I'm not sure how the IDE works with newer versions than 8, but removing anything newer than 8 and installing Java 8 may be a good idea.


body:
My project is using a genuine Arduino Mega 2560, probably 3-4 yrs old since purchased (I don't see any revision numbers on the PCB).  It's being used to read a lot of switches, buttons and drive some LED's and displays.

When using a digital pin as INPUT with the internal 10k pullup enabled, do I need to consider the draw with respect to the 200mA total through all pins?  Is it simply the 10k ohm resistor with 5V so 0.5mA?  Can I just ignore it? (there's only so many pins I suspect I can ignore it)

I've seen several posts/pages about driving LED's using transistor arrays powered by an external source and those spec sheets describe the transistor input currents so I can estimate the draws for those elements, but not sure if I need to concern myself with the Arduino pins used as INPUT.

title: Concern myself with current draw from digital pins used as INPUT with internal pullups?

Answers: 1

body:
You are right. The current through digital inputs is so low, that you can normally ignore it.

And the 0.5mA, that you calculated don't flow all the time, just, when the corresponding button is pressed and thus shorted to ground, because only then a current will flow through the pullup resistor. The current into the actual input hardware is even smaller. So, as long as not all buttons are pressed at once, the current will be even lower as calculated.

Buttons are somewhat voltage devices. They don't need a specific amount of current, just of voltage. So the actual value of pullup/pulldown resistors are not critical. LEDs in contrast are current devices. They need a specific current to light up, which is often higher, than the maximum output current of a digital pin. Thus they are often driven with an additional transistor.


body: I’m want to connect 50 LDR to my Mega, I wondering if I use a 2-female pin JST PH connector to connect the LDR, how can I link 2-pin male JST PH connector board to the Mega and does this board exist?

title: Connecting 2-pin JST PH connector to Arduino Mega

Answers: 1

body:
There exists 2.00 to 2.54mm adapters, like in [this link][1].

They look like below (example of 1.27, 2 and 2.54mm):

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

  [1]: https://www.gorilladistribution.com.au/product/8-pin-adapter-board-1-27mm-2-0mm-2-54mm/
  [2]: https://i.stack.imgur.com/akvfJ.jpg


body:
I want to take audio signal through mic connected to Arduino and then transfer it to PC using BT module. I want to do it with BT (HC05) and Arduino Mega. I need audio packages at 44 KHz and 24-32 bits per sample.

Can I use AudioInI2S library to receive audio samples? Does HC05 support this type of communication?

I want to save and analyze the audio samples later on. I have worked on Arduino before but I am totally new to audio streaming and I am not sure where to begin from. Any guidance would be appreciated.

title: Audio Recording using Arduino BT module

Answers: 1

body:
In short: No and no.

----

> Can I use AudioInI2S library to receive audio samples?

No.  The library is not for the Mega:

> This library provides simple way to play and analyze audio data using Arduino on SAMD21 based boards (i.e Arduino or Genuino Zero, MKRZero or MKR1000 Board) using the I2S bus.

----

> Does HC05 support this type of communication?

No.  The HC05 is a serial module. It works at baud rates that are far to low to transfer the data in a timely fashion, and can't send data in a form the PC sees as audio (so you'd need to write your own translation software to convert serial data into an audio file).

----

> Any guidance would be appreciated.

Just buy a cheap bluetooth headset.


body:
I would like to use the DMP of the MPU9250 with my BTLE Feather board but the docu of the [official library][1] says that only SAMP-Processors are supported.

Is the a different library I can use?

  [1]: https://github.com/sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library

title: Is there a library for non-SAMD Arduinos to use the DMP on MPU9250

Answers: 1

body:
I did have a look at the MPU9250 DMP library provided by Sparkfun and it seems that it is specifically built for their own board which has an M0 chip on the board. However looking at the library, there seems to be no reasons why it would not work with any other board. The main reason why it might not work with something like the 32u4 board would be because the end firmware is too large or the program need too much RAM that what the 32u4 has.

There is a fix provided on the github issues page for using it with a Nano, which might help you get it work with the 32u4 [here](https://github.com/sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library/issues/11#issuecomment-449472273) and there is another library [here](https://github.com/kharlashkin/MPU-9250DMP) that you might be able to use or build up on.

However the best way might be to use a M0 chip itself if you really want to use the same IMU since getting the library to work can turn out tricky. Adafruit does sell a M0 with a Bluetooth board [here](https://www.adafruit.com/product/2995) that you might be able to use.


body:
I've been trying to write a small i2c lib in C over the past week. I managed to get writing to slaves working (for example I can write to an ssd1306 oled) but reading (for example date/time from an ds3231) never works as my slaves don't seem to set SDA high when I request bytes.

```c
uint8_t
i2c_read(uint8_t ack)
{
 uint8_t i, val;

 val = 0;
 cbi(SCL);
 DDRB &= ~(1 << SDA); /* Use SDA for input. */
 cbi(SDA); /* We need to pull down SDA to receive input. */

 /* Read 8bit from the slave. */
 _delay_us(DELAY);
 for (i = 0; i < 8; ++i) {
  sbi(SCL); /* Request one more bit. */
  _delay_us(DELAY); /* Wait a little so the slave can send his answer. */
  if (PORTB & (1 << SDA)) { /* Here the slave should have set SDA to 1 but it never does. */
   PORTB |= (1 << PB4);
   val = (val << 1) | 1;
  } else {
   val = (val << 1);
  }
  cbi(SCL);
  _delay_us(DELAY);
 }

 /* Send back an ACK or NAK. */
 DDRB |= 1 << SDA; /* Use SDA for writing. */
 if (ack)
  cbi(SDA); /* Set SDA to 0 to send ACK. */
 else
  sbi(SDA); /* Set SDA to 1 to send NAK. */

 sbi(SCL);
 _delay_us(DELAY);
 cbi(SCL);
 cbi(SDA);

 return val;
}
```

I set PB4 with to 1 when a slave actually sends a 1. Apparently that never happens.
I also had a look at how the various other libs out there do it but I didn't spot anything that would make a difference.

Any clues on what I migth be missing? Before reading my program sends the slave address to the bus. Also: please don't tell me to use other libraries since this is a learning project.

title: Receiving i2c bytes on an attiny85

Answers: 1

body:
Not sure, if this is the only problem, but you are reading from the wrong register.

There are 3 registers associated with a digital output pin: DDR, PORT and PIN. To read a pin, you need to read from the PIN register. Currently you are reading the PORT register, which will only ever have the value, that you set it to (zero in this case, because you cleared the bit beforehand with `cbi(SDA);`). When you configure the pin as input with the DDR register, the PORT register determines, if the internal pullup resistor is activated or not, so it cannot reflect the actual state of the pin. For this you need the PIN register.

---

Besides that, you might want to look into another thing, that might or might not be a problem in your case: I2C is an open drain bus, meaning, that it is driven actively low and passively high (through pullup resistors). I guess you already have external pullup resistors on your lines, so that you really can deactivate the internal pullup without breaking the communication. But imagine the following situation: The slave get's a request, but cannot clock it out that fast (for whatever reason). It can pull the clock to LOW, until it is ready to push out the data bit, slowing down the clock speed. (This can be done for every bit, unless you are in highspeed mode, then only before the start of a new byte). (This behavior is called clock stretching - Thanks to Edgar for the information) You don't monitor the line, so it can happen, that you drive the clock line actively to high, before the slave has released it. This results in a significant current between master and slave, since the master drives actively high and slave actively low.

There are implementations of I2C communication, that are just doing that and are working fine in most situations. I just wanted to give you this information. And if you at some point want to implement bus arbitration (to allow a multi-master setup), you definitely need this open drain behaviour.


body:
I'm trying to understand the logic for one of the example Arduino programs for the MPU6050 IMU module. The entire program can be found [here][1].  There is an if() statement inside a while() loop inside the normal Arduiono sketch loop() function, and I'm having real trouble figuring out the logic.  The ISR and relevant code section is shown below:

    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady()
    {
     mpuInterrupt = true;

    }

        void loop()
        {
         // if programming failed, don't try to do anything
         if (!dmpReady) return;

         // wait for MPU interrupt or extra packet(s) available
         while (!mpuInterrupt && fifoCount < packetSize)
         {
          if (mpuInterrupt && fifoCount < packetSize)
          {
           // try to get out of the infinite loop
           fifoCount = mpu.getFIFOCount();

           //pulse the pin
           digitalWrite(Loop_While_Section_Pin, HIGH);
           delay(1);
           digitalWrite(Loop_While_Section_Pin, LOW);
          }
          // other program behavior stuff here
         }

         // reset interrupt flag and get INT_STATUS byte
         mpuInterrupt = false;
         mpuIntStatus = mpu.getIntStatus();

         // get current FIFO count
         fifoCount = mpu.getFIFOCount();
         if (fifoCount < packetSize)
         {
          //Lets go back and wait for another interrupt. We shouldn't be here, we got an interrupt from another event
          // This is blocking so don't do it   while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
         }
         // check for overflow (this should never happen unless our code is too inefficient)
         else if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
          // reset so we can continue cleanly
          mpu.resetFIFO();
          //  fifoCount = mpu.getFIFOCount();  // will be zero after reset no need to ask
          Serial.println(F("FIFO overflow!"));

          // otherwise, check for DMP data ready interrupt (this should happen frequently)
         }
         else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT))
         {
          // read all available packets from FIFO
          while (fifoCount >= packetSize) // Lets catch up to NOW, in case someone is using the dreaded delay()!
          {
           mpu.getFIFOBytes(fifoBuffer, packetSize);
           // track FIFO count here in case there is > 1 packet available
           // (this lets us immediately read more without waiting for an interrupt)
           fifoCount -= packetSize;
           //digitalWrite(Loop_ReadBytesSection_Pin, !digitalRead(Loop_ReadBytesSection_Pin)); //toggle the pin

           //pulse the pin
           digitalWrite(Loop_ReadBytesSection_Pin, HIGH);
           delay(10);
           digitalWrite(Loop_ReadBytesSection_Pin, LOW);
          }

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
          // display Euler angles in degrees
          mpu.dmpGetQuaternion(&q, fifoBuffer);
          mpu.dmpGetGravity(&gravity, &q);
          mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
          Serial.print("ypr\t");
          Serial.print(ypr[0] * 180 / M_PI);
          Serial.print("\t");
          Serial.print(ypr[1] * 180 / M_PI);
          Serial.print("\t");
          Serial.println(ypr[2] * 180 / M_PI);
        #endif

        // blink LED to indicate activity
          blinkState = !blinkState;
          digitalWrite(LED_PIN, blinkState);
         }
        }

  It appears that the only way the 'if()' condition can be met is if the 'mpuInterrupt' variable managed by the ISR changes from FALSE to TRUE between the 'while()' condition evaluation and the 'if()' condition evaluation, which doesn't make a whole lot of sense to me.  In addition, the 'fifoCount' variable is only incremented inside the 'if()' section, which makes the second half of both the 'while()' and 'if()' conditions a little strange too.

I do want to note that this example program DOES WORK, and if I instrument the 'if()' section to pulse a hardware pin whenever it executes, I do see pulses following many (but not all) hardware interrupt occurrences.  So I know for sure the 'if()' statement DOES execute - but this seems a very 'Rube Goldbergian' way to go about it.

Any illumination would be appreciated ;-).

  [1]: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050/examples/MPU6050_DMP6

title: How does this MPU6050 Example Code Work?

Answers: 0


body:
I'm coding a music sampler device: for fast playback / minimal latency (only a few milliseconds), it's better to have all audio .wav samples we want to use in RAM, so that when some of them are  played, the data arrays are immediately accessible. That's what I did for a Raspberry Pi project called [SamplerBox](http://www.samplerbox.org). It was possible because RPi had 1 GB RAM.

Note: When using SDcard reading, and playing many notes at the same time (imagine a pianist playing a big chord), it's usually not good in terms of latency.

Now I'm thinking about porting this project to Arduino: in which extent can we add external RAM to an ATmega? Or if not "RAM", some volatile memory (let's call it "RAM2") that would be 10 times faster than reading an SD card.

What I'd like to achieve:

* load 200 MB of audio samples into the "RAM2"

* Max polyphony allowed = 100, so at a given time, all audio buffers that have to be mixed can be copied from "RAM2" to the "real" RAM of the microcontroller, and the mixing will be done with the (maximum 100 of them) buffers in the real RAM

title: Is there a way to add external RAM (let's say 100 MB or 200 MB) in this audio buffer mixing context?

Answers: 2

body:
There are SRAM ICs / boards, however, don't expect 100 MB, more like 1 MB (with the pin numbers and connectivity / protocols that an Arduino offers).

With Flash you can get much further, but it can only be written a number of times; not sure if that suits your requirements.

Beyond that, I'm afraid the real problem is in the processing speed. Mixing 100 samples with 48 KHz stero would mean (48000 * 2) = 96 KSamples/s. Since the Arduino is only 16 MHz you have just 16e6/96e3 = 166 clock cycles to mix all those 100 samples. Probably way too less.

**Update**

Winbond is a brand that is supported by Arduino libraries and the biggest supported IC is e.g. W25Q128FVSSIG, which is 128 Mbit, thus 8 MB. For 200 MB you need 25 of them which is quite a lot, and not sure if there will be issues using so many (let alone the cost). For this you do not need a file system, however you need to write it per page (if you want to do it efficiently). Which should be ok, since the SD card also is read per page (maybe not the same page size though).
However, you still have to copy the Flash memory into SRAM to be able to process it, so it's not the same as SRAM. Getting 200 MB SRAM will be very costly.

body:
I'd also suggest looking into different microprocessors. The Teensy models often have an SD card socket, and the Teensy 4 (especially if they release one with a built-in SD socket) is extremely fast and capable (600MHZ, dual instructions/cycle). That would be far better suited than an Arduino, though you'll still have RAM limits. (Nowhere near 200 megs, but you'd have slightly less of an issue than with the Arduino's mere 2-8K of RAM. These have a few hundred K up to maybe a couple MB (note that I'm not sure if it actually goes that high))

There's also the RPI Zero, Zero W, and Compute Module to try using. Those are the Raspberry Pi system you are used to using at a low-ish cost or easily-integrated form factor.

In short, to do audio processing, you also need a better processor than a stock Arduino probably has. Lots of RAM is the easy-to-see issue, but having the computing power to do something with it is also important.

Do note that the Winbond chips mentioned in the other answer ARE a flash memory, so they may go bad on you if they see a lot of writes.


body:
I am having some trouble doing a GET request over HTTPS on the ESP32. I am using the `BasicHttpsClinet` example from the ArduenoIDE. Here is the code.

    /**
       BasicHTTPSClient.ino

    Created on: 14.10.2018

    */

    #include <Arduino.h>

    #include <WiFi.h>
    #include <WiFiMulti.h>

    #include <HTTPClient.h>

    #include <WiFiClientSecure.h>

    const char* rootCACertificate = \
    "-----BEGIN CERTIFICATE-----\n"\
    "super_secret certificate"\
    "-----END CERTIFICATE-----";

    // Not sure if WiFiClientSecure checks the validity date of the certificate.
    // Setting clock just to be sure...
    void setClock() {
      configTime(0, 0,"cn.pool.ntp.org", "pool.ntp.org", "time.nist.gov");

      Serial.print(F("Waiting for NTP time sync: "));
      time_t nowSecs = time(nullptr);
      while (nowSecs < 8 * 3600 * 2) {
        delay(500);
        Serial.print(F("."));
        yield();
        nowSecs = time(nullptr);
      }

      Serial.println();
      struct tm timeinfo;
      gmtime_r(&nowSecs, &timeinfo);
      Serial.print(F("Current time: "));
      Serial.print(asctime(&timeinfo));
    }

    WiFiMulti WiFiMulti;

    void setup() {

      Serial.begin(115200);
      // Serial.setDebugOutput(true);

      Serial.println();
      Serial.println();
      Serial.println();

      WiFi.mode(WIFI_STA);
      WiFiMulti.addAP("Master_2.4G", "wittyercheese551");

      // wait for WiFi connection
      Serial.print("Waiting for WiFi to connect...");
      while ((WiFiMulti.run() != WL_CONNECTED)) {
        Serial.print(".");
      }
      Serial.println(" connected");

      setClock();
    }

    void loop() {
      WiFiClientSecure *client = new WiFiClientSecure;
      if(client) {
        client -> setCACert(rootCACertificate);

        {
          // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
      HTTPClient https;

      Serial.print("[HTTPS] begin...\n");
      if (https.begin(*client, "https://my_end_point.com/something_or_other")) {  // HTTPS
        Serial.print("[HTTPS] GET...\n");
        // start connection and send HTTP header
        int httpCode = https.GET();

        // httpCode will be negative on error
        if (httpCode > 0) {
          // HTTP header has been send and Server response header has been handled
          Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
            String payload = https.getString();
            Serial.println(payload);
          }
        } else {
          Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        }

        https.end();
      } else {
        Serial.printf("[HTTPS] Unable to connect\n");
      }

      // End extra scoping block
    }

    delete client;
      } else {
        Serial.println("Unable to create client");
      }

      Serial.println();
      Serial.println("Waiting 10s before the next round...");
      delay(10000);
    }

I am getting the following when I run the sketch

    [HTTPS] GET... failed, error: send header failed

Guessing this is related to the issue reported here: https://github.com/espressif/arduino-esp32/issues/2670

I tried updating my esp-arduino libraries( to get the latest code with the fix mentioned in the Github issue) by redoing the steps from here: https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/mac.md#installation-instructions-for-mac-os

But I still get the same issue error.

I have double-checked my server, I know that the esp32 has not managed to make it to the endpoint yet.

I have tested the GET endpoint in my browser and it works fine. I have compared the certificate to the one hardcoded in the sketch file. They match.

How do I update my arduino-esp32 libraries to get the fix mentioned in the GitHub issue?

title: Trouble GETing over HTTPS on the ESP32

Answers: 0


body:
Does anyone know if there's an HCI command for setting the TX and the advertising power for BLE on an ESP32?

I have a Nano 33 IoT and a MKR 1010, and it has its power set annoyingly low for advertising and transmission.  The library that I'm using is [ArduinoBLE][1], which uses HCI to communicate with the ESP32.

I believe that espressiv allows the power level to be set using their dev kit, and I know that other vendors (e.g., [TexasInstruments][2]) provide extensions to HCI for setting power levels, but I haven't been able to find an HCI command for ESP32 anywhere.

Any ideas on other ways that I could do this other than HCI would be welcome too (e.g., other libraries for BLE that would work with the MKR and Nano series of boards, but would allow setting the power level for advertising and transmission.

  [1]: https://github.com/arduino-libraries/ArduinoBLE
  [2]: http://dev.ti.com/tirex/content/simplelink_cc26x2_sdk_2_10_00_44/docs/ble5stack/vendor_specific_guide/BLE_Vendor_Specific_HCI_Guide/hci_interface.html

title: ESP32 HCI command for setting BLE TX Power

Answers: 0


body:
I am trying to read the analog signal from a Pfeiffer TPG 261 Single Gauge (https://www.idealvac.com/files/brochures/Pfeiffer_Single_Gauge_TPG261.pdf)

The pin assignment of the connector I am using is the following:

[![RS232Pinassingement][1]][1]

Here is the circuit I have built:

[![BreadboardConnection][2]][2]

And here is the code used:

    int pressureSensorPin = A0;

    int analogValueP = 0;

    void setup(void)
    {
      Serial.begin(9600);
    }
    void loop()
    {
      analogValueP = analogRead(pressureSensorPin);
      Serial.println(analogValueP);
      delay(1000);
    }

Unfortunately the ouput I get with such a build is only 0 with now and then a 1023.

Any idea of what I am doing wrong ?

  [1]: https://i.stack.imgur.com/KfCBD.png
  [2]: https://i.stack.imgur.com/7XRfm.png

title: Pressure Gauge analog reading via RS232

Answers: 1

body:
You have a misconception, which signals get's outputted where. If you want to simply read the analog signal of the sensor, you need to use the "control" connector. There you can find the analog signal on pin 2. But this analog signal goes up to 10V, so you need a voltage divider between the sensor and the Arduino, to divide the voltage down to 5V max.

Currently you are using the RS232 connector. RS232 is a communication standard, which transmits digital data, not analog data. Thus you read only digital values (min voltage and max voltage, nothing inbetween). You can use it do talk with the sensor, change configuration settings and reading data digitally. But to actually do this, you need to consider 2 important things:

1. RS232 is an interface, which involves it's own voltage levels (namely +-12V), which do not fit the TTL level (0 - 5V) that the Arduino Uno uses. You can very well destroy your Arduino by connecting it directly to RS232. For making this work, you need a level converter chip (I think the MAX232 is commonly used for this), to convert the voltage levels to TTL logic. From there on this communication is normally called UART.

2. You need to understand and then implement the sensors communication protocol (when to send what data), so that the sensor and Arduino are understanding each other

---

For me it seems, that the analog signal from the "control" connector is all, that you currently need, so for simplicity you can use this. RS232 is used for more control over the functionality of the sensor.


body:
Following is the zabbix documentation with the query header format.
[Document Zabbix][1]

I have difficulty implementing this header in C ++ (Arduino),

I saw an implementation of what I need in this forum [here][2] , however it is in Russian and is implemented in C #, I tried to translate it but to no avail.

So I need someone to help me write the function of the header examples in C ++ (Arduino).

  [1]: https://www.zabbix.com/documentation/4.4/manual/appendix/protocols/header_datalen
  [2]: https://www.zabbix.com/forum/in-russian/20295-zabbix_sender-net-готовый-пример-на-c?t=20047

Follows full Arduino code after @EdgarBonet change suggestion

```c++
#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>

// Config IP
IPAddress ip(192, 168, 0, 130);
IPAddress gw(192, 168, 0, 1);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
float contador = 0;

EthernetClient client;

//Config Server address
const char* server = "192.168.0.135";
int porta = 10051;

void setup() {
    Serial.begin(9600);
    Ethernet.begin(mac, ip);
}

void loop() {
    // Begin Json
    const size_t capacity = JSON_ARRAY_SIZE(1)
                          + JSON_OBJECT_SIZE(2)
                          + JSON_OBJECT_SIZE(3);
    DynamicJsonBuffer jsonBuffer(capacity);

    JsonObject& root = jsonBuffer.createObject();
    root["request"] = "sender data";

    JsonArray& data = root.createNestedArray("data");

    JsonObject& data_0 = data.createNestedObject();
    data_0["host"] = "ethernet";
    data_0["key"] = "variavel1";
    data_0["value"] = contador;

    String json = "";
    root.printTo(json);

    const uint8_t *dataSend = (const uint8_t *) json.c_str();
    uint64_t data_length = json.length();
    uint8_t packet[13 + data_length];  // 13-byte header + payload

    // Write the 5-byte signature.
    memcpy(packet, "ZBXD\1", 5);

    // Add the 8-byte packet length, LSB first.
    for (int i = 0; i < 8; i++) {
        packet[5+i] = data_length >> 8*i;
    }

    // Add the payload.
    memcpy(packet + 13, dataSend, data_length);
    if (client.connect(server, porta)) {
        Serial.println("Enviando ao servidor");
        delay(1000);
        // Send the packet.
        client.write(packet, sizeof packet);
        delay(1000);
        contador ++;
    }
}
```

Following server response:

    2034:20191003:101411.196 Message size 2066888786 from 192.168.0.130 exceeds the maximum size 1073741824 bytes. Message ignored.

title: Code conversion

Answers: 1

body:
The problem is quite explicit in the error message:

> expected 808529969 bytes

You told the server that you were going to give it 808529969 bytes, yet
you provided much less. Why did you tell it you were going to send so
much data? Maybe we can get a clue by rewriting this number in
hexadecimal:

808529969 = 0x30313031

Breaking this into individual bytes, LSB first (as this is how the
server expects it), you have

0x31 0x30 0x31 0x30

These are the bytes you sent to the server, and they all happen to be
ASCII codes for digits, which make up the string "1010". I don't know
how you came up with this, as the code you posted is not the one you
tested (the posted code does not even compile!). But it seems at one
point you tried to convert something to ASCII binary, and indeed
`String(10, BIN)` produces exactly the string above.

The server expects the data length to be provided as binary bytes,
**not** as an ASCII string. I personally try to avoid the `String`
class, which can create memory issues. In this situation I would just
work with an array of bytes, typed as `uint8_t` (the same as the Arduino
`byte` type, only more standard). In the code below, I assume for
simplicity that you keep a `String` for building the payload, but then I
switch to a raw byte array:

```c++
const uint8_t *data = (const uint8_t *) json.c_str();
uint64_t data_length = json.length();
uint8_t packet[13 + data_length];  // 13-byte header + payload

// Write the 5-byte signature.
memcpy(packet, "ZBXD\1", 5);

// Add the 8-byte packet length, LSB first.
for (int i = 0; i < 8; i++) {
    packet[5+i] = data_length >> 8*i;
}

// Add the payload.
memcpy(packet + 13, data, data_length);

// Send the packet.
client.write(packet, sizeof packet);
```

Note that when working with binary, rather than text data, you have to
use `memcpy()` instead of `strcpy()`, and `client.write()` instead of
`client.print()`.


body:
I had an Esp8266 esp01 module programmed to log onto the router and post data.  It worked fine for a few months but all of a sudden it kicks everyone else off the router.

Actually as soon as I connect the Esp and it connects to the ssid, it kicks off my laptop (laptop can no longer even see the ssid) and I see my Google home drop it's connection as well.  It's almost immediate, about 20 seconds after powering up my esp.  Seconds after I unplug the Esp google home comes back on and my laptop sees the ssid again.

What should I check for in my router?  It's a tplink tr-wl945N.

title: Esp8266 esp01 kicks other devices off tplink router

Answers: 0


body:
I have been attempting to read data from an ATTINY84 via an ESP8266. Both are programmed via the Arduino IDE, though as PlatformIO is a proxy for that, I'm not certain what version of the ATTINY core is in use.

I have both devices connected to the I2C bus, with the Arduino as a slave.
The ESP sends a code requesting a particular type of data, then calls Wire.requestFrom() to get 8 bytes of data. I am concerned over both my implementation and about potential endian-ness issues (even if it should turn out not to be an issue on these two particular devices, I'd like to know my future options).

The ATTINY code is a complex function that is called when there is a request (and the right option code, but that's probably not very relevant). It writes eight bytes using Wire.write after uncompressing them from the relevant arrays. (I have a lot of ADC data that technically should not fit in RAM.)
Since this is is a callback function or possibly an interrupt, **do I need to be concerned about data corruption if the code is too slow to write the values onto the bus**? I have to imagine it's trying to read them even as it writes. I can also provide code snippets if it would help.

----------

I am also unsure if I am running into Endian-ness issues by using bitshift to grab the 2 and 8 bits from the ADC return value. Would this always give me the correct values, or does the C++ compiler (as I assume it does not) simply refuse to handle differences between the data order?
**Specifically, if I shift a uint16_t (or any non-trivial datatype) right by 8 bits, and mask out the bottom 8 with &0xFF, do I *always* get the second-least-significant (in this *particular* case, high) byte, or can the compiler produce alternate outputs based on byte order?**

Does Arduino have an equivalent of network byte order (or does Wire automatically do so for its overrides of the functions) that I can get around this potential issue with?

title: Sending multi-byte data over I2C between different processors

Answers: 1

body:
There seems to be multiple questions in what you are asking. Here I try
to answer specifically this one:

> if I shift a `uint16_t` (or any non-trivial datatype) right by 8 bits,
> and mask out the bottom 8 with `&0xFF`, do I always get the
> second-least-significant (in this particular case, high) byte, or can
> the compiler produce alternate outputs based on byte order?

Short answer: yes, you get the second-least-significant byte,
irrespective of the platform's native endianness.

Now, I'll expand on this answer by showing the different ways you
can convert an `uint16_t` to a sequence of bytes, and the implications
on the byte order.

If you want to control the endianness, and you want your code to work
independently of the native endianness of the platform, then bit
shifting is the way to go. Let's assume you want to convert this:

```c++
uint16_t data;
```

into this:

```c++
uint8_t bytes[2];
```

You can do it this way in order to get the least significant byte first:

```c++
bytes[0] = data >> 0;  // least significant byte
bytes[1] = data >> 8;  // most significant byte
```

Or you can instead do the assignments the other way around
(`data >> 8` goes to `bytes[0]`...) if you want MSB first. Note that
there is no point in masking, as the assignment does it implicitly.

In contrast, if you wanted to put the bytes in _native_ endianness (the
endianness of the platform), the traditional way to do it is to cast the
address of the number to a pointer to bytes, then read from this
pointer:

```c++
bytes[0] = ((uint8_t *) &data)[0];  // first byte
bytes[1] = ((uint8_t *) &data)[1];  // last byte
```

You can swap the indices on one side of the assignments if you want to
instead reverse the byte order. But note that this kind of casting is
now frowned upon, as it violates aliasing rules. A common alternative is
to have the number and the byte array share the memory within an
`union`:

```c++
union {
    uint16_t data;
    uint8_t bytes[2];
} x = { .data = some_16_bit_value };
do_something_with(x.bytes[0]);  // use first byte
do_something_with(x.bytes[1]);  // use second byte
```

These are the main byte-splitting idioms you may come across. If your
purpose is to have an endianness that you control and is independent of
the platform, then stick with the first option: the old good bit
shifting.


body:
So I have an Arduino Nano powered in parallel with an ESP-01 (for the ESP there is an extra LM1117-5.0 voltage regulator in series).

    +12V ---------+---------+
                  |         |
                 Reg        |
                  |        NANO
                 ESP        |
                  |         |
     GND ---------+---------+

My problem is that after a while, the Nano burns (my guess is the difference in current that both devices draw).

In any case, what could be the reason and what could I do to fix it?

Thanks!

title: Arduino Nano burns with ESP-01 in parallel

Answers: 2

body:
Use the 5v regulator to power both the ESP and the Nano. Those onboard regulators have minimal heat dissipation and if they burn out you lose the whole Nano. Check how hot your external regulator gets and mount it on a heat sink if it gets too hot to touch.
NB Connect the regulator output to the Nano 5v pin directly

body:
12V is the upper limit for input voltage on an Arduino. With a 12V input the regulator has to convert 12-5, or 7 volts, to heat. (That's how linear voltage regulators work.) As the other poster said, Arduinos don't have much heat dissipation on their voltage regulators.

Like jksemple, I would suggest powering both the ESP and the Nano from the external regulator (You might want to cut a USB cable and wire it to your external voltage regulator, then plug it into your Nano. That way you're not bypassing the power control circuits on the Nano.

By the way, did you build a full voltage regulator with the LM1117 chip? You need some extra components like capacitors and resistors to complete the voltage regulator.

Finally, you might think about using a DC-DC buck converter rather than a linear regulator. That will run a lot cooler and waste a lot less power.


body:
I just bought an ESP8266 ESP-07 V1.0 Serial Wifi Transceiver. Similiar to this: https://www.ebay.com/itm/ESP8266-Serial-Wifi-Transceiver-Module-for-Arduino-ESP-07-V1-0-New-/331868488091

I have connect the RX and TX pins to the RX and TX pin of the Arduino (RX to TX and TX to RX), VCC is connected to 3.3V and GND is connected to Arduino ground.
I have used the following code and writing commands to the module using the serial monitor:

    #include <SoftwareSerial.h>

    int RX_PIN = 3;
    int TX_PIN = 4;

    SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX

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

        while (!Serial){
        ;
      }

        while (!mySerial){
        ;
      }
      Serial.println("Ready");
    }
    void loop()
    {
        // listen for communication from the ESP8266 and then write it to the serial monitor
        if ( mySerial.available() )   {  Serial.write( mySerial.read() );  }

        // listen for user input and send it to the ESP8266
        if ( Serial.available() )       {  mySerial.write( Serial.read() );  }
    }

Whatever I type (for example AT+GMR) in the serial monitor at 9600 baud I don't get any response. What could be the reason? Both NL and CR is added to the command.

When pressing reset on the ESP-module I get this in the Serial monitoring:

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

Thanks for any help!

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

title: ESP8266 ESP-07 does not respond to commands

Answers: 1

body:
The esp8266 is without AT firmware. Even with SoftwareSerial at 115200 baud you should see "ready" from AT firmware and get some response to AT commands.

This esp8266 module adapter is simple to flash. It makes the 5 V to 3.3 V conversion for power and RX pin and has a program switch (io 0) and a reset button to put the esp8266 into flashing mode.

Use an USB-to-TTL-Serial adapter or an Arduino with USB chip to connect the adapter to PC. Then switch to "program" and reset it and it will be in flashing mode.

You can download the AT firmware [here][1]. I recommend ESP8266 NonOS AT Bin V1.7.1. Don't try 2.0, it is very different (ESP32 AT firmware build for esp8266).

To flash it, use [esptool][2]

The command to flash the AT firmware binaries to any module with at least 1 MB flash memory is:

    esptool.py write_flash --flash_size 2MB-c1 0x0 boot_v1.7.bin 0x01000 at/1024+1024/user1.2048.new.5.bin 0x1fb000 blank.bin 0x1fc000 esp_init_data_default_v08.bin 0xfe000 blank.bin 0x1fe000 blank.bin

don't wonder about the 2MB-c1 setting and don't change it. The AT binaries are build for 2MB-c1 partitioning. On 1 MB flash it will not support AT firmware OTA update.

If you want to use the [Espressif Flash Download Tool][3], use the same settings as on esptool command line.

  [1]: https://www.espressif.com/en/support/download/at
  [2]: https://github.com/espressif/esptool#installation--dependencies
  [3]: https://www.espressif.com/en/support/download/other-tools?keys=&field_type_tid[]=14


body:
When trying to compile

    #include <list>
    std::list<byte> l = { 7, 5, 16, 8 };

in the Arduino IDE (with [ATtinyCore](https://github.com/SpenceKonde/ATTinyCore) for ATtiny4313), I get this message:

> error: list: No such file or directory
  #include <list\>

**How to use the standard C++ `std::list` with Arduino/ATtiny?**

title: Use std::list in Arduino programming

Answers: 2

body:
I don't think that this library is supported by attiny (or even Arduino in general).

However, beyond that, it is not advised to use it, since it is uncertain how much memory and flash overhead it consumes.

Especially the memory is an issue for two reasons:

- Internally, you don't know the exact data structures used for the list. In most efficient way, it will only use 4 bytes (4 times 1 byte for the array), however, since it is a class under the hood a vtable is added, and who knows what more memory (maximum capacity, current capacity of the list etc).
- Also when adding/removing an item from the list, either the entire list is copied, or some tricks with pointers are used. In the first case you get memory gaps, in the second case maybe (and additional memory for the pointers is used).

My advice is to use just a simple array, and define a maximum of the array at compile time (if possible). Not as flexible, but robust, less memory usage and more reliable with a low SRAM  device like the Attiny (and Arduino in general).

**Removing elements**

Based on your first comment:

Removing items is indeed an issue, however, note that if you use the standard library it might copy the entire array (excluding) the new item, so temporarily you will have double the array AND a memory gap.

There are some ways to implement it yourself:

- If you only want to remove items (and never add), add a new array with booleans that denote which are present and which are deleted (e.g. deleted[4] = 1 means that item 4 is deleted. This only cost 1 bit per element.
- Use two arrays with items, and copy them back and forth each time. This will cause not really a memory gap, but you need the storage needed for two arrays. And keep a variable which of the two arrays is the 'current'.

body:
I back up Michel Keijzers' suggestion to use a plain array, especially
given the tiny amount of RAM in your MCU (only 256 bytes).

Concerning the removal of items from the list, and given that your list
will be 16 bytes at most, you don't need to get fancy: just move back
the items that are past the one you removed. It will not take long.

Here is a barebones implementation of a list that can hold at most
16 bytes and supports removal:

```c++
class List {
public:
    byte length;
    byte data[16];
    void append(byte item) {
        if (length < 16) data[length++] = item;
    }
    void remove(byte index) {
        if (index >= length) return;
        memmove(&data[index], &data[index+1], length - index - 1);
        length--;
    }
};
```

Note that this only takes 17 bytes of RAM (16 items max plus a
length count). There is not vtable, as it has no virtual methods. You
can get fancier if you want, make this a template parametrized by the
data type and the maximum length, add accessors and such... but if you
are just writing a simple sketch (as opposed to a general purpose
library), I would recommend keeping it as simple as possible.

Example usage, based on your pseudo-code:

```c++
List l { .length = 3, .data = { 12, 82, 29 } };
l.remove(1);
```

This will indeed result in the list [12, 29].


body:
I salvaged segway motor with 8 wires. I did completed basic connection of 5 hall sensors and power from 36V lipo battery in the image  below. When I connect self-learning wires then motor starts rotating so connecting must be right. So now how do I control the motor with arduino?

Controller is kkmoon motor regulator 350W - [link][1]

didn't find datasheet about motor but here are some Information:-
Type: BLDC Motor
Voltage: 36V
no of wires:- 8 (3 wires  for 3 phase, 5 for hall sensor)
Power:- 300W

[![connections][2]][2]

[![motor controller information][3]][3]

  [1]: https://www.amazon.ae/KKmoon-Regulator-Controller-Electric-Brushless/dp/B07VTQC1QV/ref=asc_df_B07VTQC1QV/?tag=googleshopp09-21&linkCode=df0&hvadid=379724527416&hvpos=1o1&hvnetw=g&hvrand=5866853317310978478&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1000013&hvtargid=pla-868311548127&psc=1
  [2]: https://i.stack.imgur.com/5QE91.jpg
  [3]: https://i.stack.imgur.com/2uevm.jpg

title: How to control segway motor with arduino uno?

Answers: 0


body:
In your code https://gist.github.com/edgar-bonet/0b03735d70366bc05fc6 for homodyne detection, is there a way to make the frequency detected a range of frequencies? For example detecting between 3kHz and 4kHz?
Thanks in advance!

title: Homodyne detection for arduino

Answers: 1

body:
It may be possible to modify that program in order to get such a large
frequency range:

 * change the local oscillator frequency to 3.5 kHz
 * drastically shorten the filter's time constant in order to get a
   wider passband

However, the homodyne detection scheme is best suited for building very
narrow band filters. In your case, the upper limit you want is quite
close to the Nyquist frequency (4,808 Hz), so I suggest you use a
high-pass, rather than a band-pass filter. The simplest high-pass you
can get is a numerical derivative:

y[n] = x[n] − x[n−1]

The gain of this filter is 2×sin(π×f/fsamp), so you get the
−3 dB cutoff at fsamp/4 ≈ 2,404 Hz. If you need
something better, you may want to try a higher order filter. But then
you get deep into the territory of digital filter design, which can be
tricky, especially if you have no experience with the z-transform or you
want to implement the filter in fixed point.

**Edit**: If you really want a bandpass, the simplest I can think of is
this two-pole filter:

y[n] = 0.360 x[n] − 0.885 y[n−1] − 0.552 y[n−2]

It will give you a maximum gain of roughly 1 at about
3.43 kHz, and −3 dB cutoffs at 3 and 4 kHz. A
straightforward floating point implementation would be:

```c++
float filter(float x)
{
    static float y1, y2;
    float y = 0.360 * x - 0.885 * y1 - 0.552 * y2;
    y2 = y1;
    y1 = y;
    return y;
}
```

You should convert this to fixed point if you want to use it, otherwise
I doubt your Arduino will have the processing power to run every sample
through it. Below is a plot of this filter's gain, compared with the
simple derivative, which I divided by 2 in order to normalize its
gain:

[![gain vs frequency][1]][1]

Note that the gain gets flat as you approach the Nyquist frequency, and
stays relatively high (above −5.4 dB).

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


body:
Consider the following example:

    int i { 0 };

    void incInt() {
        ++i;
    }

    int readInt() {
        return i;
    }

    setup() {
        Serial.begin(9600);
        attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);
    }

    loop() {
        noInterrupts();
        int currI = readInt();
        interrupts();

        Serial.println(currI);
    }

By wrapping the call to `readInt()` with `noInterrupts()` and `interrupts()` it is ensured that `i` cannot be changed externally during the execution of `readInt()`. `i` also cannot be changed externally during the execution of `incInt()`, as long as it is only called as ISR (interrupt service routine). Do I still need to declare `i` as `volatile`?

Does the situation change if `i` is accessed directly in the main loop:

    loop() {
        noInterrupts();
        int currI = i;
        interrupts();

        Serial.println(currI);
    }

In other words: What is the context in which the compiler expects a variable to not be changed externally if it is not declared `volatile`?

title: Is volatile qualifier needed if shared variable cannot be changed externally during complete function call?

Answers: 2

body:
Declaring a variable as `volatile` tells the compiler, that it always has to read the real variable and that it cannot use a cached value. Also the compiler cannot optimize this variable, since it is unknown, when the variable will change. For this it is irrelevant, how you actually read the variable in the main sketch, it only matters, that it get's read. Also this has nothing directly to do with doing the read atomically (with `noInterrupts()`) (though you only garantee correct values, when doing it)

So yes, you need to declare it volatile, or the compiler might think, that the value doesn't change and optimize it out in some way.

> What is the context in which the compiler expects a variable to not be changed externally if it is not declared volatile?

Externally here means outside of the main routine. This covers variables, that get changed in ISRs and also registers, that are changed by hardware (so the register definition in the used core are also `volatile`). The compiler cannot know, when these changes happen, because they are triggered by the hardware, not by the code. It will try to optimize your sketch (which is a rather complex procedure), and might see, that your variable is never changing in the code (the ISR does not get called from the main sketch, thus the compiler does not see it getting called) and will try to optimize it. To ensure, that your sketch works properly, it is your task to tell the compiler, that this variable can change at any time (so that it does not think the other way). You are doing this by declaring it as `volatile`

body:
Let's forget about atomicity for a moment, which is a separate issue, and
assume `i` is an atomic type (maybe `byte` or something equivalent).
Consider the following code:

```c++
void loop()
{
    Serial.println(i);
}
```

Not so long ago I would have expected this to work just fine on Arduino,
as there aren't many ways to compile this function… on its own! However,
since version 1.6.10, [the IDE enables link-time optimization][release].
This means that the compiler (or rather, the optimizer working within
the linker), can see the whole program and notice that `setup()` and
`loop()` are called from only one function which belongs to the Arduino
core:

```c++
int main()  // slightly simplified
{
    init();      // Arduino core initialization
    setup();     // User's initialization
    for (;;)
        loop();  // User's loop
}
```

This makes them perfect candidates for [inlining][]:

```c++
int main()
{
    init();      // will likely be inlined too

    // Inlined setup():
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);

    for (;;) {
        // Inlined loop():
        Serial.println(i);
    }
}
```

Now it should become clearer that repeatedly reading `i` from memory
looks like a waste of time, which can be optimized-out. The `for` loop then
becomes:

```c++
register uint8_t cached_i = i;  // save `i' in an internal CPU register
for (;;) {
    // Inlined loop():
    Serial.println(cached_i);
}
```

And now the program only prints zeros. That's why you need `volatile` to
prevent that optimization.

[release]: https://blog.arduino.cc/2016/07/27/download-the-new-arduino-ide-1-6-10/
[inlining]: https://en.wikipedia.org/wiki/Inline_expansion


body:
am stuck with something simple which is concating string not sure what am doing wrong , am getting exception (3 ) error due to it

    3 LoadStoreErrorCause Processor internal physical address or data error during load or store

my code

        String HOST = "useotools.com";
        String API_URL = "/iot/api.php";   // API URL
        uint16_t HTTPS_PORT = 4000;  // HTTPS port
        uint16_t HTTP_PORT = 4001;  // HTTP port

    void https_request_function(){
    String HOST_URL = "http://"+String(HOST)+":"+String(HTTP_PORT)+String(API_URL)+"";

    }

when first time https_request_function() is called then HOST_URL is displayed correctly and on 2nd time when this function is called by code it trigger exception(3) which is strange .

title: Arduino How to Concat Strings

Answers: 0


body:
My arduino uno is not recognized by the Arduino IDE. I'm using 1.8.0, The IDE is not showing the COM. The tool section is showing only COM 1, i.e. the hardware.

I opened Device manager, there is no board for UNO.

Help me please.

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

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

  [1]: https://i.stack.imgur.com/i8hOc.png
  [2]: https://i.stack.imgur.com/XRzPJ.png

Arduino Nano works fine.

I have CH340 driver already installed. My computer do not make any "hardware connected sound". I have 3 arduino IDE versions - 1.8.0, 1.8.9, 1.8.10!.

title: Arduino Uno board not recognized in IDE. Board is not in device manager!

Answers: 2

body:
I had a similar problem with my Arduino. My solution is to unplug it, replug it and do what you need to do before the computer can auto-configure it.
I hope it helps! :)
BTW make sure you are choosing the right board.

body: According to https://www.arduino.cc/en/Guide/ArduinoUno, you may need to install a separate driver for the Arduino Uno because it does not have a true USB port. The details are in the link.


body:
Since the Nano 33 boards are quite new right now, I haven't found any details on how to hook one up with batteries.

I'm pretty daft when it comes to electronics (I'm a software man), and I read that the new Nano 33 requires 3.2V, which is a bit of a departure from the 5V the old models supported.

From what I can tell, I might be able to use a single LiFePO4 cell. Am I correct in this assumption? And if so, are there any pitfalls in going this route?

EDIT: I might have misunderstood the difference between operating voltage and input voltage. Does this mean that I can plug any AA battery pack in as a power source?

title: Battery solution Nano 33 iOT

Answers: 1

body:
You can either use the 3.3V pin to supply power to the board, or use the Vin pin.

By using the VIN pin to power goes through a (step down) voltage regulator, that provides a nice stable 3.3V to the board. The regulator in the Nano 33 IoT is the `MPM3610`, which requires an input voltage of at least 4 - 4.5 Volt. Which is more that a LiPo or LiFePo single cell can supply. You could use a multi-cell battery pack. Or a USB power bank. So this solutions is not really ideal.

The other option was to connect the battery directly to the 3.3V pin. The voltage of a LiFePo however changes as it is being discharged. The voltage is around 3.65V when full, and 2.5-2.75V when "empty". The 3.2V rating is called the nominal voltage (kind of an average voltage).
So it's a bit too high when full, and too low when empty. The voltage also isn't regulated, so it can fluctuate a bit, based on the amount of current that's being used.

The maximum voltage for the SAMD21 on this Nano is 3.63V. Maximum voltage for the gyro (LSM6DS3) is 3.6V. The absolute maximum voltage for the radio (NINA-W10) is 3.6V.

So a full LiFePo is slightly too high for the Nano. Though I think you should be fine. But don't try this with a regular LiPo of Lion battery (4.2V when full).


body:
The ATmega328p and ATmega32u4 microcontroller have 32Kb of flash memory (as datasheet). Bootloader for each microcontroleer has different size (about 512 byte for 328p and 4kb for 32u4).

Why in boards.txt the "upload.maximum_size" parameters is 32256 for 328p and 28672 for 32u4?

I we have to consider bootloader size, the "upload.maximum_size" parameter for 328p must be about 31.5k and not 32k. And, if we do not have to consider bootloader size, as the default boards.txt configuration (above) for 328p, the "upload.maximum_size" parameter for 32u4 must be 32k not 28k. Correct?

Thank you

title: Flash size in boards.txt ATmega 328p 32u4

Answers: 1

body:
`1KB` is 1024 bytes, not 1000 bytes.

Therefore 32kb = 32768 bytes.

`32768-512=32256`, which is exactly the value used for upload.maximum_size for the 328p.

4kb=4096 bytes. `32768-4096=28672` which is the value for the 32u4.


body:
I'm checking an example for the MPU6050 and got to this part

    Wire.beginTransmission(0x68);           //begin, Send the slave adress (in this case 68)
    Wire.write(0x1B);                       //We want to write to the GYRO_CONFIG register (1B hex)
    Wire.write(0x10);                       //Set the register bits as 00010000 (1000dps full scale)
    Wire.endTransmission(true);             //End the transmission with the gyro

    Serial.begin(9600);                     //Remember to set this same baud rate to the serial monitor
    time = millis();                        //Start counting time in milliseconds

    /*Here we calculate the gyro data error before we start the loop
     * I make the mean of 200 values, that should be enough*/
    if(gyro_error==0)
    {
      for(int i=0; i<200; i++)
      {
        Wire.beginTransmission(0x68);            //begin, Send the slave adress (in this case 68)
        Wire.write(0x43);                        //First adress of the Gyro data
        Wire.endTransmission(false);
        Wire.requestFrom(0x68,4,true);           //We ask for just 4 registers

Why is there two consecutive wire.write() in the begining and only one later? Is it different somehow?

title: Why Wire.write twice?

Answers: 1

body:
The truth is, the Arduino Wire library sends the data only if `endTransmission` is called. Until then it collects the data in TX buffer. The version of the `write` function used in your snippet adds a byte to the TX buffer.

With I2C usually the first byte written is the address of the register to write. Then the data follow. In case of the first part in your snippet the data are only one byte long.

In the second part, first the register address is sent with `write` and then the data from this register and 3 following registers are requested.


body:
I'm trying to use a MS5540C (digital pressure sensor)
and the sample code has this line:

     TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

I'm a bit of a noob to the IoT but its not beyond me to check the SPI.h and see that there is indeed no declaration.

I'm using an **Arduino UNO WiFi Rev 2**.
(Seems like its pins are quit different from an UNO)
I have noted in the comments that Im using pins 32,33,34 instead of 11,12,13

I'm not 100% sure what to ask … other than
Is there a replacement call/function/method that should replace that line? ..or am I missing something else totally. As it stands now...when the program runs its results are inconsistent. I'm just commenting out the faulty line to get it to compile.

**Complete sketch**
source: [Future Electronics][1]

    /*
      MS5540C Miniature Barometer Module
      This program will read your MS5440C or compatible pressure sensor every 5 seconds and show you the calibration words, the calibration factors,
      the raw values and the compensated values of temperature and pressure.
      Once you read out the calibration factors you can define them in the header of any sketch you write for the sensor.

      Uno Pins:
      MS5540 sensor attached to pins 10 - 13:
      MOSI: pin 11
      MISO: pin 12
      SCK: pin 13
      MCLK: pin 9 (or use external clock generator on 32kHz)
      CS is not in use, but might be pin 10

      ==[ addendum start]=============================
      Uno WiFi Rev2 Pins:
      MOSI: pin 32
      MISO: pin 33
      SCK: pin 34
      MCLK: pin 9 (or use external clock generator on 32kHz)
      ==[ addendum end ]=============================

      created 29 February 2012
      by MiGeRA
    */

    /*
      Calibration of my sensor example ...

      Calibration word 1 = 46958
      Calibration word 2 = 65369
      Calibration word 3 = 39392
      Calibration word 4 = 45914
      c1 = 23479
      c2 = 2074
      c3 = 717
      c4 = 615
      c5 = 1021
      c6 = 25
    */

    #include <SPI.h>

    const int clock = 9;

    void setup() {
      Serial.begin(9600);
      SPI.begin(); //see SPI library details on arduino.cc for details
      SPI.setBitOrder(MSBFIRST);
      SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz

      pinMode(clock, OUTPUT);
      delay(100);
    }

    void loop()
    {
      Serial.println("=====================================================================");
      TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

      analogWrite (clock, 128) ;
      resetsensor(); //resets the sensor - caution: afterwards mode = SPI_MODE0!

      //Calibration word 1
      unsigned int result1 = 0;
      unsigned int inbyte1 = 0;
      SPI.transfer(0x1D); //send first byte of command to get calibration word 1
      SPI.transfer(0x50); //send second byte of command to get calibration word 1
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
      result1 = result1 << 8; //shift returned byte
      inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
      result1 = result1 | inbyte1; //combine first and second byte of word
      Serial.print("Calibration word 1 = ");
      Serial.print(result1, HEX);
      Serial.print(" ");
      Serial.println(result1);

      resetsensor(); //resets the sensor

      //Calibration word 2; see comments on calibration word 1
      unsigned int result2 = 0;
      byte inbyte2 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0x60);
      SPI.setDataMode(SPI_MODE1);
      result2 = SPI.transfer(0x00);
      result2 = result2 << 8;
      inbyte2 = SPI.transfer(0x00);
      result2 = result2 | inbyte2;
      Serial.print("Calibration word 2 = ");
      Serial.print(result2, HEX);
      Serial.print(" ");
      Serial.println(result2);

      resetsensor(); //resets the sensor

      //Calibration word 3; see comments on calibration word 1
      unsigned int result3 = 0;
      byte inbyte3 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0x90);
      SPI.setDataMode(SPI_MODE1);
      result3 = SPI.transfer(0x00);
      result3 = result3 << 8;
      inbyte3 = SPI.transfer(0x00);
      result3 = result3 | inbyte3;
      Serial.print("Calibration word 3 = ");
      Serial.print(result3, HEX);
      Serial.print(" ");
      Serial.println(result3);

      resetsensor(); //resets the sensor

      //Calibration word 4; see comments on calibration word 1
      unsigned int result4 = 0;
      byte inbyte4 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0xA0);
      SPI.setDataMode(SPI_MODE1);
      result4 = SPI.transfer(0x00);
      result4 = result4 << 8;
      inbyte4 = SPI.transfer(0x00);
      result4 = result4 | inbyte4;
      Serial.print("Calibration word 4 = ");
      Serial.print(result4, HEX);
      Serial.print(" ");
      Serial.println(result4);

      //now we do some bitshifting to extract the calibration factors
      //out of the calibration words;
      long c1 = (result1 >> 1) & 0x7FFF;
      long c2 = ((result3 & 0x003F) << 6) | (result4 & 0x003F);
      long c3 = (result4 >> 6) & 0x03FF;
      long c4 = (result3 >> 6) & 0x03FF;
      long c5 = ((result1 & 0x0001) << 10) | ((result2 >> 6) & 0x03FF);
      long c6 = result2 & 0x003F;

      Serial.print("c1 = ");
      Serial.println(c1);
      Serial.print("c2 = ");
      Serial.println(c2);
      Serial.print("c3 = ");
      Serial.println(c3);
      Serial.print("c4 = ");
      Serial.println(c4);
      Serial.print("c5 = ");
      Serial.println(c5);
      Serial.print("c6 = ");
      Serial.println(c6);

      resetsensor(); //resets the sensor

      //Pressure:
      unsigned int presMSB = 0; //first byte of value
      unsigned int presLSB = 0; //last byte of value
      unsigned int D1 = 0;
      SPI.transfer(0x0F); //send first byte of command to get pressure value
      SPI.transfer(0x40); //send second byte of command to get pressure value
      delay(35); //wait for conversion end
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
      presMSB = presMSB << 8; //shift first byte
      presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
      D1 = presMSB | presLSB; //combine first and second byte of value
      Serial.print("D1 - Pressure raw = ");
      Serial.println(D1);

      resetsensor(); //resets the sensor

      //Temperature:
      unsigned int tempMSB = 0; //first byte of value
      unsigned int tempLSB = 0; //last byte of value
      unsigned int D2 = 0;
      SPI.transfer(0x0F); //send first byte of command to get temperature value
      SPI.transfer(0x20); //send second byte of command to get temperature value
      delay(35); //wait for conversion end
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
      tempMSB = tempMSB << 8; //shift first byte
      tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
      D2 = tempMSB | tempLSB; //combine first and second byte of value
      Serial.print("D2 - Temperature raw = ");
      Serial.println(D2); //voila!

      //calculation of the real values by means of the calibration factors and the maths
      //in the datasheet. const MUST be long
      const long UT1 = (c5 << 3) + 20224;
      const long dT = D2 - UT1;
      const long TEMP = 200 + ((dT * (c6 + 50)) >> 10);
      const long OFF  = (c2 * 4) + (((c4 - 512) * dT) >> 12);
      const long SENS = c1 + ((c3 * dT) >> 10) + 24576;
      const long X = (SENS * (D1 - 7168) >> 14) - OFF;
      long PCOMP = ((X * 10) >> 5) + 2500;
      float TEMPREAL = TEMP / 10;
      float PCOMPHG = PCOMP * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

      /*
        Serial.print("UT1 = ");
        Serial.println(UT1);
        Serial.print("dT = ");
        Serial.println(dT);
        Serial.print("TEMP = ");
        Serial.println(TEMP);
        Serial.print("OFFP = ");
        Serial.println(OFF);
        Serial.print("SENS = ");
        Serial.println(SENS);
        Serial.print("X = ");
        Serial.println(X);
      */

      Serial.print("Real Temperature in C = ");
      Serial.println(TEMPREAL);

      Serial.print("Compensated pressure in mbar = ");
      Serial.println(PCOMP);
      Serial.print("Compensated pressure in mmHg = ");
      Serial.println(PCOMPHG);

      //2-nd order compensation only for T < 20°C or T > 45°C

      long T2 = 0;
      float P2 = 0;

      if (TEMP < 200)
      {
        T2 = (11 * (c6 + 24) * (200 - TEMP) * (200 - TEMP) ) >> 20;
        P2 = (3 * T2 * (PCOMP - 3500) ) >> 14;
      }
      else if (TEMP > 450)
      {
        T2 = (3 * (c6 + 24) * (450 - TEMP) * (450 - TEMP) ) >> 20;
        P2 = (T2 * (PCOMP - 10000) ) >> 13;
      }

      if ((TEMP < 200) || (TEMP > 450))
      {
        const float TEMP2 = TEMP - T2;
        const float PCOMP2 = PCOMP - P2;

        float TEMPREAL2 = TEMP2 / 10;
        float PCOMPHG2 = PCOMP2 * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

        Serial.print("2-nd Real Temperature in C = ");
        Serial.println(TEMPREAL2);

        Serial.print("2-nd Compensated pressure in mbar = ");
        Serial.println(PCOMP2);
        Serial.print("2-nd Compensated pressure in mmHg = ");
        Serial.println(PCOMPHG2);
      }

      delay(5000);
    }

    void resetsensor() //this function keeps the sketch a little shorter
    {
      SPI.setDataMode(SPI_MODE0);
      SPI.transfer(0x15);
      SPI.transfer(0x55);
      SPI.transfer(0x40);
    }

  [1]: https://cdn.shopify.com/s/files/1/0672/9409/files/water_depth_sensor_MS5540C_Arduino_tutorial.pdf?698

title: 'TCCR1B' was not declared in this scope

Answers: 1

body:
While writing this answer, I found out about the register emulation of the Arduino Uno Wifi. The Uno Wifi is a different chip, than the Uno, thus you have different registers. But the Uno Wifi was thought as a drop in replacement, so register emulation maps the old register names to the new registers, so that you can basically simply reuse the old code for the Uno. In my Arduino IDE (v1.8.9) I had a buildin Uno Wifi board, which seems to have the register emulation enabled without configuration option (I could compile your sketch even for the Uno Wifi). Through the board manager I installed the "Arduino megaAVR Boards" core, that contains the Arduino Uno Wifi rev2. If you choose this board in the board selection, you get the option to select the register emulation. For old code you need the emulation for ATmega328. With that, your old code should compile.

This makes the rest of my answer unnecessary, but since I already spend some time writing it,  I will leave it in the answer for information and for the case, that you don't want to use the register emulation.

---

You get the error, because the sketch, that you copied is made for the Arduino Uno, not the Arduino Uno Wifi. While the first uses an ATmega328P chip, the last is build with an ATmega4809 (you can find this information [here at the Arduino.cc store][1]). These are different chips, thus you cannot simply reuse code that is made for the Uno on the Uno Wifi.

`TCCR1B` is the control register B of Timer 1. This name is specific to the ATmega328P chip. The ATmega4809 has even more timers than the 328P, but they seem to get configured via different registers. Refer to the datasheets on the [product site of the ATmega4809][2]. The timer hardware and it's registers are described in the more general [megaAVR 0 series family datasheet][3]. At the first glance it seems, that not only the register description is different from the 328P, but also the positions of the different configurations. This means, that every code, that uses direct register manipulations for the timer, must be rewritten for the 4809.

Fortunately, I see only 1 line here, that does this: The line, that generated the compiler error. (The SPI library very likely already has fitting definitions inside for the 4809). You have the line

    TCCR1B = (TCCR1B & 0xF8) | 1;

That clears the 3 least significant bits (leaving the rest as it was) and setting the least significant bit to 1. According to chapter 16.11.2 of the 328P's datasheet (description of the TCCR1B register), these 3 bits are the clock selection. A bit code of `001` (only least significant bit set) means timer on, but with no prescaling.

To be honest, I'm not sure, if this line really does something, since directly after that, `analogWrite()` is called and I thought this function would overwrite the timer settings. But other posts (like [this one][4]) suggest, that it at least does not overwrite the clock selection.

I don't know, which timer get's used for outputting PWM to that pin, but for now, I will assume the first timer of type B. If you look into the families datasheet (as linked above) the clock source of the second timer (TCB) is configured with the register `TCB0.CTRLA` (see chapter 20.5.1). Bits 1 and 2 are configuring the prescaler (binary `00` for no prescaler), bit 0 enables the timer. So you can again write binary `001` to this register, leaving the rest untouched. So I suggest, you use this line instead of the old one

    TCB0.CTRLA = (TCB0.CTRLA & 0xF8) | 1;

This should do the same with the second timer, that was done in the original sketch. If the first timer is used for this, you would have to change `TCB0` to `TCA0.SINGLE` (I really don't know, why this SINGLE is needed) and change `0xF8` to `0xF0`, since TCA has 3 bits for selecting the clock source.

  [1]: https://store.arduino.cc/arduino-uno-wifi-rev2
  [2]: https://www.microchip.com/wwwproducts/en/ATMEGA4809
  [3]: http://ww1.microchip.com/downloads/en/DeviceDoc/megaAVR-0-series-Family-Data-Sheet-40002015C.pdf
  [4]: https://arduino.stackexchange.com/questions/25609/set-pwm-frequency-to-25-khz