body:
I'm using [DS3231 module][1] with [rinkydink library][2] and it is working just fine, however every time i want to compile the code Arduino IDE shows this warning:
```
C:\Program Files (x86)\Arduino\libraries\DS3231\DS3231.cpp:291:106:
warning: ISO C++ forbids converting a string constant to 'char*'
[-Wwrite-strings]
```

What is this warning and how to solve it?

  [1]: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
  [2]: http://www.rinkydinkelectronics.com/library.php?id=73

title: What is causing this warning in Arduino IDE?

Answers: 2

body:
The warning was caused by this line:

```c++
char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
```

In C++, the content of a character string such as `"Jan"` cannot be
modified. Thus, if you assign the string to a pointer, the pointer
should be declared as **const** char \*:

```c++
const char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
```

The same applies to the other arrays of strings: `daysLong`, `daysShort`
and `monthLong`. As a consequence, the prototypes of the methods
`getDOWStr()` and `getMonthStr()` should be changed in order to return a
`const char *`.

BTW, are you sure this library is still maintained? This should have
been fixed a long time ago, and it seems the source was last modified in
2015. You may be better off using a more modern alternative. For
instance, in the Arduino library manager, you can find [DS3231][] and
Adafruit's [RTClib][].

[DS3231]: https://www.arduinolibraries.info/libraries/ds3231
[RTClib]: https://www.arduinolibraries.info/libraries/rt-clib

body:
The DS3231 library from Rinky Dink is the best RTC library there is...I know, I tried them ALL.  This library allows one to print date and time strings with only 3 Arduino print statements:  Serial.print(rtc.getDateStr());
      Serial.print(" -- ");
      Serial.println(rtc.getTimeStr());
Other RTC libraries force user to make the strings up themselves, at a cost of about 12 lines of useless Serial.print commands.


body: Has anyone found the HC-05 bluetooth module (on the breakout board) with straight header pins?  I seem to only be able to find them with the 90 degree header pins.  Removing those and soldering on straight ones for my project is getting tiresome...  I would even be happy to find them without header pins (but still on the breakout board).

title: HC-05 Bluetooth module on breakout board with straight header pins

Answers: 0


body:
I'm using [RTClib][1] for my DS3231 module, the problem is the library is displaying the second without zero behind it: `22:1:1` and when i print the time on my 16x2 LCD time is displaying like this:

> 22:22:59
>
> 22:23:19
>
> 22:23:29
>
> ...
>
> 22:23:59
>
> 22:23:10
>
> 22:23:11

the second number of seconds is not getting cleared.
i know one solution to this is to use `lcd.clear()` function to update the LCD in each loop but is there any other way to clear that second number or do something so library show zero behind second?

  [1]: https://github.com/adafruit/RTClib

title: RTClib library the second, second

Answers: 1

body:
It's your responsibility to format the time properly, not the library. The library just gives you a number. If you want a leading zero then it's up to you to provide that leading zero.

For example:

    if (now.seconds() < 10) {
        lcd.print("0");
    }
    lcd.print(now.seconds());

Or:

    char timestr[9];
    snprintf(timestr, 9, "d:d:d", now.hours(), now.seconds(), now.minutes());
    lcd.print(timestr);


body:
We have an Arduino Pro Mini on a breadboard connected to a 9V battery and a sensor, reading data. We also have a full-sized [Adafruit WINC1500 WiFi Shield with PCB Antenna][1]. I would like to know if they can be connected and, if so, how.

I understand that a shield is usually stacked on a similarly sized board, but can we place the shield on the breadboard with the Mini and use jumper wire to connect the necessary pins so the Mini can use the WiFi (actually, we want to write to the SD card on the WiFi shield)? If so, how would we know which pins are used, and would we need to provide additional power? Or is connecting a Mini to a full-sized shield a ridiculous idea?

  [1]: https://www.adafruit.com/product/3653

title: Can an Arduino Pro Mini interface with a full-sized WiFi shield?

Answers: 1

body:
> I would like to know if they can be connected and, if so, how.

Yes.

> but can we place the shield on the breadboard

No, the pins are misaligned and won't plug in.

> and use jumper wire to connect the necessary pins so the Mini can use the WiFi

Yes - connect the jumper wires directly to the WiFi shield pins.

> If so, how would we know which pins are used,

Read the manual or schematic for your WiFi shield. It probably uses the SPI pins plus a few more.

> and would we need to provide additional power?

It will need a power connection, yes - though "extra" power? Not sure what you mean.


body:
So me and my dad are trying to catch would be thieves and also someone leaving behind alcohol bottles. At his storage business the cameras don't reach to these spots.

Without being too invasive I want to sense bluetooth and/or wifi signals of relatively close phones sort of like a pax counter. This is in lue of using a pir sensor which I have always found finicky and I want to make use of the esp32' cam's wifi/ble chip.

So to start I researched for the past few days or week. I found that most phones don't use ble so maybe that is out. I also found that the esp32 cam is a bit finicky and I'm not sure if it is compatible with other code I have found.

One time I was able to get the light to come on when my phone was near using code I found for the esp32.

Any help or direction would be nice

Edit: I understand this sounds weird but mostly I would just like to get proximity of bluetooth or wifi to trigger an event. The device is powered by battery and I understand not everyone carrys phones.

title: Person (phone) detector that trigger an event esp32 cam

Answers: 1

body:
Detecting a phone could be easily done by [capturing](https://github.com/brannondorsey/sniff-probes) WiFi probe requests which are sent by phones having at least one saved WiFi network. Note that such requests alone are often enough to identify the person, if their home WiFi SSID is set to something like "Davids_wifi".

Software-wise, this would be much easier to do on Linux (think Raspberry Pi or a similar device) which already have all the network sniffing software like `tcpdump`, which you would otherwise have to find or implement on ESP32.

I'm leaving out the legal implications of what you're trying to do as I don't know what country you are in, but bear in mind that hidden surveillance may be illegal in some cases.


body:
I would like to build a lib like ArduinoOTA but with no downtime at runtime. To achieve that I am wondering if it is possible to create a simple setup and loop code to

1. Check for new releases
2. If we have a new one start download it
3. As download routine is not finished keep running the current release
4. When download has finished, swap current release to the new one.
5. Now the normal routine is running the new release.

I am pretty interested if it is possible to do by myself something like that.

I didn't find any paper or articles similar to this and I don't known if this is a challenge for Arduino scope or C/C++.

Maybe I am saying something bizarre but I have been thinking of save new release into flash memory, point to it and discard the old release from flash memory.

title: Is it possible to execute a code in runtime when gets updated over the air (OTA)?

Answers: 1

body:
On many Arduinos the processor is only a few dollar part.  You are asking for a feature that only starts appearing on platforms where the processor is over an order of magnitude higher in price.  Further, such inexpensive processors normally run a single program.  Running a sketch while managing a download & update would best be done by two programs existing in an operating system.  Again, likely requiring a processor an order of magnitude higher in price.

Instead, consider implementing your design using two different Arduinos.  Swapping one out for the other after updating.   Hot swapping may not be trivial.  This really depends on how your application interfaces with the world. But likely will be much easier than solving the problem of designing the supporting software to make sketch updates transparent to the Arduino user.


body:
Currently to get time/date i'm using DS3231 module with the [RTClib][1] library, i want to use the Atmel 24C32 chip on the module to store some small values (temperature etc).

Can i use the current library AND an external EEPROM library (which one?) OR i need to change my RTC library in order to use EEPROM feature?

  [1]: https://github.com/adafruit/RTClib

title: DS3231 and EEPROM

Answers: 1

body:
> Can i use the current library AND an external EEPROM library (which one?)

Yes. Devices on an I2C bus are separate devices and use their own separate libraries.

* https://playground.arduino.cc/Main/LibraryForI2CEEPROM/


body:
I have a sensor that requires used of 5V as input to Vcc. But I dont see any 5V output pins on the NodeMCU 1.0(12E). Is there a way I could get 5V output pins?

Its not a duplicate question. I want a 5V output and not provide 5V input to NODEMCU.

title: Get 5V output from NodeMCU

Answers: 1

body:
The `VIN` pin outputs 5V approximately (dependent on USB input voltage) from the NodeMCU board.

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

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


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

How to use the reserved pins on the NODEMCU? What is their use? Also what is the use of SDD pins?

Thanks.

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

title: What is the use of reserved pins and SDD2, SDD3 pins of the NodeMCU?

Answers: 1

body:
The ESP8266 uses an external flash memory chip to store your program. It communicates with this flash chip over a 4 bit SDIO interface, on GPIO6-11. These pins are labeled SDDn, SDCLK and SDCMD.
Usually, the interface uses all 4 data lines (QIO), but you can also configure it to use only 2 of the 4 lines (DIO), giving you access to two more GPIO pins (9 & 10).
The reserved pins are not mentioned in the schematic. They cannot be IO pins, because there simply are no other pins on the ESP8266/ESP-12. It could be pins connected to the USB chip, connected to power lines, or not connected at all. The designers probably wanted to allow for extra pins on next iterations of the board, without changing the form factor. A quick search online didn't yield any results, so your best bet is to trace the connection on the PCB, or measure it with a multimeter. You probably shouldn't be using them anyway, because they are "reserved".


body:
it has been so long since I tried to connect the esp8266 through Arduino Uno and get it to work my goal is to send data from the Arduino Uno to web site, I have tried everything and a lot of codes but none worked at first I could get a response  but sometimes it does and sometimes it does not I even bought an other one but the new one did not respond at all so I flashed the old one following the instructions in [here][1] and I got response the next day I tried to reuse it and it does not respond at all not even when I put the serial on 115200 and both NR&CR and tried AT but nothing showed in return .i found this [tutorial][2]
and I tried to get it to work using a mobile app but as usual, it does not work

    AT
    AT+RST
    ATE0
    AT+CWMODE=1
    AT+CWQAP
    AT+CWDHCP=1,1
    AT+CWJAP="RemoteXY","12345678"
but i did not get hte name of it wifi in my wifi list
this is the code

    // RemoteXY select connection mode and include library
    #define REMOTEXY_MODE__ESP8266_HARDSERIAL

    #include <RemoteXY.h>

    // RemoteXY connection settings
    #define REMOTEXY_SERIAL Serial
    #define REMOTEXY_SERIAL_SPEED 115200
    #define REMOTEXY_WIFI_SSID "RemoteXY"
    #define REMOTEXY_WIFI_PASSWORD "12345678"
    #define REMOTEXY_SERVER_PORT 6377

    // RemoteXY configurate
    #pragma pack(push, 1)
    uint8_t RemoteXY_CONF[] =
      { 255,2,0,0,0,30,0,8,13,0,
      2,0,70,25,22,11,2,26,31,31,
      79,78,0,79,70,70,0,1,0,10,
      26,12,12,2,31,88,0 };

    // this structure defines all the variables of your control interface
    struct {

        // input variable
      uint8_t switch_1; // =1 if switch ON and =0 if OFF
      uint8_t button_1; // =1 if button pressed, else =0

        // other variable
      uint8_t connect_flag;  // =1 if wire connected, else =0

    } RemoteXY;
    #pragma pack(pop)

    /////////////////////////////////////////////
    //           END RemoteXY include          //
    /////////////////////////////////////////////

    #define PIN_SWITCH_1 2
    #define PIN_BUTTON_1 12

    void setup()
    {
      RemoteXY_Init ();

      pinMode (PIN_SWITCH_1, OUTPUT);
      pinMode (PIN_BUTTON_1, OUTPUT);

      // TODO you setup code

    }

    void loop()
    {
      RemoteXY_Handler ();

      digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
      digitalWrite(PIN_BUTTON_1, (RemoteXY.button_1==0)?LOW:HIGH);

      // TODO you loop code
      // use the RemoteXY structure for data transfer

    }

i wired it like this

[![enter image description here][3]][3]
one last thing is it gets hot every time so what could be the problem what's wrong with is what should I do

  [1]: http://remotexy.com/en/help/esp8266-firmware-update/
  [2]: https://www.youtube.com/watch?v=2cjufbgOBYo
  [3]: https://i.stack.imgur.com/ag3PU.png

title: ESP8266-01 is not working and it's hot

Answers: 1

body:
when a chip gets hot as soon as the VCC/GND is connected, it means :

 1. **The VCC/GND are internally connected due to a previous failure** (it
    gets hot AFTER the accident).

 2. **An output pin, is connected to a supply rail through a very low resistance load (or short circuited).** pins usually sink or
    source as low as 20mA of current. so if you connect them to a load
    less than (3.3/20)*1000 ~= 150 ohms (in your case with 3.3v supply),
    you are going to fry the output driver. always be sure that a pin, even if it's defined as an input, has a little resistor (a 220 ohms res).
this accident happens between output/supply or output/output pins.

you may have misconnected TX pin to a wrong pin.


body:
which flash option do I need to take to use EEPROM?

Can I flash with 1MB and no SPIFFs and still write data to EEPROM?

thanks T

title: esp8266 esp01s EEPROM and flashing

Answers: 1

body:
> Can I flash with 1MB and no SPIFFS and still write data to EEPROM?

Yes. The EEPROM emulation is saved into different part of the flash, not to SPIFFS.

    |--------------|-------|---------------|--|--|--|--|--|
    ^              ^       ^               ^     ^
    Sketch    OTA update   File system   EEPROM  WiFi config (SDK)

the memory map is from [esp8266 SPIFFS docs][1]

> which flash option do I need to take to use EEPROM?

There is no special option in Tools menu for EEPROM emulation. Only use the library.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html


body:
I'm using this [library][1] for my DS3231 which have a Atmel 24C32 on it.
i have a float value which increases by 0.5, like:

27.50

28

28.50
...

the code is like this:

    float lowTemp= 10.5

    float highTemp= 10.5

    void setup(){
      lowTemp = i2c_eeprom.read(100);
      highTemp = i2c_eeprom.read(101);
    }
    void loop(){
      if ((menuswtichStatus == HIGH) && (lcdWelcome == HIGH)) {
        previousMillis = millis();
        lcd.clear();
        menuScroll++;
        lcdClear = 1;
        lcdClear2 = 1;
      }
      if (menuScroll == 1) {
        lcd.setCursor(0, 0);
        lcd.print("Temperature set:");
        lcd.setCursor(0, 1);
        lcd.print("Minimum  ");
        lcd.print(lowTemp);
        lcd.print((char)223);
        lcd.print("C ");
        if (plusSwitchstatus == HIGH) {
          lowTemp += 0.5;
        }
        if (minusSwitchstatus == HIGH) {
          lowTemp -= 0.5;
        }
      }
      if (menuScroll == 2) {
        lcd.setCursor(0, 0);
        lcd.print("Temperature set:");
        lcd.setCursor(0, 1);
        lcd.print("Maximum  ");
        lcd.print(highTemp);
        lcd.print((char)223);
        lcd.print("C ");
        if (plusSwitchstatus == HIGH) {
          highTemp += 0.5;
        }
        if (minusSwitchstatus == HIGH) {
          highTemp -= 0.5;
        }
      }
      if (menuScroll == 3) {
        lcd.setCursor(0, 0);
        lcd.print("   Saving the");
        lcd.setCursor(0, 1);
        lcd.print("   Settings...");
        delay(1000);
        i2c_eeprom.write(100, lowTemp);
        i2c_eeprom.write(101, highTemp);
        delay(1000);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("    SETTINGS");
        lcd.setCursor(0, 1);
        lcd.print("     SAVED!");
        delay(2000);
        menuScroll = 0;
        lcdClear = 0;
        lcdClear2 = 0;
      }
    }
*i have the library and stuff up there, it's just an example of my code...*

The float value is not saving(written), what's the solution?

  [1]: https://github.com/QuentinCG/Arduino-I2C-EEPROM-library

title: How to write a float value EEPROM

Answers: 1

body:
You have multiple options:

1. According to jsotola's remark: the easiest is to multiply your value by 2, store it, and after reading, divide it by 2. In one byte you can store a value from 0 to 127.5 (255 / 2), or if you use signed from -64.0 to +63.5. Of course you also can use an offset in case you know the value cannot be less than e.g. -20.
2. If you need a higher range, you can still multiply it by 2, but store it in two bytes. Split the value in a 'high value' (value % 256) / 256, and a 'low value' (value % 256).
3. If you want to store the value completely, than use sizeof(float) to find the length, and a for loop to write each byte, starting from the first byte of the float until the last one.


body:
I'm trying to use my new Arduino MKR 1010 WiFi as a Bluetooth Low Energy **central**/**client**, however I could only find information on how to use it as a *peripheral/server* (for example with the [ArduinoBLE library][1], which only supports peripheral mode).

Is this possible? Maybe with a different library or firmware for the integrated NINA-W102 chip?

  [1]: https://github.com/arduino-libraries/ArduinoBLE

title: Arduino MKR 1010 WiFi as BLE central/client

Answers: 1

body:
In case this thread turns up in a search, the [ArduinoBLE][1] library now includes central and peripheral support.

  [1]: https://github.com/arduino-libraries/ArduinoBLE


body:
I need to have the firmware stored somewhere on the board in order to get back to it after flashing a new firmware.

Is there a way to store a backup of the firmware somewhere, and use a button to erase a newer firmware and get back to the old one, without re-flashing the old firmware again ?

title: Firmware backup and restore

Answers: 1

body:
Yes. You need to create a `factory` partition and upload your bin file to there.

You can read more about ESP32 partitions [here](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html)

Note that none of the partition schemes in the ESP32 core have factory partitions, so you will need to create a custom one and link it to a menu entry (look at the boards.txt file to see how that is done).

The existing partition files are just `.csv` files within the ESP32 core. Copy one and modify it, then link that to a menu entry using the new file name.


body: I am doing project and I used optical mouse IC sensor M116504386 with 16 pins and I don't know how to get this sensor libraries to interface it with arduino uno.

title: Optical mouse sensor M116504386 arduino libary

Answers: 0


body: So i am trying to stack these two shield on arduino, now the problem here is that i guess there is a conflict between the pins of arduino being used by both shields, so can anyone suggest a solution?

title: Any possible way to stack Motor Driver shield L293D with Xbee Shield v03 on arduino?

Answers: 1

body:
Read the documentation for both boards. They should list the pins used. Their associated libraries will define variables to which you can assign non-conflicting pins. Review the sample code provided as well. Usually, the sample code included setting the pins to use, even if the code only sets them to their default.

There is another possibility. I don’t think this is the case, but I’ve run into this issue with different shields. If the shields use I2C, they may need to have jumpers shorted to set an address.


body:
I've found lots of issues about serial ports not showing up at all, but none about what I'm experiencing.

Sometimes I can see my Arduino Mega 2560 in the ports list, and sometimes I can't. I've tried unplugging, replugging, rebooting my PC, and installing various CH34X USB drivers

Is there some way I can troubleshoot this issue to work out where things are going wrong?

EDIT: I have a Macbook Pro 2017 with Thunderbolt 3.0 ports connected to an adapter that lets me plug in USB. The Mega is a CH340G -> Wemos® Mega +WiFi R3 Module ATmega2560+ESP8266 32Mb Memory USB-TTL CH340G Compatible For Arduino Mega NodeMCU ESP8266.

EDIT #2: It looks like it's working again, all I did was switch around some of the DIP switches and change it from RX/TX0 to RX/TX3, sometimes when that stops working ill change it back to RX/TX0 and itll start working again. I suspect it has something to do with the USB-C adapter but haven't nailed it down yet.

title: Arduino OSX Mojave - Serial port only shows sometimes

Answers: 1

body:
A colleague at work was struggling with a similar problem just two days ago.

He said he resolved it by reinstalling the USB driver. I did not pay much attention to more details (because I did not have that problem). If you can not work how to reinstall and none can advise how, I can ask him on Monday.

In the meantime here are a couple of reinstall the USB driver links:

https://www.roland.com/global/support/support_news/18091014/

https://forum.arduino.cc/index.php?topic=570440.0

https://support.serato.com/hc/en-us/articles/115001883474-macOS-High-Sierra-10-13-macOS-Mojave-10-14-and-above-driver-install-process

Hopefully one of these will help you.

Here is the link that my colleague followed:

https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver

All I can add is that this one worked for him. He has I have High Sierra (version 10.13.3) and needed to reboot after the installation.


body:
For a project where I intend to use an arduino and an accelerometer to get rpm of an diesel / gasoline engine i intend to use following solution.
I glued an mma8453 accelerometer to a neodium magnet which will be placed on a metallic part of the engine.
Using an arduino I am reading values from accelerometter and calculate one final value which is sqrt (acc.x^2 + acc.y^2 + acc.z^2), and also get millis for each value.
The values looks like this:

First column = millis, second acc value and third I identified maximums and millis since last maximum for them. Assuming that for an engine you have to max's per revolution I can calculate rpm of the engine.

My issue is that I have no idea how to write a function to do that.

Any help really appreciated

Thanks

    269503 310
    269504 303
    269506 334
    269507 326
    269509 331
    269510 330
    269512 380
    269513 377
    269514 392
    269516 400
    269517 339
    269519 393
    269520 368
    269521 353
    269523 346
    269524 316
    269527 330
    269528 281
    269530 196
    269531 195
    269532 162
    269534 119
    269535 140
    269537 132
    269538 90
    269539 99
    269541 122
    269542 168
    269544 224
    269545 219
    269546 211
    269548 268
    269549 301
    269551 334
    269552 332
    269554 316
    269555 329
    269556 379
    269558 363
    269559 381
    269561 388
    269562 403
    269564 400
    269565 420 49
    269566 388
    269569 360
    269570 346
    269572 259
    269573 276
    269574 284
    269576 242
    269577 207
    269579 192
    269580 145
    269582 119
    269583 113
    269584 45
    269586 125
    269587 142
    269589 123
    269590 205
    269591 243
    269593 304
    269594 308
    269596 305
    269597 298
    269599 321
    269600 340
    269601 360
    269603 380
    269604 384
    269606 370
    269607 372
    269608 413
    269611 441 46
    269612 395
    269614 355
    269615 332
    269617 290
    269618 317
    269619 286
    269621 227
    269622 190
    269624 172
    269625 199
    269627 146
    269628 154
    269629 177
    269631 176
    269632 156
    269634 136
    269635 174
    269636 212
    269638 260
    269639 318
    269641 291
    269642 321
    269644 304
    269645 315
    269646 343
    269648 339
    269649 360
    269651 393
    269652 390
    269654 305
    269656 405
    269657 458 46
    269659 358
    269660 372
    269662 339
    269663 277
    269664 298
    269666 241
    269667 203
    269669 208
    269670 185
    269672 130
    269673 165
    269674 105
    269676 87
    269677 109
    269679 128
    269680 176
    269681 229
    269683 226
    269684 271
    269686 343
    269687 307
    269688 320
    269690 318
    269691 322
    269693 322
    269694 369
    269697 363
    269698 413
    269699 399
    269701 388
    269702 426 45
    269704 395
    269705 380
    269707 342
    269708 311
    269709 309
    269711 315
    269712 221
    269714 227
    269715 198
    269716 113
    269718 111
    269719 88
    269721 44
    269722 69
    269723 107
    269725 158
    269726 200
    269728 232
    269729 247
    269731 313
    269732 338
    269733 348
    269735 366
    269736 339
    269739 348
    269740 377
    269741 378
    269743 385
    269744 394
    269746 403
    269747 447
    269749 454 47
    269750 398
    269751 380
    269753 302
    269754 245
    269756 299
    269757 310
    269758 238
    269760 206
    269761 180
    269763 108
    269764 81
    269766 83
    269767 11
    269768 119
    269770 106
    269771 169
    269773 245
    269774 270
    269775 311
    269777 338
    269778 341
    269780 332
    269782 337
    269783 337
    269785 380
    269786 387
    269788 382
    269789 373
    269791 398
    269792 414 43
    269793 408
    269795 387
    269796 374
    269798 285
    269799 290
    269801 326
    269802 266
    269803 211
    269805 221
    269806 191
    269808 120
    269809 175
    269810 63
    269812 147
    269813 59
    269815 120
    269816 183
    269817 196
    269819 252
    269820 301
    269822 334
    269824 325
    269826 334
    269827 310
    269828 351
    269830 354
    269831 358
    269833 373
    269834 379
    269835 332
    269837 386
    269838 404 46
    269840 383
    269841 385
    269843 332
    269844 266
    269845 301
    269847 282
    269848 188
    269850 199
    269851 182
    269852 128
    269854 163
    269855 119
    269857 120
    269858 140
    269860 120
    269861 129
    269862 212
    269864 230
    269865 241
    269868 290
    269869 304
    269871 340
    269872 350
    269873 327
    269875 323
    269876 351
    269878 369
    269879 387
    269880 379
    269882 380
    269883 421 45
    269885 373
    269886 364
    269888 360
    269889 305
    269890 302
    269892 266
    269893 249
    269895 202
    269896 229
    269897 136
    269899 122
    269900 128
    269902 49
    269903 98
    269904 107
    269906 158
    269907 211
    269910 235
    269911 225
    269913 269
    269914 314
    269915 341
    269917 335
    269918 325
    269920 348
    269921 410
    269923 375
    269924 404
    269925 419
    269927 425
    269928 442 45
    269930 436
    269931 400
    269932 393
    269934 326
    269935 259
    269937 307
    269938 265
    269940 220
    269941 199
    269942 183
    269944 86
    269945 83
    269947 98
    269948 23
    269949 65
    269952 124
    269953 152
    269955 221
    269956 249
    269957 287
    269959 350
    269960 331
    269962 323
    269963 341
    269964 338
    269966 389
    269967 388
    269969 380
    269970 370
    269972 358
    269973 415 45
    269974 403
    269976 377
    269977 381
    269979 338
    269980 328
    269982 284
    269983 246
    269984 197
    269986 178
    269987 230
    269989 162
    269990 171
    269991 141
    269993 258
    269995 138
    269997 111
    269998 163
    270000 212
    270001 192
    270002 304
    270004 287
    270005 294
    270007 349
    270008 309
    270009 334
    270011 332
    270012 364
    270014 361
    270015 408
    270017 336
    270018 421
    270019 432 46
    270021 361
    270022 361
    270024 342
    270025 271
    270027 288
    270028 310
    270029 235
    270031 218
    270032 166
    270034 136
    270035 146
    270036 102
    270039 78
    270040 99
    270042 122
    270043 105
    270044 181
    270046 222
    270047 293
    270049 299
    270050 299
    270052 318
    270053 349
    270054 344
    270056 349
    270057 382
    270059 381
    270060 412
    270062 380
    270063 397
    270064 425 45
    270066 381
    270067 367
    270069 332
    270070 272
    270071 291
    270073 296
    270074 178
    270076 177
    270077 190
    270080 123
    270081 146
    270082 107
    270084 85
    270085 108
    270087 117
    270088 148
    270089 234
    270091 223
    270092 238
    270094 283
    270095 301
    270097 332
    270098 331

title: Getting "spikes" from an array of values - measure rpm using accelerometter

Answers: 3

body:
A simple approach would be to filter the signal using a low-pass filter, and then just calculate the time between two zero crossings.

Here's an example that works on your data. It's written in Python for easy testing and plotting, but trans-coding it to C++ should be trivial.

[![Plot of original data, filtered data using an EMA, and the calculated RPM][1]][1]

I used an [Exponential Moving Average low-pass filter](https://tttapa.github.io/Pages/Mathematics/Systems-and-Control-Theory/Digital-filters/Exponential Moving Average/Exponential-Moving-Average.html) to get rid of the noise. Depending on the frequencies involved, you can change the shift factor. The higher this factor, the lower the cut-off frequency, and the greater the phase shift.

I chose a fixed DC offset, but if necessary, you could use another (very slow) filter to get rid of it before applying the zero-cross detection.

If you want to, you could use both zero crossings. Use the average of the two last RPM measurements in that case, to compensate for asymmetric waveforms.

You could add another EMA to smooth out the RPM measurements.

```python
class ZeroCrossRPMCounter:
    def __init__(self,
                 max_rpm: float):
        self.min_distance = int(round(60_000 / max_rpm))

        self.first_crossing = True
        self.time_of_last_crossing = 0
        self.rpm = float('nan')
        self.previous_value = 0

    def __call__(self, time_ms: int, value: int):
        new_crossing = self.previous_value >= 0 and value < 0
        if new_crossing:
            if self.first_crossing:
                self.time_of_last_crossing = time_ms
                self.first_crossing = False
            elif (time_ms - self.time_of_last_crossing) >= self.min_distance:
                self.rpm = 60_000 / (time_ms - self.time_of_last_crossing)
                self.time_of_last_crossing = time_ms
            else:
                new_crossing = False
        self.previous_value = value
        return new_crossing

class EMA_shift_round:
    def __init__(self, shiftfac: int, initial: int = 0):
        self.shiftfac = shiftfac
        self.fixedPointOneHalf = 1 << (shiftfac - 1)
        self.z = initial << shiftfac

    def __call__(self, x: int):
        self.z += x
        shifted = (self.z + self.fixedPointOneHalf) >> self.shiftfac
        self.z -= shifted
        return shifted

if __name__ == '__main__':
    import numpy as np
    from matplotlib import pyplot as plt

    # Load the data
    data = np.genfromtxt('rpm-ctr-data.csv', delimiter='\t', dtype=np.int)
    time, signal = data[:, 0], data[:, 1]
    t_start, t_end = time[0] * 1e-3, time[-1] * 1e-3

    # Find the DC offset
    offset = int(round(np.mean(signal)))
    print(offset)

    # Initialize the filter and RPM counter
    lp_filter = EMA_shift_round(3)
    counter = ZeroCrossRPMCounter(2000)

    # Iterate over the data, filter it, and count the RPM
    peaks = []
    rpms = []
    filtered = np.zeros(len(time))
    for n in range(len(time)):
        filtered[n] = lp_filter(signal[n] - offset)
        new_crossing = counter(time[n], filtered[n])
        if new_crossing:
            peaks.append(time[n] * 1e-3)
            rpms.append(counter.rpm)

    # Plot the results
    plt.figure(figsize=(10, 6))
    plt.subplot(3, 1, 1)
    plt.title('Original signal')
    plt.plot(time * 1e-3, signal)
    for peak in peaks:
        plt.axvline(peak, color='red')
    plt.xlim((t_start, t_end))
    plt.subplot(3, 1, 2)
    plt.title('Filtered signal')
    plt.plot(time * 1e-3, filtered)
    for peak in peaks:
        plt.axvline(peak, color='red')
    plt.axhline(0, color='black', linestyle=':')
    plt.xlim((t_start, t_end))
    plt.subplot(3, 1, 3)
    plt.title('RPM measurements')
    plt.plot(peaks, rpms, '-o')
    plt.axhline(np.mean(rpms[1:]), color='red', linestyle=':')
    plt.xlim((t_start, t_end))
    plt.xlabel("Time [s]")
    plt.tight_layout()
    plt.show()
```

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

body:
I think most cars use a magnetic pickup next to the fly wheel to derive engine timing.  The method picked here is likely to have several problems.  For example, how to avoid picking up the shock of more than one cylinder compressing and exploding.  Or, perhaps the motor developed on is out of balance.  And a more nominal motor vibrates less making the project difficult to apply universally.

That said, using [FFTs (Fast Fourier Transforms)][1] is an alternative but fundamentally similar approach to detecting zero crossings for finding fundamental frequencies, and hence the engine's RPM.

This ["FFT on an Arduino"][2] article describes how to implement Fast Fourier Transforms on an Arduino.  It uses the FFT libraries hosted [here on github][3].

  [1]: https://en.wikipedia.org/wiki/Fast_Fourier_transform
  [2]: https://www.norwegiancreations.com/2017/08/what-is-fft-and-how-can-you-implement-it-on-an-arduino/
  [3]: https://github.com/kosme/arduinoFFT

body:
The approach suggested by tttapa is an excellent suggestion. But just to
give you more options, you can consider using an [hysteretic][] crossing
detector instead of a filter. The hysteresis in a comparator consists of
having one threshold value for detecting the high → low transition, and
another, higher value, for the low → high transition. This tends to
provide good immunity against noise, as noise spikes will not be able to
trigger false transitions as long as they are smaller than the
hysteresis (i.e. the difference between the thresholds).

Here is an example function that performs this detection. If you feed it
all your data samples, it will always return `false`, except exactly
_once_ per signal period.

```c++
const int LOW_THRESHOLD = 220;
const int HIGH_THRESHOLD = 300;

/* Returns true when a high threshold crossing is detected. */
void crossing_detector(int x)
{
    static enum { BELOW, ABOVE } state;
    if (state == BELOW && x >= HIGH_THRESHOLD) {
        state = ABOVE;
        return true;
    }
    if (state == ABOVE && x < LOW_THRESHOLD) {
        state = BELOW;
    }
    return false;
}
```

Now, it is perfectly possible to combine tttapa's filter idea with this
hysteretic crossing detector. The issue with the low pass filter is that
it is tricky to find the right time constant. If you filter too
aggressively, you may kill the signal at high RPMs. If you don't filter
enough, you may end up keeping enough noise to trigger false zero
crossings. If you use an hysteretic detector instead of a plain
zero-crossing detector, then you will be able to use less aggressive
filtering, as you will not be sensitive to the small residual noise.

[hysteretic]: https://en.wikipedia.org/wiki/Hysteresis


body:
I have a [433Mhz Superheterodyne receiver][1] and a hand set remote of similar frequency, I'm using the [RC-Switch library][2] and I couldn't find a better way than using the "numbers" that I'm receiving like this:
<!-- language-all: lang-cpp -->

    #include <RCSwitch.h>

    RCSwitch mySwitch = RCSwitch();

    void setup() {
      Serial.begin(9600);
      mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
      pinMode(13, OUTPUT);
    }

    void loop() {
      if (mySwitch.getReceivedValue() == 7264305) {
        digitalWrite(13, LOW);
      }
      if (mySwitch.getReceivedValue() == 7264308) {
        digitalWrite(13, HIGH);
      }
      if (mySwitch.getReceivedValue() == 7264306) {
        mySwitch.resetAvailable();
      }
    }

Is there any other (better?) way than just using the "numbers" simply like that or everyone are using their remote commands like I'm using?

  [1]: https://www.aliexpress.com/item/Wholesale-433-Mhz-Superheterodyne-RF-Receiver-and-Transmitter-Module-ASK-kits-with-antenna-For-Arduino-Diy/32799575156.html
  [2]: https://github.com/sui77/rc-switch

title: Is this the right way of using an RF communication?

Answers: 1

body:
Credits for this answer are mainly for jsotola (see his remarks above). But I want to show an alternative to the `if` statements, and a way to get the last 4 bits:

1. In case you want to check for the least significant bits, use `((mySwitch.getReceivedValue() & 0xFFFFF0)`
2. TO check for the least significant four bits (the data you want to act upon), use `((mySwitch.getReceivedValue() & 0xF)`
3. Use a switch statement instead of the `if` statement; also in theory (I don't know the code of `mySwitch.getReceivedValue()` does not need to be executed multiple times.

So you get something like this:

    void loop()
    {
      unsigned long receivedValue = mySwitch.getReceivedValue(); // Call function only once

      if ((receivedValue & 0xFFFF0) == 0x6ED830)
      {
        // Process action
        switch (receivedValue & 0xF)
        {
        case 0x5:
          digitalWrite(13, LOW);
          break;

        case 0x8:
          digitalWrite(13, HIGH);
          break;

        case 0x6:
          mySwitch.resetAvailable();
          break;

        default: // All other values
          break; // Ignore
      }
    }


body:
I have an Arduino Uno. It's role is to echo back what it receives.
But if I send it a stream of ascii characters it starts to error after the first one. Occasionally it gets the second character correct but often not.

If I delay each character then it works ok. I couldn't see this limitation mentioned in the SoftwareSerial library: https://www.arduino.cc/en/Reference/SoftwareSerial

The Arduino is running the following code:
<!-- language-all: lang-cpp -->

    #define BT_RX_PIN 16 // A2
    #define BT_TX_PIN 17 // A3
    #include <SoftwareSerial.h>
    SoftwareSerial OtherSerial(BT_RX_PIN, BT_TX_PIN);

    void setup()
    {
      Serial.begin(9600);  // not used
      OtherSerial.begin(9600);
    }

    void loop()
    {
      if (OtherSerial.available()) {
        char value = OtherSerial.read();
        String stri = "Received: ";
        stri += value;
        OtherSerial.println(stri);
      }
    }

The limitations do say "If using multiple software serial ports, only one can receive data at a time.".  I don't have multiple software serial ports though I do have an instance of the "normal" serial port but I'm not sending any data to it... but perhaps even just initialising it is enough to disrupt seamless communication with the SoftwareSerial port?

Using the following test code for serial communication from a Raspberry Pi (using logic level conversion to go from 5V -> 3.3V and visa versa):

    import time

    def write(msg, delay):
      for char in msg:
        with open("/dev/ttyAMA0", "w") as f:
          f.write(char)
          time.sleep(delay)

    write("hello", 0.01)

I got the following results (repeated 10 times at each delay time and averaged):

    Delay (ms)   |   Success rate
    10           |   100 %
    9            |   100 %
    8            |     0 %
    5            |     0 %
    1            |     0 %

A delay of 9 ms between each character means the communication rate falls from ~ 960 characters per second (9600 baud / 10 bits per 7 bit character) to ~ 100 characters per second (1 / (1 / 960 characters per second + 9ms)).  Is this right?  Perhaps I'm doing something else wrong / set it up wrong in software / hardware?

title: What is the best delay to use between characters sent to the serial port

Answers: 2

body:
SoftwareSerial has a considerable overhead. It can often send at 115200 successfully but 9600 is about its limit for receiving, and you're trying both send and receive. In addition, for each character your code receives, it transmits considerably more than that 1 character (11 characters, by my count). It isn't too surprising that it would fall behind. You will need to either reduce the size of what you echo or reduce the rate at which you send characters to it (which is what you accomplished with your delay) so that the transmission (echo) rate can keep up.

Update:

The OP reports success with continuous reception by, and transmission from, the Arduino at 57600 baud (but not at the same time). The transmission rate would be consistent with my experience transmitting at 115200 baud (blindly and for short bursts, to reconfigure ESP8266-01s that were shipped with a preset 115200 rate.

body:
Simply put, a serial port implemented in software requires the program to sample the input pin fast enough to detect every transition.  To satisfy the [Nyquist frequency rate][1] we need the program to sample the data twice as fast as we expect the data to change.

A serial port implemented in hardware might only need to be sampled at 1/16 this rate assuming the data size is 8 bits.

Your program implements a serial port in software which is admirably keeping up with the received data.  However, when you tell the program to send the message "Received" plus the string that was received, the program stops looking at the serial input pin long enough for data to go missing.

By far the easiest solution would be to use a hardware implemented serial port.  If this is not possible consider approaching the problem using interrupts.  However, while a powerful programming tool, interrupts can be difficult to implement and hard to debug.

  [1]: https://en.wikipedia.org/wiki/Nyquist_frequency


body:
I'm currently using google geolocation to get location data to one nodemcu and sending it through serial to another Arduino.
The serial command I'm getting right now is,
<!-- language-all: lang-cpp -->

    1.450187T103.824745

I'm using the following code to parse it.

     if (Serial.available())  {
        char c = Serial.read();  //gets one byte from serial buffer
        //if (c == '\n') {  //looks for end of data packet marker
        if (c == '\n') {
         // Serial.println(readString); //prints string to serial port out
          //do stuff
          substring = readString.substring(0,8);
          lati = substring;
          loc = readString.indexOf("T");
          substring = readString.substring(loc+1, loc+11);
         longi = substring;
           readString=""; //clears variable for new input
          substring="";

        }
        else {
          readString += c; //makes the string readString
        }
      }

It works most of the time but sometimes I get 'T' inside the string as well.
like this

    lat=1.450146&longi=102464T103
What's wrong in my code?

title: Parsing Arduino Receiving Strings

Answers: 2

body:
You could use a `for` loop to get the location of the "T", then split the `String` into 2 `Strings`.
<!-- language-all: lang-cpp -->

    // 4104 bytes.
    String readString = "1.450187T103.824745";
    String lati, longi;

    void setup(){

      Serial.begin(9600);

      //do stuff code
      for(int i = 0; i < readString.length(); i++){
        if(readString.charAt(i) == 'T'){
          lati = readString.substring(0, i);
          longi = readString.substring(i + 1);
          break;
        }
      }

      Serial.print("lati=");
      Serial.println(lati);
      Serial.print("longi=");
      Serial.println(longi);

    }

    void loop(){}

body:
with readBytesUntil and C string

    if (Serial.available()) {
      char buff[32];
      int l = Serial.readBytesUntil('\n', buff, sizeof(buff));
      if (l > 0 && buff[l - 1] == '\r') {
        l--; // to remove \r if it is there
      }
      buff[l] = 0; // terminate the string
      char* p = strchr(buff,'T'); // returns pointer in string
      if (p != NULL) {
        *p = 0; // write 0 as char at pointer to terminate the first part
        p++; // move the pointer to next char
        Serial.println(buff);
        Serial.println(p);
      } else {
        Serial.println(buff);
      }
    }


body:
**I am seeking HW.**

I would like to make keyboard with enhanced functions (RGB backlite, macros, programmed profiles etc) driven by some small MCU (Arduino Micro Pro or something similar).

To support communication, it needs to use **I2C** and **SPI**(for display and other devices), use **USB** (to communicate with PC) and use **Serial** to communicate with other Arduinos/MCUs.

The main function would be scanning keyboard matrix (like from 8x8 to 16x8 in maximal variant). The matrix would use diodes for NKRO (not ghosting, any key combination possible).

It would be really nice to have HW, where I could use 3 full ports as input (or as output) with benefit of reading/writing them with only one assembly instruction for 8bit manipulation, not to cycle over array of pins and manipulate each one independently (digitalRead/digitalWrite, which use tons of instructions to determine ports and pin and then combine them together to obtain one 8bit variable). Something like:

    byte dataout,datain1,datain2;
    PORT_A=dataout;
    datain1=PORT_B;
    datain2=PORT_C;

**Does anyone know, if there is such nonexpensive MCU and which type it is?**

On typical Arduino each port is "poluted" by some importaint communications pins, so none of them can be used as full 8bit I/O.

**Second question: Is there a reason, why are the most used communication pins spread over range of different ports and not collected on one port, while leaving other ports as full 8bit GPIO useable?**

Thank for all answers.

title: Using 8bit ports as 8bit I/O variable (while using USB,I2C, SPI and Serial) - keyboard

Answers: 2

body:
The expander MCP23S17 (spi), with a CS, is a good extention (16 I/O configurable)
That should do it !

body: I'd go with a Mega2560. Up to 86 IO if you use a board that breaks out all IO pins, otherwise 70 on the Arduino version. With a little attention to the physical chip pin mapping to the board you can have several full 8-bit ports while also using SPI, I2C, and Serial via one of 4 UARTs. I'd recommend keeping Tx(0)/Rx(0) free for comm's with PC via USB adapter for code download/debug. Tx1/Rx1, Tx2/Rx2, Tx3/Rx3 are them free for 0/5V level comm's, or other levels via USB adapter, RS232 adapter, etc.


body:
I have tried all the GPIO pins listed here:[![This is a schematic of the ESP32 cam pinouts. I have tried every one of the GPIO pins with errors in initializing the SD Card][1]][1]I am following this tutorial to save a picture using the ESP32 cam board. I am trying to add a PIR sensor.
https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card/

whenever I try to use any pins to enable wake on external pin high, there is an error either because of interruption with the camera initiation or sd card.

here is my PIR sensor
https://www.robotshop.com/en/wide-angle-pir-motion-sensor.html?gclid=EAIaIQobChMI0Y7QuaOA4wIVl_5kCh3zYA4OEAQYASABEgJFPvD_BwE[![PIR sensor schematic][2]][2]
here is the code I am using

        /*********
          Rui Santos
          Complete project details at https://RandomNerdTutorials.com/esp32-cam-    take-photo-save-microsd-card

          IMPORTANT!!!
           - Select Board "ESP32 Wrover Module"
          - Select the Partion Scheme "Huge APP (3MB No OTA)
        - GPIO 0 must be connected to GND to upload a sketch
        - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET  button to put your board in flashing mode

       Permission is hereby granted, free of charge, to any person obtaining a copy
      of this software and associated documentation files.
      The above copyright notice and this permission notice shall be included in all
      copies or substantial portions of the Software.
    *********/

     #include "esp_camera.h"
     #include "esp_timer.h"
     #include "img_converters.h"
     #include "Arduino.h"
     #include "fb_gfx.h"
     #include "fd_forward.h"
     #include "fr_forward.h"
     #include "FS.h"                // SD Card ESP32
     #include "SD_MMC.h"            // SD Card ESP32
     #include "soc/soc.h"           // Disable brownour problems
     #include "soc/rtc_cntl_reg.h"  // Disable brownour problems
     #include "dl_lib.h"
     #include "driver/rtc_io.h"
     #include <EEPROM.h>            // read and write from flash memory

        // define the number of bytes you want to access
         #define EEPROM_SIZE 1

         // Pin definition for CAMERA_MODEL_AI_THINKER
         #define PWDN_GPIO_NUM     32
         #define RESET_GPIO_NUM    -1
         #define XCLK_GPIO_NUM      0
         #define SIOD_GPIO_NUM     26
         #define SIOC_GPIO_NUM     27

         #define Y9_GPIO_NUM       35
         #define Y8_GPIO_NUM       34
         #define Y7_GPIO_NUM       39
         #define Y6_GPIO_NUM       36
         #define Y5_GPIO_NUM       21
         #define Y4_GPIO_NUM       19
         #define Y3_GPIO_NUM       18
         #define Y2_GPIO_NUM        5
         #define VSYNC_GPIO_NUM    25
         #define HREF_GPIO_NUM     23
         #define PCLK_GPIO_NUM     22

         int pictureNumber = 0;

         void setup() {
           WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

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

           camera_config_t config;
           config.ledc_channel = LEDC_CHANNEL_0;
           config.ledc_timer = LEDC_TIMER_0;
           config.pin_d0 = Y2_GPIO_NUM;
           config.pin_d1 = Y3_GPIO_NUM;
           config.pin_d2 = Y4_GPIO_NUM;
           config.pin_d3 = Y5_GPIO_NUM;
           config.pin_d4 = Y6_GPIO_NUM;
           config.pin_d5 = Y7_GPIO_NUM;
           config.pin_d6 = Y8_GPIO_NUM;
           config.pin_d7 = Y9_GPIO_NUM;
           config.pin_xclk = XCLK_GPIO_NUM;
           config.pin_pclk = PCLK_GPIO_NUM;
           config.pin_vsync = VSYNC_GPIO_NUM;
           config.pin_href = HREF_GPIO_NUM;
           config.pin_sscb_sda = SIOD_GPIO_NUM;
           config.pin_sscb_scl = SIOC_GPIO_NUM;
           config.pin_pwdn = PWDN_GPIO_NUM;
           config.pin_reset = RESET_GPIO_NUM;
           config.xclk_freq_hz = 20000000;
           config.pixel_format = PIXFORMAT_JPEG;

           if(psramFound()){
             config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ +  QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
            config.jpeg_quality = 10;
            config.fb_count = 2;
          } else {
            config.frame_size = FRAMESIZE_SVGA;
            config.jpeg_quality = 12;
            config.fb_count = 1;
          }

          // Init Camera
          esp_err_t err = esp_camera_init(&config);
          if (err != ESP_OK) {
            Serial.printf("Camera init failed with error 0x%x", err);
            return;
          }

          //Serial.println("Starting SD Card");
          if(!SD_MMC.begin()){
            Serial.println("SD Card Mount Failed");
            return;
          }

          uint8_t cardType = SD_MMC.cardType();
          if(cardType == CARD_NONE){
            Serial.println("No SD Card attached");
            return;
          }

          camera_fb_t * fb = NULL;

          // Take Picture with Camera
          fb = esp_camera_fb_get();
          if(!fb) {
            Serial.println("Camera capture failed");
            return;
          }
          // initialize EEPROM with predefined size
          EEPROM.begin(EEPROM_SIZE);
          pictureNumber = EEPROM.read(0) + 1;

          // Path where new picture will be saved in SD Card
          String path = "/picture" + String(pictureNumber) +".jpg";

          fs::FS &fs = SD_MMC;
          Serial.printf("Picture file name: %s\n", path.c_str());

          File file = fs.open(path.c_str(), FILE_WRITE);
          if(!file){
            Serial.println("Failed to open file in writing mode");
          }
          else {
            file.write(fb->buf, fb->len); // payload (image), payload length
            Serial.printf("Saved file to path: %s\n", path.c_str());
            EEPROM.write(0, pictureNumber);
            EEPROM.commit();
          }
          file.close();

          // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
          pinMode(4, OUTPUT);
          digitalWrite(4, LOW);
          rtc_gpio_hold_en(GPIO_NUM_4);

          delay(2000);
          Serial.println("Going to sleep now");
          delay(2000);
          esp_deep_sleep_start();
          Serial.println("This will never be printed");
        }

        void loop() {

        }

This is the thing I am trying to add. but no matter which pins i chose there are errors. I can add the error if that would be helpful.

    esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)

  [1]: https://i.stack.imgur.com/ksS4E.png
  [2]: https://i.stack.imgur.com/FRWs1.png

title: esp32 cam and PIR sensor

Answers: 1

body:
Software:

It may be that one of the included libraries (software) you are using depends on pin 3 (E32_RST) of the ESP32 going low in order to operate as expected (wake up and take a picture).  Using an alternate pin may wake up the ESP32 but may not behave as expected.

Hardware:

[This schematic of the ESP32 Camera][1] shows how switch K1 is connected to pin 3 of the ESP32.  There is a capacitor C7 and resistor R6 likely used to mitigate K1 switch bouncing and to pull pin 3 high when switch K1 is not pressed.  When switch K1 is pushed it pulls pin 3 to ground waking up the ESP32 to take a picture.

The PIR specified changes its output to high when activated according to its data sheet.  This is opposite of what the ESP32 needs to see at pin 3 in order to take a picture.  It appears an inverter is needed between the PIR and pin 3 of the ESP32.  An open collector type of inverter would be best as this type of driving circuit can be attached where K1, C7 & R6 come together with out interfering with the their (the existing components') operation.  This is the subject of [this stackexchange question / answer][2].

  [1]: https://i.redd.it/yv050peu22p21.png
  [2]: https://electronics.stackexchange.com/questions/30238/how-to-invert-a-digital-signal


body:
I am programming an Arduino.  In the same .ino file as `setup()` and `loop()` I have defined the following:

    void setup()
    {
      // setup code
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void loop()
    {
      // loop code
    }

But on compiling it gives the error:

    sketch_v1:37:22: error: 'CYCLE' was not declared in this scope
     String cycleToString (CYCLE cycle) {
                          ^
    /Users/.../sketch_v1.ino: In function 'String cycleToString(CYCLE)':
    sketch_v1:37:31: error: 'String cycleToString(CYCLE)' redeclared as different kind of symbol
     String cycleToString (CYCLE cycle) {
                                      ^
    /Users/.../sketch_v1.ino:37:8: note: previous declaration 'String cycleToString'
     String cycleToString (CYCLE cycle) {
            ^

Note that the `enum class` is fine and works as intended but if I try to add the function relying on the `CYCLE` type it then errors.

title: class enum was not declared in this scope

Answers: 3

body:
Note this is not an answer, since your code compiles perfectly. (adding a default/empty setup/loop function).

However, I want to give some improvements that cannot fit in a comment:

1. (optional) Align { and } under each other. Some put the { behind the line, some on a new line; this is mostly preference. But aligning { and } is mostly more clear.
2. Put each type/enum value on a new line; this makes it easier to add comments above/after it.
3. Except for trivial cases, never return from a statement, except the last one. In your case the function is quite simple, but still it's better to keep the return only at the end of a function.
4. Use a `switch` statement instead of multiple `if` statements.

So you get:

    enum class CYCLE
    {
      TypeA,
      TypeB
    };

    String cycleToString (CYCLE cycle)
    {
      String str;

      switch (cycle)
      {
      case CYCLE::TypeA:
        str = "TypeA";
        break;

      case CYCLE::TypeB:
        str = "TypeB";
        break;

      default:
        str = "Undefined";
        break;
      }

      return str;
    }

body:
This is a known bug of Arduino builder, if you have functions before structs, classes or enums in sketch.

The sketch:

    void foo() {
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void setup() {
    }

    void loop() {
    }

is processed to this .cpp file

    #include <Arduino.h>
    #line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    #line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"

    #line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void foo();
    #line 7 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    String cycleToString(CYCLE cycle);
    #line 17 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void setup();
    #line 22 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void loop();
    #line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void foo() {
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void setup() {
    }

    void loop() {
    }

as you can see the forward declarations of functions are before the first function so before the enum.

The workaround for this bug is to follow good practice and declare all the structs, enums and classes before the first function definition.

body:
It works if you move the `enum class` to the top, i.e.:

    enum class CYCLE { TypeA, TypeB };

    void setup()
    {
      // setup code
    }

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void loop()
    {
      // loop code
    }


body:
I'm using the Sim800L module and the NEO6M GPS Module in combination with an Arduino nano to create a simple tracking device. I get the data from the GPS and try to upload it to my site with some simple PHP scripts. I'm using this code down here:
<!-- language-all: lang-cpp -->

    //the function - which is responsible for sending data to the web server
    void sendLocation(String lat, String lon){
     Sim800l.listen();
     //The line below sets the URL we want to connect to
     Sim800l.println("AT+HTTPPARA=\"URL\", \"http://" + ipAddress +  "/log_info.php?dev_id=13&lat=" + lat + "&lon=" + lon + "\"");
     waitUntilResponse("OK");
     //GO
     Sim800l.println("AT+HTTPACTION=0");
     waitUntilResponse("200");
     Serial.println("Location sent");
     gpsPort.listen();
    }

Unfortunately, when I try to use this code, in my serial monitor I get this message:

    AT+HTTPACTION=0
    OK
    +HTTPACTION: 0,302,171
    error

I Looked it up in the datasheet for the Sim800L, and the number 302 means "Found". I'm expecting the number 200 for "OK". I have no idea what I did wrong, the data is not being send to the web server for some reason. I hope you can help.
Thanks in advance!

EDIT:
The datasheet with all the errors for the Sim800L
https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf

title: Sim800L Uploading issues, HTTPACTION returns 0, 302, 701

Answers: 1

body: 302 is HTTP code returned by the server. It is used for redirection. Print the response with AT+HTTPREAD to see where does it redirectd.


body:
I want my LED to turn on gradually without using the `delay()` function and blocking the code.

Here's the code i came up with:

    int led_pin = 6;
    unsigned long millisTimer = 0;
    int PWMdelay = 5000;
    int condition = 0;
    int i = 0;
    void setup() {
     pinMode(led_pin, OUTPUT);
    }
    void loop() {
     if(condition == 1){
     if ((millis() - millisTimer) > PWMdelay){
      if(i<255){
       i++;
       millisTimer = millis();
      }

     }
      analogWrite(led_pin, i);
     }
    }

Is this the "right way" of slowing the PMW duration from 0 to 255 or there are alternative/better/easier ways?

title: PWM delay without blocking the code

Answers: 1

body:
Here is my take at this - I've followed the example code mentioned by other members and here is "FadeWithoutDelay"

```Arduino

const int ledPin = 11;
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 100;               // fade interval (milliseconds)
int brightness = 0;                      // how bright the LED is
int fadeAmount = 5;                      // how many points to fade the LED by

void setup()
{
  pinMode(ledPin, OUTPUT);  // set the digital pin as output:
}
void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;         // save the last state
    analogWrite(ledPin, brightness);        // Set the brightness
    brightness = brightness + fadeAmount;   // change the brightness for next time through the loop
    // reverse the direction of the fading at the ends of the fade:
    if (brightness <= 0 || brightness >= 255)
    {
      fadeAmount = -fadeAmount;
    }
  }
}

```


body:
I am going to make a project that needs four boards of Arduino which synchronization in time is needed. The project is about capturing the timestamp (in ms resolution) whenever something is crossing ultrasonic proximity sensor. The following are the modules I am going to use:

 1. Arduino Uno R3 4 units
 2. Ultrasonic Proximity sensor 4 units
 3. DS1302 RTC modules 4 units
 4. Micro SD Card modules 4 units

The boards will be placed in 4 different places which it is quite far from each other that makes it is hard to make wired connection. The detecting object will move back and forth during a certain interval of time, so that is why the time synchronization is needed.

My idea is, by using the timestamp from RTC modules, I turn all the boards together into deep sleep mode at the time I have set in the code and wake them up together after 10 seconds. I don't have any problem with RTC modules, but my problem lies in the millis() function which did not back to zero after woke up from deep sleep mode. I need this function since the DS1302 RTC does not provide ms resolution, yet I can not achieve sync if the millis() function does not back to zero.

I tried the code (edited with millis() added in the loop) from here:
https://www.youtube.com/watch?v=8fiYvnBDsDE

Do you have any solutions? Or another RTC module which provides ms resolution instead. Thank you

title: Millis() does not back to zero after woke up from deep sleep mode

Answers: 2

body: Store millis() at boot, and if (resetCause == "Deep-Sleep Wake") zero out the stored copy of millis().

body: I do not understand how you will get them to sync with each other. The RTC modules work great but there is no communications to set or update them and they do drift. With the RTC it will be easy to generate a timestamp using Unix time. There is a lot of information posted on how to do this.  syncing (making all the clocks the same) is where I believe your problem is. Consider adding WiFi to each and use NTP to sync everything, it would be automatic.


body: In regards to the arduino which has pwm pins, can I use these pins as normal input/output digital pins or not? Thanks in advance.

title: Can I use the PWM pins as regular digital input/output pins?

Answers: 1

body:
Yes you can use them as ordinary digital io pins. PWM is essentially a normal digital output pin that is repeatedly turned on and off at a high rate.

The magic is that the turning off and on is done in the hardware according to the duty cycle  (I.e. there is no need for software to perform the on/off operations) . This is why only some pins can do h/w PWM, because the PWM hardware is not added on to all pins.

If you are not using the pin for PWM, it is available for you to use as required.


body:
Alright so I'm having problems with my code. Its my first time using DH11

I keep on getting that temperature is 0 degrees so as the humidity

    #include "dht.h"
    #define dht_apin A0

    dht DHT;

    void setup(){

      Serial.begin(9600);
      delay(500);
      Serial.println("DHT11 Humidity & temperature Sensor\n\n");
      delay(1000);

    }

    void loop()
    {

        DHT.read11(dht_apin);

        Serial.print("Current humidity = ");
        Serial.print(DHT.humidity);
        Serial.print("%  ");
        Serial.print("temperature = ");
        Serial.print(DHT.temperature);
        Serial.println("C  ");

        delay(5000)

    }

What Im getting is basically

> Current humidity = 0.00%  temperature = 0.00C

title: 0 temperature & hummidity DH11

Answers: 1

body:
I have run into problems when using some `DHT` library versions.  May I suggest that you try using a different version of `dht.h`?

This version works for me (there is a [newer version][1] I have NOT tested):

dht.h (606B 6/12/2012)

 //
 //    FILE: dht.h
 // VERSION: 0.1.00
 // PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
 //
 //     URL: http://arduino.cc/playground/Main/DHTLib
 //
 // HISTORY:
 // see dht.cpp file
 //

 #ifndef dht_h
 #define dht_h

 #if ARDUINO >= 100
  #include "Arduino.h"
 #else
  #include "WProgram.h"
 #endif

 #define DHT_LIB_VERSION "0.1.00"

 class dht
 {
 public:
  int read11(uint8_t pin);
     int read22(uint8_t pin);
  double humidity;
  double temperature;

 private:
  uint8_t bits[5];  // buffer to receive data
  int read(uint8_t pin);
 };
 #endif
 //
 // END OF FILE
 //

  [1]: http://arduino.cc/playground/Main/DHTLib


body:
I have problem with communicating VB.Net-Arduino.

It seems the interrupt pause my serial communication line in `void loop() { ... }`. I don't know what to do, and I can't erase interrupts line since I got this code from another site and he said that the interrupt play important role in this code.

So, is there another method to keep interrupts like make a new void in the code? Could you help me, please?

here is the code:

```c++
//For MEGA 2560

int i = 0;
int j = 0;
int k = 0;

int x = 0;
int y = 0;
int z = 0;

int OK = 0;
int OK1 = 0;
int OK2 = 0;
int OK3 = 0;
int OK4 = 0;

int sinPWM[] = {
    0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22,
    23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43,
    44, 45, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64,
    65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 82, 83, 84,
    85, 86, 87, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102,
    104, 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117,
    118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131,
    132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
    145, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157,
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
    171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 179, 180, 181,
    182, 183, 184, 185, 185, 186, 187, 188, 189, 189, 190, 191, 192,
    193, 193, 194, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202,
    203, 203, 204, 205, 205, 206, 207, 208, 208, 209, 210, 210, 211,
    212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 219, 219,
    220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, 226, 226,
    227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
    233, 234, 234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238,
    238, 239, 239, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242,
    243, 243, 243, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246,
    246, 246, 246, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248,
    248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 247,
    246, 246, 246, 246, 246, 245, 245, 245, 245, 244, 244, 244, 244,
    243, 243, 243, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240,
    239, 239, 238, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234,
    234, 234, 233, 233, 232, 232, 231, 231, 230, 230, 229, 229, 228,
    228, 227, 227, 226, 226, 225, 225, 224, 224, 223, 223, 222, 221,
    221, 220, 220, 219, 219, 218, 217, 217, 216, 215, 215, 214, 214,
    213, 212, 212, 211, 210, 210, 209, 208, 208, 207, 206, 205, 205,
    204, 203, 203, 202, 201, 200, 200, 199, 198, 197, 197, 196, 195,
    194, 193, 193, 192, 191, 190, 189, 189, 188, 187, 186, 185, 185,
    184, 183, 182, 181, 180, 179, 179, 178, 177, 176, 175, 174, 173,
    172, 171, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161,
    160, 159, 158, 157, 156, 155, 154, 153, 152, 152, 151, 150, 149,
    148, 147, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135,
    134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 123, 122, 121,
    120, 119, 118, 117, 116, 115, 114, 112, 111, 110, 109, 108, 107,
    106, 105, 104, 102, 101, 100, 99, 98, 97, 96, 94, 93, 92, 91, 90,
    89, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 74, 73, 72, 71, 70,
    68, 67, 66, 65, 64, 62, 61, 60, 59, 58, 56, 55, 54, 53, 52, 50, 49,
    48, 47, 45, 44, 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 29, 28,
    27, 26, 24, 23, 22, 21, 19, 18, 17, 16, 14, 13, 12, 11, 9, 8, 7, 6,
    4, 3, 2, 1, 0
};

#define toggle 7

int sw;
int nilaiVB;
int potvolt = A1;                //Pengatur Tegangan
int potfreq = A2;                //Pengatur Frequency

float potvoltval;
float potfreqval;
float DataVolt;
float DataFreq;
float A;
float F;

String inputString = "";         // a String to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String In_1;
String In_2;

int Val1 = 0;
int Val2 = 0;

void setup() {
    Serial.begin(9600);
    inputString.reserve(200);

    pinMode(4, OUTPUT);
    pinMode(13, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(5, OUTPUT);

    cli();                            // stop interrupts
    TCCR0A = 0;                       //reset nilai
    TCCR0B = 0;                       //reset nilai
    TCNT0 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR0A = 0b10100001;              //phase correct pwm mode
    TCCR0B = 0b00000001;              //tidak ada prescaler

    TCCR2A = 0;                       //reset nilai
    TCCR2B = 0;                       //reset nilai
    TCNT2 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR2A = 0b10100001;              //phase correct pwm mode
    TCCR2B = 0b00000001;              //tidak ada prescaler

    TCCR3A = 0;                       //reset nilai
    TCCR3B = 0;                       //reset nilai
    TCNT3 = 0;                        //reset nilai
    //0b  : menulis bits dalam binary
    TCCR3A = 0b10100001;              //phase correct pwm mode
    TCCR3B = 0b00000001;              //tidak ada prescaler

    TCCR1A = 0;                       //reset nilai
    TCCR1B = 0;                       //reset nilai
    TCNT1 = 0;                        //reset nilai
    OCR1A = 509;                      // compare match value
    TCCR1B = 0b00001001;  //WGM12 bit is 1 for CTC mode and no prescaler

    TIMSK1 |= (1 << OCIE1A);          // memulai interrupts

    sei();                            // enable interrupts
}

// interrupt mulai ketika timer 1 cocok dengan OCR1A
ISR(TIMER1_COMPA_vect) {

    //=========================Phase A================================//

    if (i > 629 && OK == 0) {   // nilai akhir dari sample untuk pin 13
        i = 0;                  // mulai dari nilai awal sample
        OK = 1;                 // mengaktifkan pin 4
    }

    if (i > 629 && OK == 1) {   // nilai akhir dari sample untuk pin 4
        i = 0;                  // mulai dari nilai awal sample
        OK = 0;                 // mengaktifkan pin 13
    }

    x = round(A*sinPWM[i]); // nilai x berasal dari sample dan i berindex 0
    i = i+F;                    // ke posisi selanjutnya dari sample
    if (OK == 0) {
        OCR0B = 0;                      //pin 4 0
        OCR0A = x; //pin 13 memulai pembacaan sample
    }

    if (OK == 1) {
        OCR0A = 0;                      //pin 13 0
        OCR0B = x; //pin 4 memulai pembacaan sample
    }

    // jika nilai i mencapai 209, maka phase kedua akan dimulai
    if ((i >= 418) || OK1 == 1) {
        OK1 = 1;                  //mempertahankan if function

        //=========================Phase B============================//

        if (j > 629 && OK2 == 0) {  // nilai akhir dari sample untuk pin 10
            j = 0;                  // mulai dari nilai awal sample
            OK2 = 1;                // mengaktifkan pin 9
        }

        if (j > 629 && OK2 == 1) {  // nilai akhir dari sample untuk pin 9
            j = 0;                  //mulai dari nilai awal sample
            OK2 = 0;                // mengaktifkan pin 10
        }

        y = round(A*sinPWM[j]); // nilai y berasal dari sample dan i berindex 0
        j = j+F;                    // ke posisi selanjutnya dari sample
        if (OK2 == 0) {
            OCR2B = 0;              // pin 9 0
            OCR2A = y;              // pin 10 memulai pembacaan sample
        }

        if (OK2 == 1) {
            OCR2A = 0;              // pin 10 0
            OCR2B = y;              // pin 9 memulai pembacaan sample
        }
    }

    // jika nilai j mencapai 209, maka phase ketiga akan dimulai
    if ((j>= 418) || OK3 == 1) {
        OK3 = 1;                    // mempertahankan if function

        //=========================Phase C============================//

        if (k > 629 && OK4 == 0) {  // nilai akhir dari sample untuk pin 5
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 1;                // mengaktifkan pin 2
        }

        if (k > 629 && OK4 == 1) {  // nilai akhir dari sample untuk pin 2
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 0;                // mengaktifkan pin 5
        }

        z = round(A*sinPWM[k]); // nilai z berasal dari sample dan i berindex 0
        k = k+F;                    // ke posisi selanjutnya dari sample
        if (OK4 == 0) {
            OCR3B = 0;              // pin 2 0
            OCR3A = z;              // pin 5 memulai pembacaan sample
        }

        if (OK4 == 1) {
            OCR3A = 0;              // pin 5 0
            OCR3B = z;              // pin 2 memulai pembacaan sample
        }
    }
}

void loop() {
    sw = digitalRead(toggle);

    if (sw == 0) { //    VB
        if (stringComplete) {
            if (inputString.substring(0, 4) == "VOLT") {
                In_1 = inputString.substring(4);
                Val1 = In_1.toInt();
                A = Val1/1023; // Formula Pengontrolan Tegangan
                Serial.println(Val1);
            }
            if (inputString.substring(0, 4) == "FREQ") {
                In_2 = inputString.substring(4);
                Val2 = In_2.toInt();
                F = map(Val2, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
            }

            inputString = "";
            stringComplete = false;
        }
    }
    else if (sw == 1) { // Potensiometer
        potvoltval = analogRead(potvolt);
        A = potvoltval/1023; // Formula Pengontrolan Tegangan

        potfreqval = analogRead(potfreq);
        F = map(potfreqval, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
    }
}

void serialEvent() {
    while (Serial.available()) {
        // get the new byte:
        char inChar = (char) Serial.read();
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag so the
        // main loop can do something about it:
        if (inChar == '\n') {
            stringComplete = true;
        }
    }
}
```

And here are the interrupts position:
[![Interrupts][1]][1]

And i got the code from this [site][2]

And Here is my VB code

    Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            Me.CenterToParent()
            SerialPort1.PortName = "COM4"
            SerialPort1.BaudRate = 9600
            SerialPort1.Open()
            Timer1.Start()
            SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
            SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
        Catch ex As Exception
            MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
            Me.Close()
        End Try
    End Sub

    Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
        SerialPort1.Close()
    End Sub

    Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
        Try
            SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
        Catch ex As Exception
            MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
        End Try
    End Sub

    Private Sub TrackBar2_Scroll(sender As Object, e As EventArgs) Handles TrackBar2.Scroll
        Try
            SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
        Catch ex As Exception
            MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
        End Try
    End Sub
    End Class
And the design as well[![Design][3]][3]

  [1]: https://i.stack.imgur.com/QBKY4.png
  [2]: http://www.eprojectszone.com/how-to-generate-a-sine-wave-from-arduino-or-atmega-328/
  [3]: https://i.stack.imgur.com/9qkuz.png

title: Interrupts arduino interrupting serial comunication

Answers: 1

body:
Since the ISR being too long seems to be your main problem, I will address the possibility to set a flag in the ISR. See this code example (which is not a complete compilable example, only code to show the principle):

    volatile byte flag = 0;

    ISR(TIMER1_COMPA_vect) {
        flag = 1;
    }

    void loop(){
        if(flag){
            flag = 0; // resetting the flag for the next execution
            //execute the code here, that was previously in the ISR
        }
    }

First a flag variable is declared as volatile. This tells the compiler, that the value of this variable can change at any time and that the compiler cannot optimize it by using a cached value or other optimizations. This is always required, when you access a variable both in ISR's and the normal code.

In the actual ISR this flag is simply set to `1`. This takes very short time, so that no other interrupt (for example for Serial) will be blocked by it.

Then in our `void loop()` we are checking if the flag has a value, that isn't zero (every value other than zero will evaluate as `true`, so we don't need a comparison operator here). If yes, we first reset the flag to zero, so that another interrupt can set it again to 1. Then we are executing the other code, that was previously in your ISR. Since it now runs in normal code, it will not block Serial interrupts from happening.

---

"The ISR is too long" can also mean, that it is happening too often. Juraj already stated in his comment, that the interrupt happens "every 509 clock ticks". That is not very much. You can increase the time between 2 consecutive timer interrupts by using a prescaler. As doing just this would reduce the frequency of your output sinus wave, you would need to do some calculations, maybe only using every forth or so array element of the sinus wave. With this you are loosing precision in time, but you gain more computation time to do other things.

---

In general you always have to do a trade-of. The longer the code runs, that should be executed on a timer interrupt, the less precision will be possible with it. The code should always run considerable shorter, that the time between two consecutive interrupts.

Your code is not really understandable, since you didn't use speaking variable names and your comments are not written in english. From the structure I would guess, that it can be strongly optimized by you to execute shorter, but without understanding what the code really should do, that is only wild guessing.


body:
I want to apologise first and foremost, and say that I am very new to Arduinos!

I wanted to control the torque on a MG966R servo so that I can separate it into 4 different torque levels. I read that by adjusting the input voltage, you can run the servo at different speed, hence, i was thinking if I could incorporate a rotary potentiometer to adjust the speed of the servo.

Also wondering if changing angle stepsize of MG966R servo will affect torque in anyway?

Thanks all!

title: Possible to have different torque levels on MG966R servo with Rotary Potentiometer?

Answers: 1

body:
Generally it is not easy to control the torque of a standard servo, since mostly they aren't meant for that. A servo has an internal controller, which will read the input PWM signal and control the geared motor, so that the desired position will be reached. And to get there, the most servos will use the maximum torque. Also the torque of a servo motor depends on more variables, for example speed and type of load ([See here for more information about this][1].

> I read that by adjusting the input voltage, you can run the servo at different speed

That's not really true. Most servos only support a rather small voltage range, where they will work. You can get more torque, if you use a higher voltage, but it is not a simple linear relationship, since the torque depends on way more variables. One way may be to always drive the servo to it's current maximum torque and change this maximum torque by changing the input voltage inside the working range. Though this might not get you 4 torque levels, that are different enough for you.

> Also wondering if changing angle stepsize of MG966R servo will affect torque in anyway?

It is unclear, what exactly you mean by "stepsize" here. If you mean to control the speed of the servo: Yes, it will affect the torque, but not in a linear way. And this greatly depends on the load, that you apply.

In the answer to [this question][2], sensing the current of the servo is suggested as a measurement of (applied) torque. If you use a feedback loop with this, you might be able to control the (applied) torque. I haven't done this kind of thing, so I'm not sure, if this can really work.

---

That said, you should again think about wether a normal servo is really the best way to go here, since it controls electronics, that you don't control yourself. For example you may use a geared DC motor, which you can directly control without any other electronics getting in your way.

  [1]: https://www.motioncontroltips.com/servo-motor-torque-curve/
  [2]: https://electronics.stackexchange.com/questions/170305/controlling-servo-torque


body:
I got an Arduino project that need a constant source of power. Rather than dealing with batteries, I want to use a power bank like this:

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

Better yet, I want to keep the power bank plugged in to the wall outlet using a wall charger like this:

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

The USB wire coming out of the power bank, I can modify it and connect it to the 5V on the Arduino (Pro Mini 5V version). Is it safe to do so? The application uses a stepper motor that draws around 200mA and only runs intermittently.

Thanks

  [1]: https://i.stack.imgur.com/cVfbv.jpg
  [2]: https://i.stack.imgur.com/eFJYV.jpg

title: Is it safe to power Arduino project using a power bank and wall charger?

Answers: 2

body:
Yes you can.  A promini will run very well on 5V from a wallwart.  Connect 5V to VCC (not RAW or VIN).  You can also find wallwarts with 2.1mm/5.5mm plugs, and a mating barrel jack adapter that ends in screw terminals so you don't have to try hacking up a USB cable.

Power bank, you will have to play games to convince it that something is connected and drawing sufficient current to keep it turned on.

Wallwart example  https://www.mpja.com/5-Volt-DC-Plug-Power-Supply-4A-Regulated/productinfo/18520+PS/

Barrel jack to screw terminal adapter example  https://www.mpja.com/55_21mm-Power-Jack-Screw-Terminals/productinfo/19454+PL/

body: Yes, that is my standard setup for Arduino and Raspberry Pi.


body:
I am just starting with Arduino and was trying to make the LED example work. I changed the script as follows to keep the LED on:
<!-- language-all: lang-cpp -->

    #define LED_PIN 12
    #define LED_RX_SIG LED_BUILTIN

    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_PIN, OUTPUT);
      pinMode(LED_RX_SIG, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      //delay(1500);                       // wait for a second
      //digitalWrite(LED_PIN, LOW);    // turn the LED off by making the voltage LOW
      //delay(1500);                       // wait for a second
      //digitalWrite(LED_RX_SIG, HIGH);
      //delay(1000);
      //digitalWrite(LED_RX_SIG, LOW);
      //delay(1000);
    }

I setup the Nano board, LED and a 220ohm resistor on a breadboard. The D12 port on Nano is connected to one end of the 220ohm resistor using a jumper cable. The other end of the resistor is connected to the positive (longer end) of the LED. The negative end of the LED is connected to the GND pin on Nano. The setup is shown in the image below:

[![Nano Board Setup Top View][1]][1]

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

What's wrong with the setup and why the LED is not lit?
Sorry in advance for such novice question and any help will be greatly appreciated. Thanks

  [1]: https://i.stack.imgur.com/Tqa5F.jpg
  [2]: https://i.stack.imgur.com/3xywB.jpg

title: Arduino Nano LED not working

Answers: 2

body:
As your program is currently written, you should see your LED light. I see nothing wrong with your program or your wiring. I am also assuming that you had no errors while compiling and downloading the program.

With the rest of the lines uncommented, what you should see is your LED light up for 1.5 seconds and then off. Then after another 1.5 seconds, the on-board LED should turn on and then off (both 1 second).

If you have wired up the LED wrong (or a bad connection), you should at least still see the on-board LED flash about once every 5 seconds. If you don't see this then something else is wrong.

One thing I notice from the photos is that you have no way of powering your circuit. (I realise this may just be while you took the photo). Plug a USB cable into the Arduino and the other end into the computer. You should see the LED called "POW" light up.

To verify your LED circuit, try disconnecting the jumper at D12 and connecting it to 5V and you should see the LED light. If this works then your circuit is OK so replace the jumper back at D12.

If the LED still does not light up when the jumper is connected to 5V then we need to dive into that circuit. Possible reasons include:

- The LED is dead -> replace the LED
- The breadboard is not making good connection -> wiggle the leads (to scratch away any corrosion) or twist together the wires where possible or even solder them together.
- The jumper wires are manufactured poorly (eg. the plastic wasn't stripped before crimping) -> check the jumper crimps.
- The LED has been manufactured wrong and what should be the anode is actually the cathode (I have seen this) -> reverse the polarity of the LED.
- The resistor is burnt out -> replace the resistor.

body: If your led does not turn on after you directly connect it to the VCC and the GND (as you mentioned in a comment) , it means that your led is most likely broken. Simply try using another Led as your circuit and code look fine.


body:
Like the title suggests, I have a [ATSAMD21G18][1] microcontroller that I want to interface with a [LTC6803-4][2] chip, but I'm not sure how to set up the SPI bus on the microcontroller, and the datasheet proved too confusing for me to understand.

  [1]: https://www.microchip.com/wwwproducts/en/ATsamd21g18
  [2]: https://www.analog.com/en/products/ltc6803-4.html

title: How to utilize SPI Serial bus on a ATSAMD21G18?

Answers: 1

body:
Use the SPI API provided by Arduino (https://www.arduino.cc/en/Tutorial/SPITransaction) and the command format that the chip wants you to use based on the datasheet. Here's a bit of example code for SPI transaction. Though untested, it's what I understood from reading the datasheet. Written for an Adafruit Feather M0 express (uses SAMD21G18 MCU). For pinout see https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/adafruit2-pinouts#logic-pins-2-8.

Also note that Analog Devices does provide Arduino-Code for *similiar* devices like LTC6803-2 but not for the -4. Still, you can look how they implemented a driver. See [here](https://www.analog.com/en/products/ltc6803-2.html#product-documentation)

<!-- language: cpp-->

    #include <Arduino.h>
    #include <SPI.h>

    /* pin setup */
    int chip_select_pin = PIN_A2;
    /* SPI pins labeled "SCK" "MO" "MI" on the Adafruit Feather M0 express board
     * are used implicitly.
     * PIN_SPI_MISO (22),  PIN_SPI_MOSI(23), PIN_SPI_SCK(24),
     * */

    #define LTC6803_4_MAX_SCLK_FREQ 1000000
    #define LTC6803_4_USED_SCLK_FREQ (LTC6803_4_MAX_SCLK_FREQ/2)

    SPISettings settings(LTC6803_4_USED_SCLK_FREQ, BitOrder::MSBFIRST, SPI_MODE3);

    void start_voltage_adc_conversion(){
     SPI.beginTransaction(settings);
     digitalWrite(chip_select_pin, LOW);
     //STCVAD
     //Start Cell Voltage ADC Conversions and Poll Status, with Discharge Permitted
     uint8_t tranfer_buf[2] = {
       0x10, //CODE
       0xB0 //PEC
     };
     SPI.transfer(tranfer_buf, 2);
     //wait for conversion, just a static time. at least 12 milliseconds.
     delay(20);
     digitalWrite(chip_select_pin, HIGH);
     SPI.endTransaction();
    }

    void read_voltages_1_to_4(){
     //trigger voltage conversion
     start_voltage_adc_conversion();

     SPI.beginTransaction(settings);
     digitalWrite(chip_select_pin, LOW);
     //transfer buffer must have 2 bytes for command
     //and 6 bytes for response (four 12-bit ADC values encoded in 6 registers CVR00..CVR05)
        //plus 1 byte for PEC from chip
     //Read Cell Voltages 1-4, "RDCVA", page 22
     uint8_t tranfer_buf[2 + 6 + 1] = {
       0x06, //CODE
       0xD2 //PEC
     };
     SPI.transfer(tranfer_buf, 9);
     digitalWrite(chip_select_pin, HIGH);
     SPI.endTransaction();

     //recover 12-bit ADC value from C1V[0]..C1V[11] from register values CVR00 and CVR01
     //see datasheet page 24
     uint16_t adc_cell_1 = tranfer_buf[2] | ((tranfer_buf[3] & 0B1111) << 8);
     //adc value to voltage conversion according to page 15
     float voltage_cell_1_millivolt = ((int)adc_cell_1 - 512) * 1.5f ;
     Serial.print("Cell voltage 1: ");
     //print with 5 digits accuracy
     Serial.print(voltage_cell_1_millivolt, 5);
     Serial.println(" mV");
    }

    void setup() {
        Serial.begin(115200);
     pinMode(chip_select_pin, OUTPUT);
     SPI.begin();
    }

    void loop() {
     read_voltages_1_to_4();
     delay(2000);
    }


body: Some FC's say that they support cleanflight and have no mention of Ardupilot. Is this just because its what's recommended or because it's all that works?

title: Can you put Ardupilot on any flight controller?

Answers: 1

body:
There are pre-built binaries for many flight controllers.

[http://firmware.ardupilot.org/][1] lists out the different ardupilot builds (arducopter, arduplane, etc.) and by clicking on them , you can see the different versions, then the different builds per version.

[This document][2] goes into more detail on the file structure they use for pre-built binaries.

  [1]: http://firmware.ardupilot.org/
  [2]: http://ardupilot.org/dev/docs/pre-built-binaries.html


body:
I'm using Arduino Micro to read from 5 flex sensors and display the corresponding angles to the Serial monitor. I am currently having quite some problems with the oscillating values I am getting from the analogRead(). It doesn't seem to matter whether the pin is connected to a flex sensor or just grounded - the output is oscillating a lot.

Originally everything was being read and outputted just fine but I wanted to have an exact 100Hz sampling frequency and tried to play a bit with Timer Interrupts. And that's when this oscillating behaviour started. I reversed to my original code, which just uses some delay(), and simplified to only read from two pins, but cannot seem to shake off the oscillations.

I think I may have messed up something about ADC when trying to implement Interrupts, but I don't know how to check it or fix it. Please, help me figure out how to fix this!

This is the raw output of analogRead. The drop in values occurs when I bend the flex sensor:

[![This is the raw output of analogRead. The drop in values occurs when I bend the flex sensor][1]][1]

And this is the resulting calculated angle. Also oscillating:

[![And this is the resulting calculated angle. Also oscillating.][2]][2]

This is the code I've been using to read the pins:

    int fin;
    const int input[5] = {A0,A1,A2,A3,A4}; // the analog pins

    int flex[5]; // analog signal read
    float flexV;
    float flexR[5]; // resistance on the 47k resistor
    int angle[5]; // joint angles

    const float VCC = 4.98; // Measured voltage of Arduino 5V line
    // Measured resistance of the 47k resistors R1-R5
    const float R[5] = {45900.0,45900.0,45900.0,45900.0,45900.0};

    // Calibration values of resistance measured during straight phase and 90 deg bend phase
    const float R_STRAIGHT[5] = {37651.0,37651.0,37651.0,37651.0,37651.0};
    const float R_BEND[5] = {71783.0,71783.0,71783.0,71783.0,71783.0};

    void setup() {

    }

    void loop() {

      for(fin = 0; fin <= 4; fin++) {
       flex[fin] = analogRead(input[fin]);
       flexV = flex[fin]*VCC/1023.0;
       flexR[fin] = R[fin] * (VCC/flexV - 1.0);
       angle[fin] = map(flexR[fin],R_STRAIGHT[fin],R_BEND[fin],0,90.0);
       delay(1);
        }
        Serial.print(angle[0]);
        Serial.print(" ");
        Serial.print(angle[1]);
        Serial.print(" ");
        Serial.print(angle[2]);
        Serial.print(" ");
        Serial.print(angle[3]);
        Serial.print(" ");
        Serial.print(angle[4]);
        Serial.print(" ");
        Serial.println(millis());
        delay(6);
    }

  [1]: https://i.stack.imgur.com/eVNVf.png
  [2]: https://i.stack.imgur.com/Up2fp.png

title: analogRead() output oscillates even though the pin is grounded

Answers: 1

body:
You have nothing in your setup loop. You need to set up all the inputs as inputs.

You setup() should look like this:

    void setup()
     {
       Serial.begin(9600);
       for (int i = 0; i < 5; i++);
        {
          pinMode(input[i], INPUT);
        }
     }

The code cycles through your array "input", setting all the pins as inputs. Try that.