body:
I use the Arduino IDE 1.8.10 and the esp8266 core 2.7.1 and the Wemos-D1 with SD Card Module
For the SD Card i use the SdFat.h library, because i need to set the timestamp for the uploaded file.

I am not a expert to arduino programming.

Currently my scetcch can this:
List Files from the SD Card on a webpage and show Filename and Filesize. Working.
Delete selected File. Working.

My Goal:

Download a File over http from the SD Card to my Windows PC.

Upload a File over http to SD Card with Timestamp from the original File.
With sd.h a simple Upload is working. But the Timestamp is every time 1.1.2020 01:00

My Includes:

    #include "SdFat.h"
    #include "sdios.h"
    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPClient.h>
    #include <ESP8266mDNS.h>

My **Old code** with sd.h for download:

    void SD_file_download(String filename){
      if (SD_present) {
        File download = SD.open(filename);
        if (download) {
          filename.replace(" ","_");
          int last_slash = filename.lastIndexOf('/') + 1;
          filename = filename.substring(last_slash);
          server.sendHeader("Content-Type", "text/text");
          server.sendHeader("Content-Disposition", "attachment; filename="+filename);
          server.sendHeader("Connection", "close");
          server.streamFile(download, "application/octet-stream");
          download.close();
        } else del = "2";
      } else ReportSDNotPresent();
    }

My **new Code** for Download with SdFat.h:

    void SD_file_download(String filename){
    SdFile dl_file;
      if (SD_present) {
        if (dl_file.open(filename.c_str())) {
          filename.replace(" ","_");
          int last_slash = filename.lastIndexOf('/') + 1;
          filename = filename.substring(last_slash);
          server.sendHeader("Content-Type", "text/text");
          server.sendHeader("Content-Disposition", "attachment; filename="+filename);
          server.sendHeader("Connection", "close");
            size_t sent = server.streamFile(dl_file, "application/octet-stream");
          dl_file.close();
        } else del = "2";
      } else ReportSDNotPresent();
    }

If i compile i get many errors

    In file included from F:\Eigene Dateien\Arduino\esp_fileserver05\esp_fileserver05.ino:14:0:

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h: In instantiation of 'size_t esp8266webserver::ESP8266WebServerTemplate<ServerType>::streamFile(T&, const String&, HTTPMethod) [with T = sdfat::SdFile; ServerType = WiFiServer; size_t = unsigned int]':

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h:177:50:   required from 'size_t esp8266webserver::ESP8266WebServerTemplate<ServerType>::streamFile(T&, const String&) [with T = sdfat::SdFile; ServerType = WiFiServer; size_t = unsigned int]'

    F:\Eigene Dateien\Arduino\esp_fileserver05\esp_fileserver05.ino:211:60:   required from here

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h:185:58: error: 'class sdfat::SdFile' has no member named 'size'

     _streamFileCore(file.size(), file.name(), contentType);

                                                          ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h:185:58: error: 'class sdfat::SdFile' has no member named 'name'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h:187:21: error: no matching function for call to 'WiFiClient::write(sdfat::SdFile&)'

       contentLength = _currentClient.write(file);

                     ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WebServer\src/ESP8266WebServer.h:187:21: note: candidates are:

    In file included from C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/ESP8266WiFi.h:39:0,

                 from F:\Eigene Dateien\Arduino\esp_fileserver05\esp_fileserver05.ino:12:

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:59:18: note: virtual size_t WiFiClient::write(uint8_t)

    virtual size_t write(uint8_t) override;

                  ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:59:18: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'uint8_t {aka unsigned char}'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:60:18: note: virtual size_t WiFiClient::write(const uint8_t*, size_t)

    virtual size_t write(const uint8_t *buf, size_t size) override;

                  ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:60:18: note:   candidate expects 2 arguments, 1 provided

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:62:10: note: size_t WiFiClient::write(Stream&)

    size_t write(Stream& stream);

          ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:62:10: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'Stream&'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:65:10: note: size_t WiFiClient::write(Stream&, size_t)

    size_t write(Stream& stream, size_t unitSize) __attribute__ ((deprecated));

          ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src/WiFiClient.h:65:10: note:   candidate expects 2 arguments, 1 provided

    In file included from C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Stream.h:26:0,

                 from C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/HardwareSerial.h:32,

                 from C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Arduino.h:245,

                 from sketch\esp_fileserver05.ino.cpp:1:

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:76:23: note: size_t Print::write(int8_t)

         inline size_t write(int8_t c) { return write((uint8_t) c); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:76:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'int8_t {aka signed char}'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:75:23: note: size_t Print::write(char)

         inline size_t write(char c) { return write((uint8_t) c); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:75:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'char'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:73:23: note: size_t Print::write(long unsigned int)

         inline size_t write(unsigned long t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:73:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'long unsigned int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:72:23: note: size_t Print::write(long int)

         inline size_t write(long t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:72:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'long int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:71:23: note: size_t Print::write(unsigned int)

         inline size_t write(unsigned int t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:71:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'unsigned int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:70:23: note: size_t Print::write(int)

         inline size_t write(int t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:70:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:69:23: note: size_t Print::write(short unsigned int)

         inline size_t write(unsigned short t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:69:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'short unsigned int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:68:23: note: size_t Print::write(short int)

         inline size_t write(short t) { return write((uint8_t)t); }

                       ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:68:23: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'short int'

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:64:16: note: size_t Print::write(const char*, size_t)

         size_t write(const char *buffer, size_t size) {

                ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:64:16: note:   candidate expects 2 arguments, 1 provided

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:58:16: note: size_t Print::write(const char*)

         size_t write(const char *str) {

                ^

    C:\Users\pl\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h:58:16: note:   no known conversion for argument 1 from 'sdfat::SdFile' to 'const char*'

    exit status 1
    Fehler beim Kompilieren für das Board LOLIN(WEMOS) D1 R2 & mini.

i can't use te line:File download = SD.open(filename); with sdfat.h because i get a compiler error "reference to 'File' is ambiguous"

The problem is this line: size_t sent = server.streamFile(file, "application/octet-stream");

How can i solve this problem?

Thank you for Help...

title: how can i download a file with http from sd card using the SdFat.h

Answers: 0


body:
I am planning to build a small wireless keyboard, around 5 buttons and 1 rotary encoder, that will connect via WiFi to my Spotify account. For this project, I was looking at the Node MCU for the board.

I could not find online how much of a battery I will need for this project. I read somewhere that it can draw up to 200mA, so, if I use 4 of these [batteries](https://www.batteryspace.com/lg-lithium-21700-rechargeable-cell-3-63v-5000mah-18-2wh-inr21700-m50---un38-3-passed.aspx) and run them through a [3V3 regulator](https://www.mgsuperlabs.co.in/estore/3.3V-3.6A-Step-Down-Voltage-Regulator-D36V28F3), i should have 20.000mAh, so it should be able to be powered on for at least 100 hours, right? But it will actually be more, as it does not draw 200mA consistently, right?

Should this work? Do you have any other suggestions? Maybe some different batteries?

Also, how should I go about to make it so that it can have an USB C port that can charge the batteries while it is still in use? Sorry if this question is stupid, this is my first real project.

I thought the easiest, cheapest and dumbest solution was to simply try and fit in a regular 28.000mAh power bank and charge the NodeMCU via USB. Is this a decent idea?

title: NodeMCU Power Draw and charging Circuitry

Answers: 0


body:
I'm using the HC-05 Bluetooth module but I'm confused about the TX,RX pins.
I want to know when should I connect the RX to a divider circuit to convert 5v to 3.3v.
Because while searching, I saw both of the following:

1. either RX is connected to TX of the UNO and TX is connected to RX of the UNO without a divider circuit.
2. or RX is connected to a divider circuit and then connected to any digital pin , TX is connected to any digital pin as well.

So can you give me a thought about both the situations?
my thought is that only digital pins needs a divider rule, but the TX,RX pins can be connected directly and operates without any problems but if so, then what's the difference between both??
Note that I'm using HC-05 to turn on a LED.
Hope to see some good explanation that suits a new Arduino learner.
Thank you..

title: HC-05 TX,RX divider rule

Answers: 2

body: While you *should* use a voltage divider on the Arduino TX --> BT RX signal, you honestly don't need to. Many people, including myself, have used HC-05s without voltage dividers and haven't let "the magic smoke" out of the device. Adding a voltage divider may, though, may increase the lifespan of the HC-05.

body:
You need a logic level translator of some form (such as a resistive divider) if the Arduino runs at 5V. If it's a 3.3V Arduino then you don't need one since the logic levels will match.

You connect to the TX and RX pins (or TX1/RX1 etc) of the Arduino if you want to use a hardware UART (Serial, Serial1, etc). You connect to *any* pins you like (with certain exceptions for the Mega) if you use `SoftwareSerial` instead of a hardware UART.


body:
[![enter image description here][1]][1]I am using proteus and Arduino software to simulate my circuit. What I need to do, is to have an LDR in my Arduino uno. When light intensity increases in my LDR, I need another LED which is connected to a PWM pin to react to this change in light intensity. The more light LDR detects I need my LED to get dimmer and vice versa.
I have uploaded my circuit picture. The potential probe that I have connected to LDR works fine, the more light there is, the higher voltage it has (ranged from 0 to 5v) but on the other side, my LED does not work properly. If LDR detects little light. my LED is turned on, surprisingly with no current passing the ammeter, when light intensity is less than some threshold, my LED starts blinking! again, no current passing through the ammeter! and the voltmeter always varies between 0 and 4.9 (voltmeter on my LED), it never has a value between 0 and 4.9, it seems it acts digitally, while I have used analogWrite. By the way, I mention again that I need my LED pin to have PWM.This is my code in Arduino:

    void setup() {
    Serial.begin(9600);
    pinMode(A0,INPUT);
    pinMode(10,OUTPUT);
    }

    void loop() {

    int sensorValue = analogRead(A0);
    Serial.println(sensorValue);

    analogWrite(10,sensorValue/4);

    delay(200);
    }

By the way, I know the way I have coded, it means that LED follows the torch, and the more light intensity LDR feels, the brighter LED gets, I need it to be vice versa but I also did not know how to use it.
And finally, a minor question:
what does the  Serial.println() function do? I mean it must print it's content somewhere, but where? This feature would be useful for debugging, but I don't know how to see its printed value. I should also say that my code is a modified version of analogReadSerial example.
Thanks.

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

title: Chance light intensity in a pwm pin using LDR using Arduino UNO

Answers: 0


body:
I know it's bad to use Strings due to the memory problems that can occur.
I've tried to remove all instances of strings from my code.
But I'm not sure about this line:

    http.getString().toCharArray(ipAddressBuffer, lengthOfIPAddress);

Is calling `toCharArray()` enough to prevent memory problems? Or is there a string still being created on the heap?

If it's still created on the heap, how can I modify the code so it only deals with cstrings?

Here's my code:

    void setIPAddress(char* ipAddressBuffer){
      HTTPClient http;
      http.begin("http://bot.whatismyipaddress.com/"); //Only allowed to call once per 5 mins.
      http.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
      int httpCode = http.GET();
      if (httpCode > 0) {
        http.getString().toCharArray(ipAddressBuffer, lengthOfIPAddress);
      }
      else {
        Serial.println("Error on HTTP request");
      }
      http.end();
    }

I'm using the HTTPClient.h library btw.

title: Does toCharArray prevent a String being created on the heap?

Answers: 2

body:
The return value of getString allocates and the deletes a char array in heap for a temporary String object.

For ESP8266HTTPClient and ESP32 HTTPClient library you can use `writeToStream` or `getStream()`to read the response without using String class with `getString()`, where `stream` is `WiFiClient& stream = client.getStream();`

`getStream`, returns the underlying WiFiClient. You can read the data with classic `while (stream.available()) { char c = stream.read; ... }`

`writeToStream` copies the data to a stream. My StreamLib library has a stream wrapper over a char array. It is called CStringBuilder.

body:
`http.getString()` creates a temporary Arduino String object and fills text into dynamic memory on the heap. Calling the method `.toCharArray`copies this text to a char array, wherever you defined it.
Immediately after that, the temporary String gets out of scope and the text on the heap is deleted again.


body:
I seem to have an unbelievable thing. My code was working perfectly on one arduino, when i upload the same sketch to another one, it is behaving strangely, it seems like it is not reading any of my pin states:

The code is ment to drive a simple stepper motor with driver. depending on the state of several pins in which direction it moves or moves at all.

What is happening now is when i upload the sketch the motor starts to turn, nomatter what pinstate any of the input pins have, the motor just turns on uploading and even if i apply 5v to any of the pins, it just keeps turning the same direction.

Following the code. I hope someone could tell me what i am doing wrong, i am a newbie to programming:

```c++
int PUL=7; //define Pulse pin
int DIR=8; //define Direction pin
//int ENA=5; //define Enable Pin
int up = 2;
int down = 3;
int limitpin=1;
int limitpinup=4;
int i=0;

int buttonupstate = 0;
int buttondownstate = 0;
int limitstate=0;
int limitstateup=0;

void setup() {
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(limitpin, INPUT);
  pinMode(limitpinup, INPUT);
}

void loop() {
  buttonupstate = digitalRead(up);
  buttondownstate = digitalRead(down);
  limitstate = digitalRead(limitpin);
  limitstateup = digitalRead(limitpinup);
  i = 0;
  switch (limitstateup){
  case LOW:
    switch (limitstate){
    case LOW:
      if (buttondownstate==HIGH){
        do
        {
          digitalWrite(DIR,LOW);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttondownstate = 0;
          buttondownstate = digitalRead(down);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttondownstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      if (buttonupstate == HIGH){
        do
        {
          digitalWrite(DIR,HIGH);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttonupstate = 0;
          buttonupstate = digitalRead(up);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttonupstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      break;
    case HIGH:
      do{
        digitalWrite(DIR,HIGH);
        digitalWrite(PUL,HIGH);
        delayMicroseconds(20);
        digitalWrite(PUL,LOW);
        delayMicroseconds(20);
        limitstate = 0;
        limitstate = digitalRead(limitpin);
      }while (limitstate == HIGH );
      break;
    }
    break;
  case HIGH:
    do{
      digitalWrite(DIR,LOW);
      digitalWrite(PUL,HIGH);
      delayMicroseconds(20);
      digitalWrite(PUL,LOW);
      delayMicroseconds(20);
      limitstateup = 0;
      limitstateup = digitalRead(limitpinup);
    }while (limitstateup == HIGH );
    break;
  }
}
```

title: Arduino doesnt seem to be reading my pin states

Answers: 1

body:
Thanks all of you,

Indeed there is nothing wrong with my code. The problem is indeed in the pull-down resistors, I rebuild the connection on a breadboard and works perfectly. I will have to check my PCB that contains all relays and resistors, the problem has to be on that board, bad connection or something like that.

However I would like to state that on the Osoyoo Uno board, the whole thing worked perfectly, so there has to be something different between Osoyoo Uno board and another Arduino board.

<hr>

Here is the schematic to my PCB board. I checked it again, but i think all the digital pins have actually pull-down resistors active.

[![circuit schematic][1]][1]

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


body:
I have maybe a very stupid question but connecting the +5V pin to a digital input pin programmed as input ( let's say pin2) . Will it destroy the board? Cause after i did this my board doesn't work anymore and i can also not upload a sketch to it. it does nothing anymore, yet nothing has burned or no smoke.

??

Thanks

title: What happens to the board if you connect the +5V pin directly to a digital input configured as input

Answers: 1

body:
> Will it destroy the board?

No, it will just read HIGH. That's what HIGH is - 5V.

> Cause after i did this my board doesn't work anymore

Then you probably did *something else*.


body:
For a project of mine I have always wanted to build an electronic load and I am mostly done. However I have found myself stuck at one part that I thought would be simple but has thus only caused headache.

The problem is that I have a keypad connecting along with a TFT display to an Arduino. I want to enter for example my current for the electronic load and display the value that I set on my display. I have tried the simple code for keypads that is available on tutorials all over the web but what happens is that it displays the key I press but if I press another one it erases the first and displays the second in the same spot. I want to be able to have 4 or 5 digits that can all show up in order. I have found some different code and modified it. I can now display multiple digits but the issue is that if I press for example 4 a 4 will show up but if I press a 5 another 4 will show up and then if I press a 5 again then a 5 will show up on and on.

Additionally it resets the screen even though I don't have a reset function in my code. So every time I press a key the screen will reset to white and then show the numbers. If anyone has time to help me out it would be greatly appreciated.

EDIT: Thank you for everyone's help and I have solved the problem. However I haven't found a way to incorporate a decimal point into it. This code is the code that works except for the decimal point.
<!-- language-all: lang-cpp -->

      #include <Keypad.h>
    #include <MCUFRIEND_kbv.h>
    MCUFRIEND_kbv tft;

    String v1;
    String num;

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

    char hexaKeys[ROWS][COLS] = {
      {'1', '4', '7', '*'},
      {'2', '5', '8', '0'},
      {'3', '6', '9', '.'},
      {'A', 'B', 'C', 'D'}
    };

    byte rowPins[ROWS] = {31, 22, 23, 24};
    byte colPins[COLS] = {25, 26, 27, 28};

    Keypad kpd = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );

    #define BLUE    0x001F
    #define WHITE   0xFFFF

    #define DATAOUT 11//MOSI
    #define DATAIN 12//MISO
    #define SPICLOCK  13//sck
    #define SLAVESELECT0 10//ss

    void setup()
    {
      uint16_t id = tft.readID();
      tft.begin(id);
      tft.setRotation(1);
      tft.fillScreen(WHITE);
      tft.setTextColor(BLUE, WHITE);
    }

    void loop() {
      v1 = GetNumber();
      v1.toInt();
    }
    String GetNumber()
    {
      char key = kpd.getKey();
      // while (key != '#')
      {
        switch (key)

        {
          case NO_KEY:
            break;

          case '0': case '1': case '2': case '3': case '4':
          case '5': case '6': case '7': case '8': case '9':
            num = num + key;
            tft.setTextSize(5);
            tft.setCursor(10, 50);
            tft.print(num);
            break;
        }
        key = kpd.getKey();
      }
      return num;

    }

title: Displaying Keypad Input on TFT Display

Answers: 0


body:
I am running my Arduino based from the ATMEGA328P-PU chip from a 4v battery with this setup:

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

Everything works great and now I will like to make my project permanent building a custom PCB from easyeda.com. Anyways this question is not about how to create the custom PCB I have already made one and it works great. This is the PCB that I created:

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

Because I liked it so much now I want to build it even better. For example now I will like to combine the crystal with the 22pf ceramic capacitors into one small part.

**Question**

Can I use [----THIS----][3] part instead of the basic 22pf capacitor and the big 16Mhz crystal? In other words I want to replace the left picture with the right picture:

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

If its possible to use part [7325-1600A2210-00][3] then where can I find information on what pins to connect to the atmega328 chip and what pins to connect to ground? 7325-1600A2210-00 has 4 pins. To me it makes sense to connect 2 of the pins to pins 9 and 10 and the other 2 pins to ground. Will this work?

  [1]: https://i.stack.imgur.com/TaVAQ.jpg
  [2]: https://i.stack.imgur.com/ZCjEm.png
  [3]: https://lcsc.com/product-detail/New-Arrivals_XTY-7325-1600A2210-00_C389842.html
  [4]: https://i.stack.imgur.com/q5PbO.png

title: Custom build of arduino on a pcb

Answers: 1

body:
> Can I use ----THIS---- part instead of the basic 22pf capacitor and the big 16Mhz crystal?

No. That is just a crystal. You still need the capacitors.  If you want a single device then you need a *ceramic resonator*.

Also you're lacking any decoupling capacitors in your circuit. You may find it works for now, but it will become flaky when you start getting it to do things.


body:
I am having a problem when I want to run code like this on a Arduino Uno with esp8266-01. It's not working. In serial monitor nothing about esp.
<!-- language-all: lang-cpp -->

    #include <SoftwareSerial.h>
    SoftwareSerial esp8266(2,3);

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      esp8266.begin(9600);
      esp8266.print("AT+RST");
      delay(1000);
      esp8266.print("AT+CWMODE=1");
      esp8266.print("AT+CWJAP=\"ssisd\",\"pass\"");

    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

But when I load to Arduino empty code and to serial monitor write "AT" it working or I can connect to
my wifi, but only with empty code.

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

RX is in pin 2 and TX is in pin 3.
And i flashing esp with this [Tutorial][2]

  [1]: https://i.stack.imgur.com/xIwiz.png
  [2]: https://create.arduino.cc/projecthub/pratikdesai/flash-firmware-on-esp8266-esp-01-module-e1f758

title: ESP8266-01 & Arduino Uno Problem

Answers: 0


body:
HDOP is supposed to be greater than 1: https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation)
But I get HDOP about 0.7. What does it mean?

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

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

Where can I found explanation of the output parameters?

title: Why HDOP in TinyGPS++ is less than 1?

Answers: 1

body:
[HDOP can be less than 1 according to this article.](https://support.spirent.com/SpirentCSC/SC_KnowledgeView?Id=FAQ13942). I am no expert in this area, but according to the article, the `HDOP=1` limit is based on 4 satellites; visibility *and use* of more than 4 satellites can reduce HDOP below this limit. When you think on it, this makes sense.

GPS specifications limit the inherent accuracy of a *position solution* through timing errors and vagaries in rf propagation through our atmosphere. Imagine drawing a vector from a GPS satellite to your receiver. The length of that vector represents the distance from the satellite to your receiver, but we depend on *signal timing* to *infer* distance/vector magnitude. In other words, we can only measure distance as accurately as we can measure time.

Now think about the accuracy of a position solution based on a single satellite. If we assume the receiver is confined to the surface of the earth (and the satellite is *geostationary*), the single vector of length **L1** will intersect the surface of the earth forming a circle. Your position could be anywhere on that circle - which could be quite a large range of values!

Now imagine a 2nd satellite, a 2nd vector of length **L2** tracing a second circle. Now your position is constrained to be those points where the two circles intersect - two points! With a third satellite, a 3rd vector of length **L3**, one of these two points will be eliminated.

Now replace those sharp lines with bands or swaths of some width **D**. In this case, the intersection describes a polygon instead of a point. We know our position is within the polygon, but with only three satellites that is the best we can do.

As you can see, adding more satellites will begin to "slice off" sections of the original polygon, making it progressively smaller. So: `HDOP=1` represents the limit with 4 satellites; more satellites yield a smaller polygon, and smaller HDOP.

---

While writing this, I found [a video that does a far better job than my words at describing the position solution process](https://www.youtube.com/watch?v=80nhC0LbbKw) with multiple satellites.

[This video](https://www.youtube.com/watch?v=FU_pY2sTwTA) is quite good also!


body:
I'm trying to control the positioning of a NEMA17 bipolar stepper motor by turning the knob of a potentiometer, using an EasyDriver board.  The control part is solved.  My problem is that if I quickly turn the knob to one end of its range and then back, the stepper motor lags behind by about 1/5 of a second.

All the spec sheets for the motor says I should be able to expect a lot more responsiveness (based on max RPM, acceleration, etc...). I'd like to speed up the responsiveness of the motor to shorten the lag. My code is as follows:

```
//Declare pin functions on Arduino
#define stp 2
#define dir 3  //LOW => forward, HIGH => backward
#define MS1 4
#define MS2 5
#define EN  6

//Declare variables for functions
int x;
int const potPin = A0;
long potval; // current analog read of A0 voltage
int potrotsteps = 166; //num of stepper motor steps for 300-degree rotation
int cur_step_pos = 0; //current position in terms of stepper steps
long cmd_step_pos = 0; //step-position to command stepper motor to go to
int tomove; //num steps to move

void setup() {
  //stepper motor setup
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); //Set step, direction, microstep and enable pins to default states
  Serial.begin(9600); // initialize serial communication at 9600 bits per second
  Serial.println("\n\n\n#################    setup completed     #################");
}

void loop() {

  //map analog voltage read from pot to a step-position (0-166) of the stepper motor
  potval = analogRead(potPin);
  cmd_step_pos = potval * potrotsteps / 1023; // find where stepper motor should be in terms of step-position
  tomove = abs(cur_step_pos - cmd_step_pos);

  if (cmd_step_pos > cur_step_pos) { //if should-be position greater than current position
    digitalWrite(dir, LOW); // move forward
    CommandStepperMotor(tomove); //move forward by the diff in position
  } else { //if should-be position is lower
    digitalWrite(dir, HIGH); //move backward
    CommandStepperMotor(tomove); //move backward by diff in position
  }
  cur_step_pos = cmd_step_pos; //current position is now former should-be position

}

//GLOBAL FUNCTIONS

//Reset Easy Driver pins to default states
void resetEDPins() {
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);  //default "forward" movement
  digitalWrite(MS1, LOW); // L-L => full steps, H-L => 1/2 step
  digitalWrite(MS2, LOW); // L-H => 1/4 steps, H-H => 1/8 step
  digitalWrite(EN, LOW); //Enable motor control
}

void CommandStepperMotor(int numsteps) {
  for (x = 0; x < numsteps; x++) {
    digitalWrite(stp, HIGH); //Trigger one step forward
    delay(1);
    digitalWrite(stp, LOW); //Pull step pin low so it can be triggered again
    delay(1);
  }
}
```

I understand that changing delay(1) to delayMicroseconds(100) in the **CommandStepperMotor** function should help, but as it turns out, anything smaller than a delay of 1 millisecond stalls the motor.  I've tried to Google other's solutions to the problem, but it seems they had no problem at all lowering the delay in sending the HIGH/LOW signals to the stepper pin to <1 ms.

Any ideas?  Thanks in advance!

title: How can I increase the responsiveness/speed of my stepper motor?

Answers: 1

body:
Your problem is that you want to go from a standstill to full speed instantly. That just isn't going to happen. As you have seen there is a limit to how fast you can go from stationary.

If you want to go faster you will have to *accelerate* up to that speed.

The simplest way to do that is to use a library that is designed for it, such as the popular [AccelStepper.h](https://www.airspayce.com/mikem/arduino/AccelStepper/index.html) library.


body:
TinyGPS++ give many output parameters. Where can I find explanation what do all output parameters mean? I don't understand what is the meaning of the following parameters:

> Course Speed Card  Distance Course Car

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

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

UPD

**2365** is distance to London

**wnw** is the direction to London: https://en.wikipedia.org/wiki/Points_of_the_compass#Compass_point_names

**0.00** - Vertical speed?

**0.06** - Horizontal speed?

**294.06** - ???

title: What do the TinyGPS++ output parameters mean?

Answers: 1

body:
As you can see when you look at the source code of the FullExample.ino that is part of the TinyGPS++ library, the values you marked are:

1. Course Speed Card*: The current speed (in km/h), course (in degrees) and cardinal course (which is the course translated to a cardinal direction on a compass, i.e. N,S,E,W, NE, NNW, etc.) of the GPS receiver (i.e. you).

2. Distance Course Card**: The distance (in km) and course and cardinal course to some location or waypoint (London in this example).

After the information you added in your edit, this means the following:

 - 0.00 is your current course over ground (i.e. due North)
 - 0.06 is current current speed over ground (i.e. as good as stationary)
 - N is your current cardinal course
 - 2365 is the distance to London (km)
 - 294.06 is the bearing to London from your location
 - WNW is the cardinal bearing to London

\* this is also known as SOG (Speed Over Ground) and COG (Course Over Ground, which is used in (aero)nautical navigation) or Bearing.

\** this is also known as DTG and CTS (Distance to Go and Course to Steer) when navigating to a GPS waypoint.


body:
i want to get the date and time (Timestamp) of a specific file on sd card.
How can i do this?

I use the sd.h and can not use any other like SdFat.h

title: how to get file date and time (Timestamp) from a file on sd card with SD.h?

Answers: 0


body:
I have an esp8266 wifi module, arduino uno and an old mobile. I was wondering if there is any way by which i could remove the camera from the mobile and connect it with my arduino in order to view video captured by the camera.
Is this possible by the hardware which i currently have? Or i will have to buy more hardware?
Please let me know if more information is required also give the link of helpful articles.

title: Is there any way to connect my old phone camera with an arduino?

Answers: 2

body:
> **Is there any way to connect my old phone camera with an arduino?**

Yes, but it may be a huge amount of work requiring expensive equipment and skills that take decades to acquire.

See [Mike's Electric - Interfacing a cheap phone camera module to a PIC32 microcontroller.](https://www.youtube.com/watch?v=rQYByorpoFk) which is a great video and will give you an idea of what is involved. Note that he's using a 32-bit microcontroller with relatively large RAM on the chip. You might need to use a 32-bit Arduino (Due etc) not one of the 8-bit Arduinos (Uno etc).

Mike is the kind of person who could reverse-engineer a random camera module from an old phone but this isn't a project for a typical Arduino user like you or I.

Since these camera modules cost about $1, it is probably best to look for a [camera breakout for Arduino](https://www.google.com/search?q=arduino+camer+module) that comes with documentation and software libraries.

body:
An Uno is undersized and underpowered (speed) for this job. Without even considering how to transfer the image, an Uno has nowhere for it to go. The most modest cell phone cameras' images were probably 3 Megapixels, and even assuming 2 bytes of storage per pixel (allowing 5 bits for each of 3 colors), you'd need 6 MB  or 6000 KB to store the image. An Uno's RAM is 2K bytes before you subtract whatever RAM its program needs besides room to store the image. Based on those assumptions, an Uno would need another memory, 3000 times the size of its RAM, to hold the image.

Update:

> Is there any possibility that the image is not stored in the arduino
> rather sent to the server in stream (i.e in small packets)?

I can't imagine why not - at least in theory - but I have no idea what kind of communication hardware might be built into the camera, or if you'd need to develop something on your own. But somehow you'll need to get the image data to the Arduino and in some kind of format you understand and can work with, at least once it gets to the web application. At this point, the critical piece of knowledge would be to know the specs of how the camera delivers image data - how fast, in what format, must the Arduino and the camera interact or does the data just pour out in a flood once started, ... ?

Your first steps will probably need to be to learn how some typical cameras handle this, and to figure out what specific camera you have and how *that* camera works. Then you'll have a much better idea about what it will take to complete your project.


body:
I'm using two HC-05 modules on two Arduino UNO boards. One of my modules connected successfully to a raspberry pi port. However the other doesn't want to connect, but sometimes it does and then randomly disconnects. When I did manage to connect both modules to port on the pi I had code written to send data to the pi and display it in the terminal but only one Arduino data would show up on the pi terminal even though both were sending data. Is there an easier way to connect the modules? I've been using the bluetooth manager tool on the pi

```
void setup() {
 Serial.begin(9600);
 pinMode(8, INPUT); // first sensor input
 pinMode(7, INPUT); // second sensor input
 pinMode(6, INPUT); // third sensor input
 pinMode(5, INPUT); // fourth sensor input

}

void loop()
{

    int sensordata_1 = digitalRead(8); // read status and store it into variable
     {
          if(sensordata_1 == LOW)        //  CAGE 1
          {
            Serial.println("Arduino 1 s1: 1");  //
          }
          else
          {
            Serial.println("Arduino 1 s1: 0");
          }
          delay(200);

    }
}
```

```
void setup() {
 Serial.begin(9600);
 pinMode(8, INPUT); // first sensor input
 pinMode(7, INPUT); // second sensor input
 pinMode(6, INPUT); // third sensor input
 pinMode(5, INPUT); // fourth sensor input

}

void loop()
{

    int sensordata_1 = digitalRead(8); // read status and store it into variable
     {
          if(sensordata_1 == LOW)        //  CAGE 1
          {
            Serial.println("Arduino 2 s1: 1");  //
          }
          else
          {
            Serial.println("Arduino 2 s1: 0");
          }
          delay(200);

    }
}
```
```
import serial
import time

port = serial.Serial("/dev/rfcomm2", baudrate=9600)
port_2 = serial.Serial("
port.flush() # This wil flush any input and output buffer, so it will
#avoid receiving or sending bad data

while True:

    if(port.in_waiting > 0):
        data = port.readline().decode('utf-8').rstrip() # decode will translate
        #the data from unicode to byte
        print(data)
```

title: Arduino communication to Raspberry Pi using HC-05

Answers: 1

body:
 1. `port_2 = serial.Serial("` is most likely a copy and paste error on your part, but needs to be fixed if you want 2 serial ports to deal with
 2. You only read from `port` in your Python while loop without touching `port_2`. This is the reason you only see output from one serial port
 3. You should use a robust serial data packet-system. Right now you have no way of ensuring that the data received in Python is corrupt or not. You can easily use the pip-installable Python package [pySerialTransfer][1] and compatible Arduino library [SerialTransfer.h][2] (installable via the Arduino IDE's Libraries Manager).

For theory behind robust serial communication, check out the tutorials [Serial Input Basics][3] and [Serial Input Advanced][4].

  [1]: https://github.com/PowerBroker2/pySerialTransfer
  [2]: https://github.com/PowerBroker2/SerialTransfer
  [3]: https://forum.arduino.cc/index.php?topic=396450.0
  [4]: https://forum.arduino.cc/index.php?topic=662346.0


body:
Im having some problems with parsing gps coordinates with the arduino ide.

To be honest I want to process the data without a library.

From my sensor I get this String: 4815.98450

The result of String.toDouble(): 4815.9843750

I also parsed it on my own, but i got the same result: (yes this code is not nice ;))

`````
char buf[10];
  msg.toCharArray(buf, 19);
  double num = 0.0;

  int c;

  c = buf[0] - '0';
  double num0 = (c * 1000);
  c = buf[1] - '0';
  double num1 = (c * 100);
  c = buf[2] - '0';
  double num2 = (c * 10);
  c = buf[3] - '0';
  double num3 = (c * 1);
  c = buf[5] - '0';
  double num5 = (c * 0.1);
  c = buf[6] - '0';
  double num6 = (c * 0.01);
  c = buf[7] - '0';
  double num7 = (c * 0.001);
  c = buf[8] - '0';
  double num8 = (c * 0.0001);
  c = buf[9] - '0';
  double num9 = (c * 0.00001);
  num = num + num0;
  num = num + num1;
  num = num + num2;
  num = num + num3;
  num = num + num5;
  num = num + num6;
  num = num + num7;
  num = num + num8;
  num = num + num9;
``````

Does somebody have a solution for my problems?

Thank you very much :=)

title: Arduino parsing Double is incorrect

Answers: 3

body:
There is no easy solution. The Arduino you are using does not support
double precision floating point. The type `double` is just an alias for
`float`, which has 24-bit accuracy.

Your program is actually giving you the correct result, as the float
closest to 4815.98450 is exactly 4815.984375.

body:
`double` (or float) is just an inappropriate data type.

Perhaps you take int(4815) and float(0.98450) as two numbers?

----------
And BTW, I bet from your sensor you don't get a String object.

body:
You can convert this to a long, do your arithmetic, and convert it back to an ASCII-Decimal number:

Remove the decimal point from the string. Convert the remaining string of digits to a long. Now you have the coordinate in binary, in units of the least significant decimal digit; 1 lsb == 0.00001, if you used 5 decimal places.

Manipulate your data however you need to using long integer arithmetic.

Divide the value by 10^ -(# of fraction digits you used). The quotient is the whole number part; the remainder is the fractional part. Print the quotient and a decimal point. Print the remainder padding with zeros to the left as necessary to result in your printing (# of fraction digits you used) total fraction digits.

The output conversion is even easier if you're willing to use sprintf():<br>
Divide the value by 10^ -(# of fraction digits you used), as above. Let's assume 5 places as in your example:

    char buffer[BIGENOUGH+1];
    sprintf(buffer, "%ld.ld", value/100000, value0000);

Note that I made two divisions to get the quotient and the remainder and assumed you could tolerate the performance hit. If you're expecting to crank out a lot of values and speed is a factor, you could look up or write a division routine that can return both the quotient and the remainder results from a single division.

Update: @edgar_bonet points out that the compiler is smart enough to notice this fragment uses both results of the numerically same division and avoids dividing twice after all.


body:
    #include "connection.h"

    void setup() {
      Serial.begin(115200);
      Funcs::Connect conn;
      conn.connectWifi();
    }

    void loop() {

    }

then **connection.h** file:

    // connection.h

    namespace Funcs
    {
      class Connect
      {
        public:
          void connectWifi();
      };
    }

and then **connection.cpp**

    #include <Arduino.h>
    #include <ESP8266WiFi.h>
    #include "connection.h"
    const char* ssid     = "ssid";
    const char* password = "password";

    namespace Funcs
    {

      void connectWifi() {
        // Connect to WiFi network
        Serial.println();
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(ssid);

        WiFi.begin(ssid, password);

        while (WiFi.status() != WL_CONNECTED) {
          delay(10);
          Serial.print(".");
        }
        Serial.println("");
        Serial.print("WiFi connected with ip ");
        Serial.println(WiFi.localIP());

      }
    }
On compiling I get this error:

    /Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/cores/esp8266/HardwareSerial.h:76:
    undefined reference to `Funcs::Connect::connectWifi()'
collect2: error: ld returned 1 exit status

    collect2: error: ld returned 1 exit status
    exit status 1
    Error compiling for board WeMos D1 R1.

But I do not have `Funcs::Connect::connectWifi()` in my code, it was in old code.

title: trying to make wemos d1 code modular causes collect2: error: ld returned 1 exit status exit status 1

Answers: 1

body:
You are calling Funcs::Connect::connectWifi() right here:

    conn.connectWifi();

since conn is of type Funcs::Connect

But you defined a function Funcs::connectWifi():

    namespace Funcs
    {

      void connectWifi() {

where I think you meant to have connectWifi be a member of that Connect class.

    namespace Funcs
    {

      void Connect::connectWifi() {

That's not the only issue with your code, you also create the instance in setup and let it go out of scope after calling just the one function.  But that's a different kind of error.  It's legal code, just probably doesn't do what you want.


body:
For IR sender at Nano Every (ATMega4809-based) I am using infrared4arduino to send simple remote control codes. I am double-checking those with a Nano-based receiver with IRrecvDumpV2 example from IRremote library but I am receiving something else what I am sending (I think):

The sender has the following code using Infrared4Arduino:
```
   IrSignal* sig=Nec1Renderer::newIrSignal(0,0x906f); // cmd 0x90
   IrSenderPwm::getInstance(true)->sendIrSignal(*sig,1);
```
but the receiver dumps (besides some garbage like 0-bit `JVC` and `SANYO` frames):
```
Encoding  : NEC
Code      : FFF609 (32 bits)
unsigned int  data = 0xFFF609;
```
`0x00` and `0xff` (first 2 bytes of the "packet") are device and its logical complement, those are fine.

The command sent as `0x90` (followed by its logical complement `0x6f`) is decoded as `0xF6` (plus its logical complement `0x09`). Why? Is it an accident that `906f` is `f609` backwards?

What's going on here?

I will try to run both sender and receiver with the same lib (IRremote is not ported to Nano Every) but before I go ahead, better ask. Perhaps I am only doing some IR-beginner's mistake.

title: IR signal: different libs, different bit/byte ordering?

Answers: 1

body: It is the receiver (IRremote-based) which is decoding bits in reverse order. IRremote and IRLib2 implement the NEC protocol incorrectly (both on sending and receiving sides). More details in the issue report https://github.com/bengtmartensson/Infrared4Arduino/issues/52 .


body:
Good night! Based on stuff I get a bit here and there, came up with a program for an Arduino Audio Selector with shift registers and some features. Working as expected, only missing connecting the relay boads, but that's for future. Since I have a few devices, instead of having to write all, is there anyway of I change for instance a line and then on display show that line?

Thanks. Here's my code, realy big, try to short the part of the shift registers but seems to me it was unstable.

[Arduino selector 4x20][1]

  [1]: https://github.com/nmbb/arduinoaudioselectorlcd20x4/blob/master/arduino_selector_20x4_function_shift_register.ino

title: Possibility of clean the code?

Answers: 1

body:
I see a lot of 'almost' repetitions like :

      if (RelaySourceDigi == 7) {
        shifter.setPin(16, LOW);
        shifter.setPin(17, LOW);
        shifter.setPin(18, LOW);
        shifter.setPin(19, LOW);
        shifter.setPin(20, LOW);
        shifter.setPin(21, LOW);
        shifter.setPin(22, HIGH);
        shifter.setPin(23, LOW);
        shifter.write();
        lcd.setCursor(0, 2);
        lcd.write(8);
        lcd.setCursor(2, 2);
        lcd.print("Coaxial 3");
      }

Move this to a separate function, and make an argument (or more) of items that vary.
This will greatly reduce your code, making it more managable/maintainable.

Below I changed the entire program. Note I didn't check for runtime errors, and it is highly possible I made some copy/paste errors, but it will give you a clue what you can change. As you can see, the program is radically shortened (and more maintainable).

What you need to do is:

- Check each change
- Check for copy/paste errors
- Read a little bit about pointers (e.g. the `&RelaySource` and `*t` constructs)
- Also I highly suggest not to use so many constants, but use `enum`s, to denote the value for each different mode you have. So instead of `case 1`, you can write `case TAPE_1`.
- Split `loop` in smaller functions (e.g. one function per mode).
- I didn't install your libraries but used e.g. #include "LiquidCrystal_I2C.h" and stubbed all functions (meaning I can call them but they don't do anything, just to check for compiler errors in the main program).
- Also instead of Aux, use a boolean `(true, false)`.
- You see I use a lot of `(state - 1)` constructs. It's common practice to start counting at 0, not at 1, it will make your life easier. Only when displaying a value for a user, add +1.
Below the program.

        //Libraries
        #include "LCD.h"
        #include "LiquidCrystal_I2C.h"
        #include "Shifter.h"

        #define SER_Pin 8 //SER_IN 14 on 74HC595
        #define RCLK_Pin 9 //L_CLOCK 12 on 74HC595
        #define SRCLK_Pin 10 //CLOCK 11 on 74HC595
        #define NUM_REGISTERS 3 //how many registers are in the chain
        //initaize shifter using the Shifter library
        Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

        LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

        const int ButtonPinUp = 2;
        int ButtonPinUpState = 0;
        const int ButtonPinDn = 3;
        int ButtonPinDnState = 0;
        const int MuteButtonPin = 5;
        int MuteButtonPinState = 0;
        const int AuxButtonPin = 4;
        int AuxButtonPinState = 0;
        const int fbutton = 6;
        int RelaySource = 1;
        int RelaySourceDigi = 1;
        int RelayRec = 1;
        int RecDigi = 1;
        int Mute = 0;
        int Mode = 0;
        int Aux = 1;
        int state = 0;
        int old = 0;
        int ButtonPoll = 0;

        byte opt[8] = {
          0b00000,
          0b01110,
          0b11011,
          0b10001,
          0b10001,
          0b10001,
          0b11111,
          0b00000
        };

        byte coax[8] = {
          0b00100,
          0b01110,
          0b11111,
          0b10001,
          0b10001,
          0b01110,
          0b00100,
          0b00100
        };

        byte mut[8] = {
          0b00001,
          0b00011,
          0b00111,
          0b11111,
          0b11111,
          0b00111,
          0b00011,
          0b00001
        };

        byte outp[8] = {
          B00000,
          B00100,
          B00110,
          B11111,
          B11111,
          B00110,
          B00100,
          B00000
        };

        byte upp[8] = {
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111
        };

        byte inpp[8] {
          0b10000,
          0b10000,
          0b10100,
          0b10110,
          0b11111,
          0b00110,
          0b00100,
          0b00000
        };

        byte ann[8] {

          0b11111,
          0b10001,
          0b10101,
          0b10101,
          0b10001,
          0b10101,
          0b10101,
          0b11111
        };

        byte dnn[8] = {
          0b11111,
          0b10011,
          0b10101,
          0b10101,
          0b10101,
          0b10101,
          0b10011,
          0b11111
        };

        byte too[8] = {
          0b00000,
          0b00100,
          0b00110,
          0b11111,
          0b00110,
          0b00100,
          0b00000,
          0b00000
        };

        void printAtCursor(int a, int b, const char* c)
        {
          lcd.setCursor(a, b);
          lcd.print(c);
        }

        void setup() {
          lcd.begin(20, 4);
          lcd.backlight();

          byte* list[] = {outp, coax, mut, opt, upp, inpp, ann, dnn, too };
          for (int n = 0; n < 9; n++)
          {
            lcd.createChar(n + 1, list[n]);
          }

          pinMode(fbutton, INPUT);
          pinMode(ButtonPinUp, INPUT);
          pinMode(MuteButtonPin, INPUT);
          pinMode(ButtonPinDn, INPUT);
          pinMode(AuxButtonPin, INPUT);

          for (int n = 11; n < 14; n++)
          {
            pinMode(n, OUTPUT);
          }

          printAtCursor(3, 0, "Digital/Analog");
          printAtCursor(3, 1, "Audio Selector");
          printAtCursor(4, 2, "Built-In DAC");
          printAtCursor(2, 3, "V2.0f (23052020)");
          delay(4000);
          lcd.clear();
        }

        void setPin(int first, int last, int pin)
        {
          for (int n = first; n < last + 1; n++)
          {
            shifter.setPin(n, pin == n ? HIGH : LOW);
          }

          shifter.write();
        }

        void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
        {
            lcd.setCursor(0, a);
            lcd.write(b);
            lcd.setCursor(2, a);
            lcd.print(t);
            if (x != -1)
            {
              lcd.write(x);
              lcd.print(u);
            }
        }

        void loop()
        {
          // shifter.clear(); //set all pins on the shift register chain to LOW
          shifter.write(); //send changes to the chain and display them
          //check button states
          ButtonPinUpState = digitalRead(ButtonPinUp);
          ButtonPinDnState = digitalRead(ButtonPinDn);
          MuteButtonPinState = digitalRead(MuteButtonPin);
          AuxButtonPinState = digitalRead(AuxButtonPin);
          ButtonPoll = digitalRead(fbutton);

          if (AuxButtonPinState == HIGH && RelaySource == 1 && state == 1) {
            lcd.clear();
            Aux           = ~Aux;
            digitalWrite(13, Aux == 0 ? LOW : HIGH);
          }

          if (ButtonPoll == HIGH) {
            state = old + 1;
          }

          lcd.clear(); // Happens in all cases
          switch (state) {
            case 1: // Fall through
            case 2: // Fall through
            case 3: // Fall through
            case 4:
              lcd.setCursor(1, state - 1);
              lcd.write(5);
              old = state;
              break;

            default:
              old = 0;
              break;
          }

          // Assuming state = 1..4
          if (ButtonPinUpState == HIGH)
          {
            lcd.clear();
            int* t = NULL;
            int maxValue = -1;

            switch (state)
            {
              case 1: t = &RelaySource;     maxValue = 8; break;
              case 2: t = &RelayRec;        maxValue = 5; break;
              case 3: t = &RelaySourceDigi; maxValue = 8; break;
              case 4: t = &RecDigi;         maxValue = 4; break;
              default: break;
            }

            *t = min(1, max(maxValue, *t + (ButtonPinUpState == HIGH ? 1 : 0) + (ButtonPinDnState == HIGH ? -1 : 0)));
          }

          if (MuteButtonPinState == HIGH) {
            lcd.clear();
            Mute = (Mute == 0 ? 1 : 0);
            digitalWrite(12, Mute == 0 ? HIGH : LOW);
          }

          // RelaySource
          setPin(0, 7, RelaySource - 1);
          if (RelaySource == 1 && Aux == 0)
          {
            setLines(0, 7, "D", 9, "A:");
          }
          else
          {
            const char* rs1[] = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };
            setLines(0, 7, rs1[RelaySource - 1]);
          }

          if (RelaySource == 8)
          {
            shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
          }

          // RelayRec
          int         rr1[] = { 8      , -1   , 9       , 10      , 11       };
          const char* rr2[] = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
          const int   rr3[] = { -1     , -1   , 9       , 9       , 9        };
          const char* rr4[] = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

          setPin(8, 11, rr1[RelayRec - 1]);
          setLines(1, 6, rr2[RelayRec - 1], rr3[RelayRec - 1], rr4[RelayRec - 1]);

          // RelaySourceDigi
          setPin(16, 23, 17 - RelaySourceDigi);
          if (RelaySource == 1 && Aux == 0)
          {
            lcd.setCursor(7, 0);
            const char* t[] = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
            lcd.print(t[RelaySource - 1]);
          }

          const char* t1[] = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
          const int   t2[] = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
          const char* t3[] = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };
          setLines(2, 8, t1[RelaySourceDigi - 1], t2[RelaySourceDigi - 1], t3[RelaySourceDigi - 2]);

          // RecDigi
          const char* t[] = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
          setPin(12, 15, 11 + RecDigi);
          setLines(3, 6, t[RecDigi - 1]);

          delay(150);
        }

**Update**

I wanted for myself to see how to clean it fully, so I tried below.

Still check for copy/paste problems, as I didn't execute the sketch (but it compiles without warnings).

Original sketch: 2746 bytes (8%) program storage space, 142 bytes (6%) of dynamic memory
Sketch below   : 1546 bytes (4%) program storage space,  40 bytes (2%) of dynamic memory.

Conclusion:

- 25% less program storage space used
- 67% less dynamic memory used
- Less lines of code
- Better readability
- Better maintainability
- No (or less) code duplication
- Smaller function complexity
- Less statements (added more to initialization)

Code:

    //Libraries
    #include "LCD.h"
    #include "LiquidCrystal_I2C.h"
    #include "Shifter.h"

    const uint8_t SER_Pin = 8; //SER_IN 14 on 74HC595
    const uint8_t RCLK_Pin = 9; //L_CLOCK 12 on 74HC595
    const uint8_t SRCLK_Pin = 10; //CLOCK 11 on 74HC595
    const uint8_t NUM_REGISTERS = 3; //how many registers are in the chain

    Shifter _shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);
    LiquidCrystal_I2C _lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

    enum EMode
    {
      RELAY_SOURCE,
      RELAY_REC,
      RELAY_SOURCE_DIGI,
      REC_DIGI,
      LAST_MODE
    };

    static const uint8_t _buttonPinUp = 2;
    bool _buttonPinUpState = false;
    static const uint8_t _buttonPinDown = 3;
    bool _buttonPinDownState = false;
    static const uint8_t _muteButtonPin = 5;
    bool _muteButtonPinState = false;
    static const uint8_t _auxButtonPin = 4;
    bool _auxButtonPinState = false;
    static const uint8_t _forwardButton = 6;
    uint8_t _relaySource = 0;
    uint8_t _relaySourceDigi = 0;
    uint8_t _relayRec = 0;
    uint8_t _recDigi = 0;
    bool _mute = false;
    bool _aux = true;
    EMode _mode = RELAY_SOURCE;
    bool _buttonPoll = false;

    static const byte OPT[8]  PROGMEM = {  0b00000,  0b01110,  0b11011,  0b10001,  0b10001,  0b10001,  0b11111,  0b00000 };
    static const byte COAX[8] PROGMEM = {  0b00100,  0b01110,  0b11111,  0b10001,  0b10001,  0b01110,  0b00100,  0b00100 };
    static const byte MUT[8]  PROGMEM = {  0b00001,  0b00011,  0b00111,  0b11111,  0b11111,  0b00111,  0b00011,  0b00001 };
    static const byte OUTP[8] PROGMEM = {  B00000 ,  B00100 ,  B00110 ,  B11111 ,  B11111 ,  B00110 ,  B00100 ,  B00000  };
    static const byte UPP[8]  PROGMEM = {  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111 };
    static const byte INPP[8] PROGMEM = {  0b10000,  0b10000,  0b10100,  0b10110,  0b11111,  0b00110,  0b00100,  0b00000 };
    static const byte ANN[8]  PROGMEM = {  0b11111,  0b10001,  0b10101,  0b10101,  0b10001,  0b10101,  0b10101,  0b11111 };
    static const byte DNN[8]  PROGMEM = {  0b11111,  0b10011,  0b10101,  0b10101,  0b10101,  0b10101,  0b10011,  0b11111 };
    static const byte TOO[8]  PROGMEM = {  0b00000,  0b00100,  0b00110,  0b11111,  0b00110,  0b00100,  0b00000,  0b00000 };

    static const byte* const CHAR_LIST[] PROGMEM = {OUTP, COAX, MUT, OPT, UPP, INPP, ANN, DNN, TOO };
    static const uint8_t PINS[] PROGMEM = { _forwardButton, _buttonPinUp, _muteButtonPin, _buttonPinDown, _auxButtonPin };

    static uint8_t* const    MODE_VALUES[] PROGMEM = { &_relaySource, &_relayRec, &_relaySourceDigi, &_recDigi };
    static const uint8_t     MAX_VALUES[] PROGMEM = { 7             , 4         , 7                , 3         };

    static const char* const RELAY_SOURCES[] PROGMEM = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };

    static const char* const RELAY_SOURCE_DIGI_1[] PROGMEM = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
    static const int         RELAY_SOURCE_DIGI_2[]         = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
    static const char* const RELAY_SOURCE_DIGI_3[] PROGMEM = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };

    static const int         RELAY_REC_1[] PROGMEM = { 8      , -1   , 9       , 10      , 11       };
    static const char* const RELAY_REC_2[] PROGMEM = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
    static const int         RELAY_REC_3[] PROGMEM = { -1     , -1   , 9       , 9       , 9        };
    static const char* const RELAY_REC_4[] PROGMEM = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

    static const char* const DIGI_RELAY_SOURCES[] PROGMEM = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };

    void printAtCursor(int a, int b, const char* c)
    {
      _lcd.setCursor(a, b);
      _lcd.print(c);
    }

    void setup()
    {
      _lcd.begin(20, 4);
      _lcd.backlight();

      for (int n = 0; n < 9; n++)
      {
        _lcd.createChar(n + 1, (byte*) CHAR_LIST[n]);
      }

      for (int n = 0; n < sizeof(PINS) / sizeof(uint8_t); n++)
      {
        pinMode(PINS[n], INPUT);
      }

      for (int n = 11; n < 14; n++)
      {
        pinMode(n, OUTPUT);
      }

      printAtCursor(3, 0, "Digital/Analog");
      printAtCursor(3, 1, "Audio Selector");
      printAtCursor(4, 2, "Built-In DAC");
      printAtCursor(2, 3, "V2.0f (23052020)");
      delay(4000);
    }

    void setPin(int first, int last, int pin)
    {
      for (int n = first; n < last + 1; n++)
      {
        _shifter.setPin(n, pin == n ? HIGH : LOW);
      }

      _shifter.write();
    }

    void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
    {
        _lcd.setCursor(0, a);
        _lcd.write(b);
        _lcd.setCursor(2, a);
        _lcd.print(t);

        if (x != -1)
        {
          _lcd.write(x);
          _lcd.print(u);
        }
    }

    void ResetShifter()
    {
      // _shifter.clear(); //set all pins on the shift register chain to LOW
      _shifter.write(); //send changes to the chain and display them
    }

    void ReadButtons()
    {
      _buttonPinUpState = digitalRead(_buttonPinUp) == HIGH;
      _buttonPinDownState = digitalRead(_buttonPinDown) == HIGH;
      _muteButtonPinState = digitalRead(_muteButtonPin) == HIGH;
      _auxButtonPinState = digitalRead(_auxButtonPin) == HIGH;
      _buttonPoll = digitalRead(_forwardButton) == HIGH;
    }

    void HandleAuxButton()
    {
      if (_auxButtonPinState && (_relaySource == 0) && (_mode == EMode::RELAY_SOURCE))
      {
        _aux = !_aux;
        digitalWrite(13, _aux ? HIGH : LOW);
      }
    }

    void HandlePollButton()
    {
      if (_buttonPoll)
      {
        _mode = (EMode) ((_mode + 1) % EMode::LAST_MODE);
      }
    }

    void StartLcd()
    {
      _lcd.clear(); // Happens in all cases
      _lcd.setCursor(1, (int) _mode);
      _lcd.write(5);
    }

    void HandleButtonPinUp()
    {
      if (_buttonPinUpState)
      {
        static uint8_t* const modeValue = MODE_VALUES[_mode];
        static uint8_t maxValue = MAX_VALUES[_mode];
        *modeValue = min(0, max(maxValue, *modeValue + (_buttonPinUpState ? 1 : 0) + (_buttonPinDownState ? -1 : 0)));
      }
    }

    void HandleMuteButton()
    {
      if (_muteButtonPinState)
      {
        _mute = !_mute;
        digitalWrite(12, _mute ? HIGH : LOW);
      }
    }

    void ProcessRelaySource()
    {
      // RelaySource
      setPin(0, 7, _relaySource);
      if (_relaySource == 0 && !_aux)
      {
        setLines(0, 7, "D", 9, "A:");
      }
      else
      {
        setLines(0, 7, RELAY_SOURCES[_relaySource]);
      }

      if (_relaySource == 7)
      {
        _shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
      }
    }

    void ProcessRelayRec()
    {
      setPin(8, 11, RELAY_REC_1[_relayRec]);
      setLines(1, 6, RELAY_REC_2[_relayRec], RELAY_REC_3[_relayRec], RELAY_REC_4[_relayRec]);
    }

    void ProcessRelaySourceDigi()
    {
      setPin(16, 23, 17 - _relaySourceDigi);
      if (_relaySource == 0 && !_aux)
      {
        _lcd.setCursor(7, 0);
        _lcd.print(DIGI_RELAY_SOURCES[_relaySource]);
      }
      setLines(2, 8, RELAY_SOURCE_DIGI_1[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_2[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_3[_relaySourceDigi - 2]);
    }

    void ProcessRecDigi()
    {
      static const char* const t[] PROGMEM = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
      setPin(12, 15, 12 + _recDigi);
      setLines(3, 6, t[_recDigi]);
      delay(150);
    }

    void loop()
    {
      ResetShifter();
      ReadButtons();

      HandleAuxButton();
      HandlePollButton();
      StartLcd();
      HandleButtonPinUp();
      HandleMuteButton();

      ProcessRelaySource();
      ProcessRelayRec();
      ProcessRelaySourceDigi();
      ProcessRecDigi();
    }


body:
I am trying to read data from thingspeak for esp8266 but I couldn't do that. There is a link:
GET https://api.thingspeak.com/channels/123456/fields/1.json?api_key=***********&results=2
But how can I use it?

title: How to read data from ThingSpeak for esp8266

Answers: 1

body:
I directly code the esp8266 with thingSpeak library. Anyone who is interested look here:[How to read data from thingspeak][1]. And it worked. Thanks for your replies.

  [1]: https://electronics-project-hub.com/how-to-read-data-from-thingspeak-arduino-esp8266-nodemcu/


body:
I have a potentiometer attached to one analog port of arduino (assume A0)
I'm reading the value of that using ```input_voltage = analogRead (A0);``` which is a value between 0-1023.
So I want to map this value to frequency from 1Hz to 20Hz. Then I want to fade my LED using this frequency.
Tried to doing this map using ```int frequency = map (input_voltage, 0, 1023, 1, 20);```
But how can i apply this frequency to LED?
I mean PWM has a constant frequency (about 500Hz). How should I apply frequencies from 1 to 20 to this LED in order to fade it?

title: Fading LED with different frequencies

Answers: 1

body:
There is a library in which you can change the frequency

Here is my example code I did long time ago I had the same problem

Get the library from [here][1]

Go ahead and try example code there and try to understand too.

**Include the library first to code**

my code

    void setup() {
      pinMode(13, OUTPUT);
      pinMode(8, OUTPUT);
      digitalWrite(8,LOW);
      Serial.begin(115200);
      InitTimersSafe();
    }
    void loop() {
      //mapping
      long x = map(analogRead(A0),0,1023,1,20);
      bool b = SetPinFrequencySafe(9,x);
      digitalWrite(13,b);
      pwmWrite(9,127);
      Serial.print(x);
      Serial.print(" Hz ");
      Serial.println(b);
      delay(100);
    }

Built in led will turn on if the frequency is stetted.

By the way led will turn on in 50% on and 50% off in one cycle in pin 9.

Use only the PWM pins in Arduino 3,9,6 etc.

Now you can change the PWM frequency...

*I just put a led in the female socket in for easiness + terminal in 9 and - terminal in 8 to go to ground that's why I did put pin 8 to low.*

  [1]: https://github.com/terryjmyers/PWM


body:
Would like to ask for assistance with the code below.  It's the Adafruit Bluefruit Atmega32U LE module with Adafruit's Arduino IDE example "heart-rate monitor" sketch.   The code uses the hardware SPI setup with Adafruit's BLE code between the Atmega32U and the nRF51822 using AT Commands built into a BLE stack by Adafruit.

It works at the same speed in real-time on the PC's Arduino IDE USB serial terminal and also on the Android phone's nRF Connect app or any other BLE app that can read "notifications".

**Problem:  If remove the module from the PC's USB (thus the serial stopped and only using BLE) the update rate on the BLE Android app slows down to 5 second intervals compared to the near real-time speed while connected to USB.**   I tried many things, including commenting out the Serial commands  in the void loop() and also the delay(), but no change.  As if the BLE stack by Adafruit would have a update period limitation.  According to Adafruit, they do not give access to to their BLE stack.  But I could possibly load another BLE stack on this nRF51822 chip.   Also I do have the Adafruit Sniffer with Wireshark, but not an expert using it.

How can I get less than 1 second update rates?  The data stream is not in 1 second intervals. Maybe 10-15 seconds between readings, but I need it updated within 1 second of being read from the sensor.

https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le?view=all

```c++
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

// Create the bluefruit object, either software serial...uncomment these lines
/*
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

/* The service information */

int32_t hrmServiceId;
int32_t hrmMeasureCharId;
int32_t hrmLocationCharId;
/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  while (!Serial); // required for Flora & Micro
  delay(500);

  boolean success;

  Serial.begin(115200);
  Serial.println(F("Adafruit Bluefruit Heart Rate Monitor (HRM) Example"));
  Serial.println(F("---------------------------------------------------"));

  randomSeed(micros());

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  /* Perform a factory reset to make sure everything is in a known state */
  Serial.println(F("Performing a factory reset: "));
  if (! ble.factoryReset() ){
       error(F("Couldn't factory reset"));
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  // this line is particularly required for Flora, but is a good idea
  // anyways for the super long lines ahead!
  // ble.setInterCharWriteDelay(5); // 5 ms

  /* Change the device name to make it easier to find */
  Serial.println(F("Setting device name to 'Bluefruit HRM': "));

  if (! ble.sendCommandCheckOK(F("AT+GAPDEVNAME=Bluefruit HRM")) ) {
    error(F("Could not set device name?"));
  }

  /* Add the Heart Rate Service definition */
  /* Service ID should be 1 */
  Serial.println(F("Adding the Heart Rate Service definition (UUID = 0x180D): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDSERVICE=UUID=0x180D"), &hrmServiceId);
  if (! success) {
    error(F("Could not add HRM service"));
  }

  /* Add the Heart Rate Measurement characteristic */
  /* Chars ID for Measurement should be 1 */
  Serial.println(F("Adding the Heart Rate Measurement characteristic (UUID = 0x2A37): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=3, VALUE=00-40"), &hrmMeasureCharId);
    if (! success) {
    error(F("Could not add HRM characteristic"));
  }

  /* Add the Body Sensor Location characteristic */
  /* Chars ID for Body should be 2 */
  Serial.println(F("Adding the Body Sensor Location characteristic (UUID = 0x2A38): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A38, PROPERTIES=0x02, MIN_LEN=1, VALUE=3"), &hrmLocationCharId);
    if (! success) {
    error(F("Could not add BSL characteristic"));
  }

  /* Add the Heart Rate Service to the advertising data (needed for Nordic apps to detect the service) */
  Serial.print(F("Adding Heart Rate Service UUID to the advertising payload: "));
  ble.sendCommandCheckOK( F("AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18") );

  /* Reset the device for the new service setting changes to take effect */
  Serial.print(F("Performing a SW reset (service changes require a reset): "));
  ble.reset();

  Serial.println();
}

/** Send randomized heart rate data continuously **/
void loop(void)
{
  int heart_rate = random(50, 100);

  //Serial.print(F("Updating HRM value to "));
  //Serial.print(heart_rate);
 // Serial.println(F(" BPM"));

  /* Command is sent when \n (\r) or println is called */
  /* AT+GATTCHAR=CharacteristicID,value */
  ble.print( F("AT+GATTCHAR=") );
  ble.print( hrmMeasureCharId );
  ble.print( F(",00-") );
  ble.println(heart_rate, HEX);

  /* Check if command executed OK */
 // if ( !ble.waitForOK() )
 // {
   // Serial.println(F("Failed to get response!"));
  //}

  /* Delay before next measurement update */
 // delay(1000);
}

/////////////////AND BELOW IS THE BluefruitConfig.h TAB in ARDUINO IDE --This is a separate file under a new tab in the IDE////////////////..

    // COMMON SETTINGS
// ----------------------------------------------------------------------------------------------
// These settings are used in both SW UART, HW UART and SPI mode
// ----------------------------------------------------------------------------------------------
#define BUFSIZE                        128   // Size of the read buffer for incoming data
#define VERBOSE_MODE                   true  // If set to 'true' enables debug output

// SOFTWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins that will be used for 'SW' serial.
// You should use this option if you are connecting the UART Friend to an UNO
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SWUART_RXD_PIN       9    // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN       10   // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN         11   // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN         8    // Optional, set to -1 if unused

// HARDWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the HW serial port you are using. Uncomment
// this line if you are connecting the BLE to Leonardo/Micro or Flora
// ----------------------------------------------------------------------------------------------
#ifdef Serial1    // this makes it not complain on compilation if there's no Serial1
  #define BLUEFRUIT_HWSERIAL_NAME      Serial1
#endif

// SHARED UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following sets the optional Mode pin, its recommended but not required
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_UART_MODE_PIN        12    // Set to -1 if unused

// SHARED SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for HW and SW SPI communication.
// SCK, MISO and MOSI should be connected to the HW SPI pins on the Uno when
// using HW SPI.  This should be used with nRF51822 based Bluefruit LE modules
// that use SPI (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_CS               8
#define BLUEFRUIT_SPI_IRQ              7
#define BLUEFRUIT_SPI_RST              4    // Optional but recommended, set to -1 if unused

// SOFTWARE SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for SW SPI communication.
// This should be used with nRF51822 based Bluefruit LE modules that use SPI
// (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_SCK              13
#define BLUEFRUIT_SPI_MISO             12
#define BLUEFRUIT_SPI_MOSI             11
```

title: Arduino Atmega32U with nRF51 BLE by Adafruit limited to 5 second update rate?

Answers: 1

body:
The "verbose" error check mode for debug in the "BluefruitConfig.h" tab slowed down the flow of BLE data. I changed it from "true" to "false" to turn it off.

```c++
#define VERBOSE_MODE true  // If set to 'true' enables debug output
```


body:
i'm trying to use a E18-D80NK sensor with arduino but the output is always at 1, i really don't understand why
This is my code :

    int irPin2 = 8;// define pint 2 for sensor

    void setup() {
      Serial.begin(9600);// setup Serial Monitor to display information
      pinMode(irPin2, INPUT);// define pin as Input  sensor
    }

    void loop() {
      int out = digitalRead(irPin2);// read the sensor

        Serial.println(out);

      delay(250);
     // E18-D80NK Obstacle Sensor
    }

and circuit: [![E18-D80NK Obstacle Sensor][1]][1]

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

title: I'm trying to use a E18-D80NK but the output is always 1

Answers: 2

body:
There are a few possibilities for what is wrong:

1) The wiring may be wrong: the datasheet you reference lists two types (red,black,yellow) and (blue,brown,black) but in your pic it looks like you have (blue, grey, black).  I wouldn't assume the color coding of the sensor wires are correct.

2) The "pull-up" resister mentioned in the data sheet referenced (and included schematic) is not functioning as a pull-up resistor.  I would get rid of the resistor and plug the digital-output wire of the sensor directly into the arduino input.   Also, try configuring the input with pull-up like:  pinMode(irPin2, INPUT_PULLUP);
The Arduino inputs are high impedance and typically do not need a series resistor.

body: Your sensor pull low and not high, normally they pull high , I did however buy a few that is permanently on and then switch of ( pull low) when object in range.


body:
I am working on project where I have to do  AES encryption of plain text  received through normal UART port of ESP8266 create a cipher text and sending it to LoRa module ([EByte E32 868T30D][1]) through Software Serial port and recieve on the other end decrypt and get the plain text back. the problem I am facing is when I try to sendlarge array of bytes more than 300 or so I am getting garbled values on the other end. I am well aware of the 512 byte limit in LoRa module and so I tried using Hardware flow control by AUX pin that is available. Eventhough I am not successfull in implementing a working code. I have a grey area in how to implement such a hardware flow control in ESP8266. since its my first time I am seeking for help from experts in this field. My project requires me to send about 10kB of data over LoRa with minimum possible delay between each 512 byte transmission
[![enter image description here][2]][2]
```
/*===========================================================================================================================================================================
   ---------------------------------------------------- ESP8266 EByte 32 Lora Encryption Test ----------------------------------------------------
   Author: Mister.B
   Date: 10 May 2020
   Objective: To test AES256 ECB Encryption on LoRa Modules
   Third-Party ibraries used:
   1) aes256 - https://github.com/qistoph/ArduinoAES256
  ===========================================================================================================================================================================*/
#include "aes256.h"
#include <SoftwareSerial.h>

//EByte E32 Pin Configuration

#define M0 D5
#define M1 D6
#define AUX D2 // AUX HIGH means BUSY LOW means READY
#define RX_Pin D3
#define TX_Pin D4

//BaudRate Selection

#define E32_BAUD 9600
#define SERIAL_BAUD 9600

//AES Parameters
#define BUFFER_SIZE 2048 //2kB buffer to store the values
#define BLOCK_SIZE 16

//Timeout selection
#define UART_SERIAL_TIMEOUT 5000
#define E32_SERIAL_TIMEOUT 5000

//Debug Selection
#define DEBUG_CONSOLE true

//Class Instances
aes256_context ctxt;
SoftwareSerial E32(RX_Pin, TX_Pin);
//#define E32 Serial
//======Global Variables Declaration======
uint8_t key[] = {
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
uint8_t data_buffer[BUFFER_SIZE] = {};
int i = 0, in_count = 0, out_count = 0;
unsigned long last_packet_arrival = 0;

//MACROS
#define ARRAY_SIZE(arr) ((sizeof(arr))/(sizeof(arr[0])))
#if DEBUG_CONSOLE == true
#define DUMP(str,i,buf,sz){Serial.println(str);\
    for(i=0;i<sz;++i){if(buf[i]<0x10)Serial.print('0');Serial.print(char(buf[i]),HEX);}\
    Serial.println();}
#else
#define DUMP(str,i,buf,sz)
#endif

void setup()
{
  Serial.begin(SERIAL_BAUD);
  E32.begin(E32_BAUD);
  pinMode(M0, OUTPUT);
  pinMode(M1, OUTPUT);
  pinMode(AUX, INPUT);
  /*
     Setting Ebyte 32 in Normal Mode (M0=LOW and M1=LOW)
  */
  digitalWrite(M0, LOW);
  digitalWrite(M1, LOW);
  delay(1000);
  DUMP("\nKey:", i, key, sizeof(key));
  aes256_init(&ctxt, key); // Send key for key scheduling
}
void loop()
{
  int frame_count = 0;
  out_count = 0;
  in_count = 0;
  last_packet_arrival = millis();
  /*
     RECEIVE DATA FROM EBYTE E32 LoRa
  */
  if (E32.available()) {
    out_count = 0;
    last_packet_arrival = millis();
    frame_count = (int)E32.read();
    while ((millis() - last_packet_arrival < E32_SERIAL_TIMEOUT) or (frame_count > out_count)) {
      out_count += E32.readBytes(data_buffer+out_count,58);
      if (out_count >= BUFFER_SIZE)Serial.printf("\n Input Buffer[%d] full :(", BUFFER_SIZE); break; //Prevent buffer overflow
    }
    Serial.printf("\nFc:%d", frame_count);
    frame_count = 0;
    Serial.printf("\nReceiveCount:%d\n", out_count);
    DUMP("\nRecived Data:", i, data_buffer, out_count);
    for (int n = 0; n <= (out_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_decrypt_ecb(&ctxt, data_buffer + n);
    DUMP("\nDecrypted Data:", i, data_buffer, out_count);
    for (int i = 0; i < out_count; i++)Serial.print((char)data_buffer[i]); yield();
    memset(data_buffer, 0x00, BUFFER_SIZE);
    out_count = 0;
  }
  /*
     RECEIVE DATA FROM UART Port
  */
  if (Serial.available()) {
    in_count=0;
    last_packet_arrival = millis();
    while ((millis() - last_packet_arrival) < UART_SERIAL_TIMEOUT) {
      in_count += Serial.readBytes(data_buffer + in_count, 58);
      if (in_count >= BUFFER_SIZE)Serial.printf("\n Output Buffer[%d] full :(", BUFFER_SIZE); break; // Prevent buffer overflow
    }
    /*
       Padding with zeros
    */
    if (in_count < 58) { // if Serial data entered is smaller than 58
      for (int i = in_count; i < 58; i++)data_buffer[i] = 0x00;
    }
    if (in_count > 58 && (in_count % 58 != 0)) { // if the Serial data is not multiple of 58 do padding with 0x00
      for (int i = in_count; i < in_count + (in_count % 58); i++)data_buffer[i] = 0x00;
    }
    Serial.printf("\nSendCount:%d", in_count);
    DUMP("\nData Entered:", i, data_buffer, in_count);
    //for (int n = 0; n <= (in_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_encrypt_ecb(&ctxt, data_buffer + n); // Encrypting whole data by 16 byte blocks
    //DUMP("\nEncrypted Data:", i, data_buffer, in_count);
    /*
       Add the length number of 512 byte in data frame
    */
    //uint8_t data_frame[BUFFER_SIZE + (BUFFER_SIZE % 58)] = {};
    //for (int i = 0; i <= BUFFER_SIZE; i++) data_frame[i + 1] = data_buffer[i];
    //data_frame[0] = (in_count / 58) + 1;
    //DUMP("\nSent Data:", i, data_frame, in_count + 1);
    /*
       Prevent buffer overflow in LoRa module using Hardware Flow control
    */
    uint8_t buff[58] = {};
//    for (int i = 0; i < (in_count / 464)+1 ; i++) //divide the data buffer into 464 byte frames
//    {
//      for (int j = 464 * i; j < (464 * i) + 464; j += 58) { //divide the 464 byte frames into 58 byte frames
        byte* f_count=(in_count<58) ? in_count : (in_count / 58) + 1;
        E32.write(f_count,1);
        for (int j = 0 ; j < in_count ; j+=58){
        memcpy(buff, data_buffer + j, 58);
        aes256_encrypt_ecb(&ctxt,buff);
        DUMP("\nEncrypted Data:", i, buff, 58);
        while (digitalRead(AUX) == HIGH) yield(); // wait for the pin to get LOW
        if (digitalRead(AUX) == LOW) { //if the module is READY send
          E32.write(buff, 58);
//          E32.flush();
        }
      }
//    }
    in_count = 0;
    memset(data_buffer, 0x00, BUFFER_SIZE);
    //memset(data_frame, 0x00, ARRAY_SIZE(data_frame));
  }
}
```

  [1]: http://www.ebyte.com/en/product-view-news.aspx?id=189
  [2]: https://i.stack.imgur.com/XNQyB.png

title: how to implement AES in LoRa Module with Hardware Flow control using ESP8266?

Answers: 0


body:
I am writing a wav file to an SD card on a ESP32 and that requires that every time I append data to the the end of the file I modify the header to set the right size in some fields.

I cannot find how to replace a value inside a file, I tried to write the new values with the seek function but unless I'm missing something looks like this deletes everything after the new value added.

I do not want to create a new file and to delete the old one as I will storing potentially large wav files and looks like wasting resources.

Is there a way to overwrite one value inside a file. I'm using **SDlib** but I'm open to others too.

Here the code I use to create the file and to update it:

    #include "WavFileWriter.h"

    void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
    {
      byte headerBuffer[44];
      wavFileHeader->getHeaderData(headerBuffer);
      File file = SD.open(filename, FILE_WRITE);
      file.write(headerBuffer, 44);
      file.close();
    }

    void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
    {
      File file = SD.open(filename, FILE_WRITE);
      file.write(data, dataLength);

      byte headerBuffer[44];
      wavFileHeader->setFileSize(file.size());
      wavFileHeader->getHeaderData(headerBuffer);

      file.seek(0);
      file.write(headerBuffer, 44);
      file.close();
    }

After calling appendData I end up with a file with just the header size (with the right header for a file with data but the data is gone).

title: How to modify values inside a file

Answers: 2

body: SD.seek() is the API you're looking for.  It allow you to position the read/write pointer within a file.   In standard C++ the fseek() API is used.

body:
The `FILE_WRITE` in SD library is 'append' (for historical reasons)

    #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

so use

     File file = SD.open(filename, O_WRITE);