text:
What is the best delay to use between characters sent to the serial port
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:
#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?

Really, there is no "best delay" as it appears the delay needed depends on what the RPi sends the Arduino.  The more the RPi sends, the longer the delay in order for the Arduino to not let any data go missing.

Are you opening the serial port for every single character? Why? Should you not put the with line before the for line?

@NickGammon it was a quick hack to flush the characters to the file.

Quick hack or not, surely opening the file each character will take time?

@NickGammon ah, you mean in terms of making the "delay ms" value I have reported here actually being even longer? True. The fact we're operating in tens of ms though means it's probably not significant. * goes off to check * looks like you can open and close that file descriptor 180 times in 10 milliseconds on the hardware I'm using, about 57 microseconds.

Do you have the hardware to measure the actual delay between sends? According to my calculations you should need a longer delay: 13 * (1/960) = 13.54 ms, whereas you are saying it works with a 10 ms delay.

Fairly obviously, you will get much better throughput if you don't send the word "Received:" for each character you receive. That's like putting 13 litres of water into a bucket every second and taking 1 litre out, and then wondering why it overflows.

Thank you for your thoughts @NickGammon.  It's mainly due to the behaviour and limitations not being clearly described in the documentation that I'm on stackexchance asking for help.

The documentation should indeed make it clear that SoftwareSerial cannot receive at the same time as it is transmitting, so it is not a good choice for attempting to do that.

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.

13 characters because of the carriage-return/newline. This is right, you can't expect to send 13 characters for every one you receive, and keep up. Plus, when SoftwareSerial sends it turns interrupts off, so it can't receive at the same time.

@JRobert I've managed to successfully transmit continuously at 57600 baud (but with no transmit from the Arduino until after the whole message has been sent to it).  Could you edit your answer to reflect this and I'll mark it as the "correct" answer.  Thanks.

Sure - is that 57600 transmission to- or from the Arduino? Not having the direct experience, I feel I should quote yours in my update.

Yes 57600 transmission is to and from.  I tried with 115200 but (and perhaps it's due to my longer electrical wires / lack of proper grounding / interference) but this didn't work and the echo was garbage.  This could have just been the transmit from the Arduino to the Raspberry Pi but regardless in this case it didn't work at 115200 but did at 57600.

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 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.


text:
Parsing Arduino Receiving Strings
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,

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?

what is the reason for transmitting the H? ... you only need the T to separate the two values

Can you show us the actual serial String, that you received in that case?

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);
  }
}

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Using 8bit ports as 8bit I/O variable (while using USB,I2C, SPI and Serial) - keyboard
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.

Seems mostly a problem of how many pins you need for your keyboard. You didn't state, how many pins you need. You seem to need an MCU with native USB support.

Define "Non-Expensive"...

Personally I'm a fan of the PIC32. It has 16 bit IO ports not 8 bit (though not all pins are populated on all ports), so you could LATE = dataout; datain = PORTB; for example.

@chrisl Yes, I want to make USB keyboard for PC (and also use it for other purposes so need to suppor I2C, SPI and UART too) Except this, I want for the keyboard 8+8 pins (for matrix 64 keys) or better 8+16 pins (for full keyboard with aditional keys like macros, multimedia, layout switches etc.)

Personally I do not see the need to save some instructions. Mostly you want combined ports to achieve high performance, but a keyboard is operated by a human normally, which is VERY slow compared to an MCU scanning all keys. Or do you need microsecond latency?

You can use shift registers (both parallel-in-serial-out and serial-in-parallel-out) connected to the SPI bus. You can then transmit one or two bytes over SPI, which is extremely fast (8 MHz clock on even the most basic Arduinos). You can daisy chain two shift registers if you want 16 inputs.
As others have mentioned, you don't really have to worry about the speed of human input devices.

@Majenko nonexpensive - I am using some Arduinos from aliexpress, about 2-3EUR each and at worst I can add some shift register for few cents to expand pin count and be able to do the work. On Arduino shop the same are about 8-20$. Both works well. So something around this range (say 1-30$?, not 100+$)

tttapa+MichelKeijzers: I know that, but was also thinking about some "code elegance" as why do 8 loops of about 50 instructions each for what could be done by just two instructions as well (so in like 200x less). I know I can do it somehow anyway and do all others tasks also somehow  (like the USB and manipulation of 20+ WS2812B
LED and OLED display and rot. encoder and who knows what else I came with) to not be excesivelly slow, but it counts together fast and I would like for once do it effective, not just pile library over library and compensate unnecessery ineffectiveness with faster HW.

You could read and entire port, and apply a mask, so only the bits you're interested in remain. Slightly more code, but faster than 16 digitalReads. But I'm counting that you'd need 32 GPIO pins, plus USB, So I think that's the problem you should focus on.

@Majenko is there some PIC32, which you would recomend me for start? Having USB and beat AVR32U4 is enought for me to give it try :) (So probably some cheaper model would be more than enought)

@Gerben for my current try it is 2 (I2C display+communication PD0-1) + 4 SPI (PB0-3) + USB (D+ D-) + 2 Serial (PD2-3) + 16 GPIO (PB4-7,PD4-7, PC6-7,PF0-1,4-7 ) - from that 16 GPIO I would use 8 as inputs, 1 for LEDs, 3 as outputs for 3-to-8 decoder (as only 1 row is active at each time) and have 4 free, or I would use 7 as outputs for 8x7 matrix which works for normal keyboard (128 keys, no external chip).

@gilhad You could do worse than the Fubarino SD

@Majenko thank you :) Looks interesting :) I will try it :)

If you use a diode separated key matrix, I don't see a way to press two or three keys at once if you don't implement a anti ghosting algorithm in your controller. To work, the capturing of the pins must be very fast. Nearly at once. And the mcu must be fast enough to find even a really short delay for pressing two or three keys. If there is a delay we, assume a human pressed the keys. That's anti ghosting. An expensive way of avoiding ghost keys is reading all keys separate  into a chain of shift registers. Or build a DAC with a resitore chain and read the analog value. One Channel = 10 Bits

To answer your second question: The pin setup depends on the internal layout of the chip. It is easier the have functional groups in their own blocks, e.g. the clock logic and the shift registers. The manufacturer chooses the pin position the way, it needs the shortest wiring of the gold wires and also it should avoid crossing wires.

@PeterPaulKiefer Key matrix input is read in the way, tah you attach signal to one row, then read all collumns to see, if signal is there. If it is there, then the key on crossing of row and collumn is pressed. Then continou with other row and after you check all rows, you know, which keys are pressed. Ghosting happens, if there are no diodes and user press keys on 3 crossings, that forms rectangle. Then even for the unpressed crossing is there signal, as it travels over the rest 3 and "ghost key" is detected, as we see the signal there, even if the key is not pressed. No speed helps here.

If there ARE diodes, then pressing the 3 keys does not make way for the 4. as diodes disallow the signal freelly travel to other rows. Even slow mcu can read that safely (as long as it does that faster, then human free the keys - say in 0.1s = eternity for mcu. Faster mcu can get more precise time of pressing, nothin more). No special algorithmus is needed here too. Normal matrix works fine. See also this answer: https://arduino.stackexchange.com/questions/66691/which-kind-of-diodes-i-should-use-in-buttons-keys-matrix-input-making-gaming-k/66710#66710

It was late, I was tired, sorry I forgot the "don't" : My intention was to write: "If you don't use a diode separated key matrix, ....".  You're right that you have to press at  least 3 keys to get the ghost effect. And of cause two of the pressed keys must be on the row that is powered "ghostly" by the third pressed key. Mea culpa, thinking while writing is helpful. ;-) By the way, I have already created some keyboards, it's not my main business but from time to time ... . They have to work in harsh environments. Sometimes for some reasons I'm not allowed to place diodes in the key matrix.

One of these projects required me to allow the user to press a maximum of four keys out of sixty four and I was not allowed to use diodes. In the end we solved it by using a 16 Bit shift register. We powered the rows and read the cols and we had to handle the ghost keys. We used an algorithm that was called the anti ghosting algorithm in the literature we studied. This checks whether the signals of the pressed keys comes quick enough to interpret it as a ghost signal or if the user had really pressed the keys.

We did not check how quick the user released the key we check for the very fast time the power jumps from one row to the "ghost" row. The smaller the checked  time intervals, the more reliable is the recognition of a keys. And that you dream of testing in the nano second scale. But even with this algorithm the reading was not reliable because sometimes we were not fast enough or the the keys were pressed in an an unlucky order. We detect user pressed keys as ghost keys. Then we tried to build a Resistor based DAC. with 7 channels to read the 64 Keys. This works fine but failed in production.

It failed in production because there was strong EMI. And the analog inputs got unreliable. At the end we capitulated and used four of the sixteen bit shift registers to read each key separately. The was the long story of the short comment above. I didn't what to teach you how keyboards work. I just want to show you what we had done, so could used it for your decisions . I'm not a native English speaker. In fact my English is very poor. So I did not recognize, that I made some errors, and I had not written with the precision I would write if I write German texts. But I promise, I'll  practice

@PeterPaulKiefer Yes, "don't" can make big difference sometimes :) My English is also far from perfect (4. language learned) - and I am from Czech. Your answer confused me, so I went to longer explanation. At the end there is none disagreement between us :)

Yes, that's right ! And I forgot: Thank you for pointing me to the errors. ........ And there is still one thing. You wrote, you want to connect the keyboard using USB (among other methods). If you intent to use the keyboard as a HID device (which you should ;-) ), the board you'll choose should be able for this. I know that the Leonardo and the DUE have this feature. Here is a link that explain the usage for a keyboard: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/

And if you choose for a e.g. Mega as suggested in one answer, this video might be helpful: https://www.youtube.com/watch?v=bTlM27jzOIQ

@PeterPaulKiefer I am using Micro so far, which have also HW USB ability :) http://micro-corner.gilhad.cz/blog/Arduino/progs/KlikiMouse3/images/klikimouse.s.jpg http://micro-corner.gilhad.cz/blog/Arduino/progs/KlikiMouse3/2019-04-29-Arduino-progs-Klikimouse3.html as it is pretty cheap from Aliexpress :)

Funny, I saw this part so often in the internet stores but was not aware of that feature. It has a 32u4 MCU. Thank you for pointing me to it. So you will use this in addition to a bigger MCU that can read the keyboard inputs? Or do you plan to use shift registers (aka port expander; like the MCP23S17)?

If you are interested in other brands: Do you know the STM32 Nucleo F-series?  These are boards with STM32 ARM M0-M4 MCUs in a price range from 10 to 20 dollars with arduino headers and own headers (Morpho) with a full pin out ~ 55 IO Pins. They have also a rich set of communication interfaces. Here is a link to the F3 series MCU https://www.st.com/en/microcontrollers-microprocessors/stm32f3-series.html. (Oh and they have a flexible interconnect matrix. Choose your pins ;-) )

@PeterPaulKiefer I would probably use much cheaper 74HC138 or 74HC595 for output or 74HC165 for inputs :) or just use Blue Pill as I did for old PS/2 keyboard :) http://download.gilhad.cz/STM-keyboard.s.jpg

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.

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

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
esp32 cam and PIR sensor
I have tried all the GPIO pins listed here: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
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)

A schematic of how you are hooking up the PIR to the esp32 cam board would help.

@st2000 I added some more info to the OP.

So, you are using pins other than pin 3 (E32_RST)?  Guessing, most embedded processors generate different vectors (places they go to and start code execution) based on which pins are generating interrupts.  It may be that the libraries you are using only setup an interrupt for pin 3.  As this is all guess work - I'm resisting the temptation to change this comment into an answer.

I am not seeing a pin 3 (esp32 rst) on this board. Could you point it out. Then you can change this to can answer.

I am looking at this schematic.  Assuming this is the board you have.  I see a reset switch connected to net ES32_RST.  Which appears at pin 3 of the ESP-32S chip.  Guessing, if  your PIR uses an open collector to ground type output, you might try soldering to the open side of the reset switch.

Ok I think I see now. I would need to solder it to the esp32-s chip itself. I will provide a high signal to the rst pin 3 via the PIR sensor and it will reset the board? I added an edit to include the schematic of my PIR sensor.

I don't think that is going to work.  The PIR spec says it will output a high when activated.  And the ESP32 Cam schematic, if accurate, shows K1 making a connection to ground when pushed.  So the PIR is doing the opposite of what you need.  Also, the ESP chip is probably a QFN package is is extremely difficult to solder directly to.  Likely it would be much easier to solder to the push button switch lead.

Ok I will give it a shot

Let us continue this discussion in chat.

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 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.


text:
class enum was not declared in this scope
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.

Arduino builder has problems if structs, enums, classes are not defined before the first function

why do you write enum class instead of just enum?

@chrisl, enum class or enum struct from C++11 is enum where the values can be used only with the enum type name like CYCLE::TypeB.

Could you please provide an example that reproduces this comiler error? I embedded your code in the setup()-loop() template and it works!

Done @SimSon and that was where the "bug" was lurking.  See Juraj's answer.

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.

please see my answer.  If you can edit yours to include / clarify this I'll delete mine and mark yours as correct.  Many thanks.

@AJP, I know about this bug so I identified it in your Question, but I could not know what function do you have before the enum. I wrote the answer more generic. Now I added something about workaround.

Done.  Thanks @Juraj

+1 for the answer and -1 for the Arduino IDE. Valid C++ should simply compile. I don't want to learn the quirks of another programming language if I can already program C++. I can't believe this hasn't been resolved in the last 4 years.

I don't understand the workaround. I already have my enum declared before the function using it as argument, but I still get the error.

@AgainPsychoX you have to put it before all functions

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:

(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.
Put each type/enum value on a new line; this makes it easier to add comments above/after it.
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.
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;
}

Thanks Michel.  Completely agree with multiple lines per enum.  I condensed it to aid shortening the question.  I like the idea of putting the { and } in vertical alignment.  I've made that change now and it's good, thanks.  I don't agree with the switch statement as I don't like the fall through bug if you forget break.  Do common C++ IDEs warn you?  As a benefit of switch: does C++ error / warn if you don't handle all enum types?  Only return once pattern: yes completely agree.  Thank you.

You're welcome. An if statement can be as dangerous (using = instead of ==). I don't think you get a warning forgetting a break (you can try easily). C++ does not warn you for not checking all enum values, but that's where the 'default' keyword is for.

Right.  I understand.  In your experience is the if (a = x) more prevalent as a bug than forgetting the break?  I guess it ultimately comes down to practice (?) but I've done the former perhaps 2 times in my life but the later a lot more so I personally eschew switch for that reason.

You might like to read: https://stackoverflow.com/questions/97987/advantage-of-switch-over-if-else-statement   (actually I was curious too). Anyway, a switch is more readable. In all (professional) software projects I have done, a code review would not pass a bunch of if statements above a switch (when comparing against a single variable). Btw, I checked, Arduino IDE does not show any warning (not even with all warnings on).

Even Visual Studio 2019 with warnings on does not show. I have worked with lint (a static C/C++ checker) and I'm fairly sure that application mentions forgotten break. Although in C it is allowed to have multiple case statements (to perform the same action for multiple values). Mostly people put // Fall through behind it, to show the break is forgotten deliberately.

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
}

I found workaround on Arduino forums: Put your enums in separate file (I use enums.hpp), and include it from the main sketch file (.ino) like #include "enums.hpp".

do you have the .hpp included at the same location in the ino where you had originally the enum?


text:
Sim800L Uploading issues, HTTPACTION returns 0, 302, 701
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:

//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

302 is HTTP code returned by the server. it is used for redirection. try to print the response with HTTPREAD. most common redirection is to https on the same server. does the server support unsecured access with http?

The server im using does niet support HTTPS. But how would i go about using this command? AT+HTTPREAD=URL or something else?

page 261 in the manual

Thanks, im trying it now.

I'm a bit of a noob with this stuff, I think I've got the syntax wrong but im not getting any response while trying this command

I figured it out, but HTTPREAD just returns a "1".

with what parameters did you run HTTPREAD?

HTTPREAD=0,1 The manual stated the first digit for start byte (witch i assumed would be byte 0?) and the second one for byte length.

you asked for one character.

ohhh... That makes sense.. lol. I should just make the last one bigger right? like 1024 or something?

I used 1024 now, I indeed see it gets redirected, to https://www.t-mobile.nl/prepaid-data-pass Which is weird because i have 4€ of data left...

redirect to captive portal to enter password before using the network

Thanks, i am an total idiot. thanks alot!

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.


text:
PWM delay without blocking the code
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?

Seems ok for fade in timer. Why are you doing the else with i--? Do you want to fade out the LED after the fade in? That does not work this way, since it will only vary between 254 and 255.

the Fade example in IDE uses delay, but shows how to go up and then down. and put millisTimer = millis(); outside if-else

@chrisl newbie mistakes... thanks for mentioning it.

From my personal definition, the "right way" is a way that works. So, does it work? Your approach is a common way to do tasks without delay (like in the BlinkWithoutDelay example)

@SimSon i'm new to this and i don't know how others write code in "standard way", thought asking may open new doors to learn new things.

see the Fade example and the BlinkWithoutDelay example in IDE Examples menu

@Juraj okay thanks.

That's fine, I do it the same way

all code inside if(condition == 1){ block, except the analogWrite(), should be indented one more level

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

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;
    }
  }
}


text:
Millis() does not back to zero after woke up from deep sleep mode
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:

Arduino Uno R3 4 units
Ultrasonic Proximity sensor 4 units
DS1302 RTC modules 4 units
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

why are not able to treat the millis() value, at wake time, as the zero reference point?

I don't actually think that millis() is supposed to be reset on a wakeup...

This looks like an XY problem. X: you need to synchronize the times, Y: you want to reset millis().

I can not achieve sync if the millis() function does not back to zero ... change your code so that it does not require millis() to be reset

You should read edgar's reference to the XY problem. Although it sounds like it might relate to tracking an object in two dimensions. It is actually talking about something else.

You should also read jsotola's comment again. Here is an additional clue... zeroTime = millis();  time goes by, stuff happens, sampleTime = millis(); and elapsedTime = sampleTime - zeroTime. In this clue, does it really matter what the value of start time is? Make sure you use unsigned values for your. Variables.

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

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.


text:
Can I use the PWM pins as regular digital input/output pins?
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.

have you tried?

Not directly related to the question but perhaps noteworthy, you can also use the Analog-In pins as regular digital IO.

Yes that is true and an often overlooked fact. Indeed most pins have multiple functions. Arduino pinout diagrams are extremely useful to see what an individual pin is capable of. Most have more than one function. Some have more than two functions.

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.


text:
0 temperature & hummidity DH11
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

did you run the example code?

Suggestion: drop the dht11 in favor of Bosch's BME280 (not BMP!).  It measures temperature, humidity AND pressure.

@tonygil ... and it doesn't make use of dump 1-wire protocoll. As long as 1w is not supported by hardware this turns out to be a game-breaker in many professional (non-makers) applications (my experience). BME is a great alternative and provides SPI and i2c

Do you have the external pullup?

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 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
//


text:
Interrupts arduino interrupting serial comunication
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:
//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:

And i got the code from this site
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

You misdiagnosed the problem. These cli() and sei() calls are harmless. Please, explain what your real problem is.

cli() and sei() are only used in setup, they are not the problem. Maybe your Timer ISR is taking too long. You can make it shorter, doing more things in loop. But please describe further, what undesireable behavior you see with this code.

the interrupt is executed every 509 clock ticks (no prescaler) and the handler is long. there is no time for anything else

The developers said To be sure there is no problem with interrupts we will use cli() ( stop interrupts) and sei()(enable interrupts). .please make sure how to timer interrupts works! How to PWM works! Try to interrupts simple LED or something to diagnosed your problem.

What do you want your program to do in general. What are you trying to achieve? Then tell us what problems you are seeing? What is it doing wrong?

@EdgarBonet.. I am working on VFD Inverter controlled by VB.Net. So, the output voltage and the frequency can be controlled with VB.Net. Now, the problem is i can't control the output, and i assume something is wrong with my interrupt. Nut the people here told me ISR is too long, i think that's also right. Now i don't know what todo with making the ISR shorter.

@chrisl.. When i ask someone else, he also mentioned the ISR is too long. Do you have any advice to make the ISR shorter? About the undesireable behavior, when i start VB.Net and scroll Voltage Trackbar, nothing happens to my project output. I expect the output Voltage can be vary through trackbar in VB.Net. But, when i use potensiometer, it works.

@Juraj.. Could you tell me what i supposed to do then, please?

@sa_leinad.. As you can see in my comments, i intend to control voltage and frequency through VB.Net. The problem is, i can't send any data from VB to arduino. I don't really know what's wrong. But i assume it's related with interrupt or ISR. Do you have any advice about the code?

How do yo know the value of OCR1A = 509 and you give i > 629? But based your link with OCR1A = 509 and   value of variable i < 313 instead. For the example where timer0 is for interrupt i have used the same formula OCR1A=(fclk/fOC1A*N)-1, where instead of OCR1A appear OCR0A.

To see if it is related to interrupts you could wrap the while (Serial.available()) loop in serialEvent() in a ATOMIC_BLOCK section. To shorten the ISR simply set a flag and then in the loop(): if(flag) // call the ISR as a function and clear the flag. Something else: variables used in an ISR and your program (like F) must be declared volatile'. You have to filter the analog output in hardware as analogWrite()` does not create an analog voltage but a pwm instead.

@abu-ahmedal-khatiri, 629 is the end variable of vector table, since the author said the table only generate 50Hz, i doubled it. In my logic, if 50Hz consist 314 variable, i thought for 100Hz needs 629 variable.. (why 629? Because i give extra 0 variable, just to make sure the mosfets is ok)

@SimSon.. Thanks for your advice. And, could you tell me simple code about how to set a flag? I can't find any example about it.

@SimSon.. i found something about flag in this link. But i am not sure how to put it in my code. Could you tell mw what to do first??

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.

Thanks for your answer. I'll definitely try this.


text:
Possible to have different torque levels on MG966R servo with Rotary Potentiometer?
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!

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.

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, 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.


text:
Is it safe to power Arduino project using a power bank and wall charger?
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:

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

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

you will possibly kill your power bank faster, unless it has a pass thru circuit (does not discharge while plugged in and fully charged).  i keep my rural Arduino PWS (weather station) powered like this all the time, because we have power outages on an almost daily basis.

what’s the load? is it enough to drop voltage and confuse your charge controller? if yes, it becomes a fire hazard. the USB battery needs to output 5V when plugged in, and mustn’t discharge the batteries to do this. use your multimeter to discover the truth!

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/

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


text:
Arduino Nano LED not working
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:

#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:

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

You didn't ask any question. What is the problem with this circuit?

Try and connect the red wire to VCC (instead of D12), to verify that the led works. The code looks fine to me. You can also try a different pin than D12. There might be a bad solder connection on D12. There's a lot of trial and error involved with Arduino.

@chirsl thanks for pointing it out; edited my post and added the relevant question

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.

Thanks for the answer. With the lines uncommented,I do see the on-board LED flash roughly about every 5 seconds. I added that earlier to check if the circuit is receiving code. Also, it compiles successfully and also uploads without error. I tried the 3V pin, 5V pin. Still no LED. What can be wrong with the circuit? I watched a lot of videos on Youtube that used a similar circuit. I am not sure how to troubleshoot these problems. FYI, also tried D11, D10 and D9. Didn't work.

@AbrarHossain I have edited my answer and included more information to the end.

Did the extra information help? Did you get a solution to you problem?

@sa_leinard Here's what I have done so far. I bought a new Nano board, used new jumper cables and a new 220ohm resistor. Finally, the LED is blinking. Thanks for all your help. I believe the problem may have been with any of the components I replaced. I will try to debug exactly which caused the problem and update the question.

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.


text:
How to utilize SPI Serial bus on a ATSAMD21G18?
Like the title suggests, I have a ATSAMD21G18 microcontroller that I want to interface with a LTC6803-4 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.

SPI.begin()...? Or aren't you using the Arduino API?

i'm not even that far, I dont know how to physically connect them, not sure what pins to use on the ATSAMD21G18

You connect it to the PAD[x] pins for the SPI port you want to use.

TBH it looks overly complicated on that chip. I'd choose a simpler chip. Any specific reason why you want to use that particular chip?

I wanted to integrate BLE, 3 LTC6803-4 ics, a Real time clock and a microsd reader/writer onto the same board, and i figured i would base it off the Adafruit Feather M0 Bluefruit BLE, but i'm open to recommendations for easier micro controllers

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
#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);
}


text:
Can you put Ardupilot on any flight controller?
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?

Probably the Ardupilot is based on Atmel MCU, like Arduino. The newest flight controller are based on STM32F4 and STM32F7.

This is a usage question which should be asked on the support forum for the software in question, it is not an electronic design question fitting here.  If you were personally trying to port the software and had a very specific question about a difficulty in your attempt to match a particular capability with a different MCU's peripherals, that might be on topic if well supported with the details of the problem.

There are pre-built binaries for many flight controllers.
http://firmware.ardupilot.org/ 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 goes into more detail on the file structure they use for pre-built binaries.


text:
analogRead() output oscillates even though the pin is grounded
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:

And this is the resulting calculated angle. Also oscillating:

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);
}

The first graph looks to me like to are plotting two channels interspersed.

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.

As I remember, the pinmode doesn't matter for analogRead, since pinMode(pin, INPUT) will set the pin as digital input. analogRead() will configure the pin to use the ADC, which has nothing to do with digital input. This is only often done for readability, so that the reader directly sees, which pins are inputs and which are outputs.

Gpios are input by default

I think the pins should be input by default? Anyways, I've tried that. No change. I think I somehow messed up the ADC by have no idea how to test it out...

You can easily test your ADC by connecting it to a variable power source. You should be seeing 1023 when it's at 5v and 0 when it's at 0v. If you don't have a variable power source use a 10K potentiometer, with the left side connected to 5v, middle pin to your ADC pin, and your right to GND. Turning the knob will produce the same results. You can also use a multimeter to verify the flex sensors are working properly.

Tried that out. I'm getting nice 1023 at 5V but anything between 220 and 800 at 0V...

Hmm sounds like a bad grounding issue to me. How are you powering the Arduino?


text:
Velleman KA02 not working on Mega 2560 r3
I have a Velleman KA02 audio shield. When I use this shield on an Arduino UNO R3 with this sample code, it works. And by "work" I mean when I interact with the Serial Monitor (by pressing Y, for example), I hear the playback.
However, if I place this audio shield on a Mega 2560 R3, the shield no longer works (pressing Y does nothing). I read about the SPI library, and the document seems to suggest that MISO, MOSI, SCK and SS are different for the Uno vs the Mega. For the Uno,

MOSI: 11
MISO: 12
SCK: 13
SS: 10

and the article is consistent with the constants defined in the ISD1700.h file. For the Mega,

MOSI: 51
MISO: 50
SCK: 52
SS: 53

I can modify ISD1700.h for use with the Mega easy enough. However, I do not think I can just sit the audio shield right on top of the Mega with the modified code and have it work. I used some (male to female) jumper wires to connect from the Mega pins 50, 51, 52, 53 to the audio shield pins 12, 11, 13, 53 (correspondingly). Additionally, I have jumper wires connecting the power and ground from the Mega to the audio shield. What works is that the audio shield has power and I am able to press the physical buttons on the audio shield to record and playback. What does not work is that when I enter Y in the serial monitor to force a playback, although the character is read and the switch case is reached, the playback never happens.
Any ideas on what I am doing wrong? On the Velleman site, they seem to suggest that this audio shield only works with the Uno, but the Illustrated Assembly Manual says that the audio shield should work with the Mega.

put the shield on and it should work. don't change ISD1700 chip(10); to ISD1700 chip(53);

Nevermind, I solved it. There's 6 pins located on the Uno and Mega labelled ICSP, and those were the key. I simply connected the MOSI, MISO and SCK pins on the Mega to the audio shield (along with GND and 5V) and also the 10 pin (audio shield) to the 53 pin (Mega) via a male to male jumper. The header code was modified to work with the new values, and now I am able to send character signals via the serial monitor.

and why did you change ISD1700 chip(10); to ISD1700 chip(53);? 10 is a good for CS


text:
How to prevent modify library of arduino?
For some reasons of security, I created library for everybody to use, but I don't want people change my library, cause it make device not work. I search around but still not working. Do I need to set password for library or make it unreadable or make it can not modify or another way that you can give the direction ?
P/s: Think like a hacker, I can change library and make an attack to the server from library.

why is it a problem for you if someone changes the library and the device fails as a result?

it make device not work

@Quang, that does not answer my question ... you already said that the device may not work .... why is it your problem? ... why is it not the problem of the person that changed the library?

it make device not work - what device? A few more details, please.

Maybe if you provide a precompiled library for the users. Though I'm not really qualified in that field.

See my amended answer for my thoughts about your "hacker" comment.

No, you can't do that. How could a library work if it is unreadable?
If you don't want people changing it, don't publish it.
If you publish it you could put a disclaimer on it:

If you change my library, it may stop working.

(Added to question two days later)

P/s: Think like a hacker, I can change library and make an attack to the server from library.

Yes, but, if you distribute the original library, then someone would have to download it, change it, and then attack themselves with it!
And if your library does something to do with servers (you haven't said what your library does) then someone could make a similar library, and build the attack code into that. Hacking your particular one wouldn't be required.
My other issue is: If your library is a secret, that is, I can't read its source code, then I might presume that your library is where the hack is. At least if people get the source code they can read it and check it.

Later versions of the IDE have the ability to use pre-compiled libraries.  This means that the end user only gets the compiled version of your library (a .a file) rather than the source code.
Modify your library.properties file to include dot_a_linkage=true. If you don't have a library.properties file you need to make sure you create your library in 1.5.x format.
Then compile your library in the normal way. This will result in a .a file somewhere in the build  tree which gets linked with your sketch.  You need to grab that .a file.
Next make a new copy of your library that has just the header file (needed for compilation) and the .a file (needed for linking). No .cpp files.
Now you in the new library.properties file you add precompiled=true.
As long as you lay out the files right it should now compile using the precompiled .a file.
You can read more about the library.properties contents here.

Hmm, I didn't know that.

@NickGammon it's not something that is well documented, and not used much. I haven't used it myself, just inferred it fun the spec.

This answer should probably mention that this is only a mild deterrent, as it's relatively easy to disassemble and edit a .a file.

@JosephSible It's simple to extract the .o files from a .a file, yes. Less easy to disassemble those .o files back into source code, modify them, and recreate them. I'd hardly call it a "mild" deterrent.  True, anything can be reverse engineered if you're determined enough - but we're talking about an Arduino library here - with the associated level of competence that a typical Arduino user has...  I.e., a .a file is a complete mystery to them...

Distribute your library in compiled format. The when code is compiled it's "translated" from "human readable code" to "machine code". Machine code is almost impossible to read and understand without years of experience.
There always is a possibility of decompilation. There are programs called decompilers that change any "machine code" into "human readable code". The resulting code is different then your original code, and there is nothing you can do to prevent decompilation because in the end Arduino has to have that "machine code" to know what operations to execute, and it's impossible to have it encrypterd in any way.
You can make always decompilation more troublesome. There is a procedure called "code obfuscation". You can manually, (or using a specialized code obfuscation software) make the "human readable" code no longer readable by humans. They can add extra variables, extra methods change constants to variables that are generated by completely unrelated parts of code. This will also change machine code, and make the code after decompilation much harder to understand. Unfortunately it will also complicate the machine code and make library run much slower.
Fun Fact!
There exists a competition in code obfustation https://www.ioccc.org/
And this is a valid C code that you can compile and run. https://www.ioccc.org/2014/sinon/prog.c


text:
Memory usage in AnalogBinLogger of SdFat library
The AnalogBinLogger.ino file of SdFat library says the following:

Each 512 byte data block in the file has a four byte header followed by up to 508 bytes of data. (508 values in 8-bit mode or 254 values in 10-bit mode).
   Each block contains an integral number of samples with unused space at the end of the block.

I was wondering why only 254 values can be stored in 10-bit mode instead of (508*8 bits/ 10 bits ~ 406 values ).

Is this because of the memory being byte-addressable and hence does a 10-bit value take up 2 bytes?
If so, how will a file-reader differentiate between a 10-bit value taking 2 bytes and two 8-bit values?
The AnalogBinLogger.ino says:

The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT additional buffers.

BUFFER_BLOCK_COUNT is 1 for the Arduino Uno since it has 2KB of SRAM. Each buffer is 512-byte long. Is SdFat's internal buffer also in SRAM? If I am not wrong, the libraries the program uses and the program code reside in the Flash memory, can SdFat write into a buffer in Flash memory?

yes it is because it takes 2 bytes. "10 bit mode" is the 10 bit mode of the ADC, the source of the data, not some 10 bit mode of the file

@Juraj If the ADC converts the analog values to a 10-bit binary value, why does the value take 16 bits when written to the file?

@Harini: Because you cannot store bits in a file. A file is a sequence of bytes.

it is only an example, not an exercise in optimization or compression

@EdgarBonet Sure, in that case, referring to the second part of my question: how does a file-reader differentiate between a 10-bit value and two 8-bit values? You can post it as an answer so that I can mark it accepted for this question.

how will a file-reader differentiate between a 10-bit value taking 2
  bytes and two 8-bit values?

The file AnalogBinLogger.h, which comes with the example sketch you
mentioned, contains the following:
// First block of file.
struct metadata_t {
  unsigned long  adcFrequency;     // ADC clock frequency
  unsigned long  cpuFrequency;     // CPU clock frequency
  unsigned long  sampleInterval;   // Sample interval in CPU cycles.
  unsigned long  recordEightBits;  // Size of ADC values, nonzero for 8-bits.
  unsigned long  pinCount;         // Number of analog pins in a sample.
  unsigned long  pinNumber[123];   // List of pin numbers in a sample.
};

Thus, the file reader just needs to be aware of the format of this first
block, and read the recordEightBits field in order to know whether
this is 8-bit data or not.

Is SdFat's buffer also in SRAM?

Yes, that's the only sensible place you could have a data buffer. It's
allocated on the stack, only during the execution of the
logData() function.

Is this the 'four-byte header' mentioned in AnalogBinLogger.ino which I have quoted in my question? But clearly, this header is 24 bytes.

@Harini: No. This is the first block of the file. It's 512 bytes long, not 24. The four byte header you mention is in every block except the first one.

You're right, pardon me for not accounting for the 123 elements in pinNumber. It would be helpful if you can clarify the third part of the question about SRAM and Flash memory use.

Yes, the line of code highlighted in the link provided is the additional buffer SdFat uses. The sketch mentions the use of SdFat's internal buffer and my question is whether this too resides in the SRAM.


text:
Problem with passing string pointer from child to parent
I am trying to pass a pointer to a const char * from a child to its parent, but I am clearly not understanding how to do this correctly. Here is the code which contains three classes:
1) parent
2) Alpha (child)
3_ Beta (child)
#pragma once
class Parent {
protected:
    char *childName;

public:
    Parent ( char* _childName ) {
        childName = _childName;
    }

    char *getChildName () {
        return childName;
    }
};

class Alpha: public Parent {
protected:
    const char* alphaName = "ALPHA";

public:
    Alpha (): Parent ( alphaName ) {
        Serial.print ( F ( "My name is " ) );
        Serial.println ( getChildName () );
    }
};

class Beta: public Parent {
protected:
    const char* betaName = "BETA";

public:
    Beta (): Parent ( betaName ) {
        Serial.print ( F ( "My name is " ) );
        Serial.println ( getChildName () );
    }
};

Alpha *alpha;
Beta *beta;
void setup () {
    Serial.begin ( 115200 );
    while (!Serial.availableForWrite ()) {}

    alpha = new Alpha ();
    beta = new Beta ();
}

void loop() {}

And here is the output I get:
My name is �
My name is �˵

try to add const to all char*. on what mcu architecture do you compile and run it?

I tried your code, after adding the missing const to have it compile, and I get the expected output: "My name is ALPHA\r\nMy name is BETA\r\n".

A long time ago a senior programmer told me the correct way of defining literals was to do const char betaName[] = "BETA"; unfortunately I can't remember the precise details but it was to do with the way the memory was allocated.  HOWEVER this was back in the 90's so hopefully the compilers are better now.

The short version is that const will entice the compiler to use program memory (which is usually more abundant) to store the value rather then data memory (which is usually less abundant).  Notice all the "qualifiers" I used?  This is because different compilers and platforms combinations will likely have different results.

The problem here is that alphaName and betaName are member variables. That means they are initialized during the Alpha and Beta constructors. However, the superclass constructor of Parent is always called first, before calling the child class constructors. Result: Parent::Parent(char *) is called with an uninitialized pointer.
Here is your code on the Compiler Explorer: https://godbolt.org/z/otAuQU
As you can see, Alpha::Alpha() compiles to the following:
call Parent::Parent(char*)
ldd r24,Y+1
ldd r25,Y+2
ldi r18,lo8(.LC0)
ldi r19,hi8(.LC0)

.LC0 is the string "ALPHA".
The solution here is to make the names static. That way, they are initialized before the parent constructor is called.
class Parent {
  protected:
    const char *const childName;

  public:
    Parent(const char* childName) : childName(childName) {}

    const char *getChildName () const {
        return childName;
    }
};

class Alpha : public Parent {
  protected:
    constexpr static const char *alphaName = "ALPHA";

  public:
    Alpha() : Parent(alphaName) {
        Serial.print(F("My name is "));
        Serial.println(getChildName());
    }
};

This compiles to:
ldi r22,lo8(.LC0)
ldi r23,hi8(.LC0)
call Parent::Parent(char const*)

As others have mentioned, pointers to string literals should always be const. The only reason this doesn't give an error is because the Arduino folks decided that it was a good idea to compile everything with -fpermissive ...
Mutating a string literal is undefined behavior, so an error.

And the award goes to tttapa who has now fried a few of my remaining brain cells with his precise and correctly working code sample. Thanks, tttapa! And now I have a lot of code that needs fixing.

@BobJones, I think using const char* should be enough and Edgar Bonet reported it working in a comment. But we don't know the platform you are using

@Juraj, I think that's still undefined behavior. The reason that it appears to be working is that the compiler optimizes it because it knows that it will be constant. However, there is no guarantee that the pointer should be initialized before calling the parent constructor, it's just a happy coincidence.

C++ reference "Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished." https://en.cppreference.com/w/cpp/language/initializer_list

@Juraj, I'm not talking about the constructor body, I'm talking about the Parent constructor. First the Parent::Parent(const char *) constructor gets called, the Parent member variables are initialized (childName), then data members of Alpha are initialized (alphaName), and finally, the body of Alpha::Alpha() is executed.
I just tested the original code with added const on an UNO with version 1.6.23 of the AVR Core. It doesn't work. When the names are static, it does work.