# Question
Title: Arduino IDE for ESP32: Compilation Error: Exist status 255
**Problem:**

I have a ESP32 and I've been trying to flash it with the Arduino IDE, however it's been giving me Python error messages :/ when I'm trying C/C++ code to flash the Arduino.

**Question:**

How can I setup the board below so I can flashi it with C/C++ from the Arduino IDE?

**Error Message:**

```
  [6909] Error loading Python lib '/var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libpython3.8.dylib': dlopen: dlopen(/var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libpython3.8.dylib, 10): Symbol not found: ____chkstk_darwin
  Referenced from: /var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libintl.8.dylib (which was built for Mac OS X 11.0)
  Expected in: /usr/lib/libSystem.B.dylib
  in /var/folders/wm/_tds7_0s6_j9587rbm54nfv00000gn/T/_MEIli4AzL/libintl.8.dylib

  exit status 255

  Compilation error: exit status 255

```

**ESP32:**

**References Used/Due Diligence:**

**Version Numbers:**

* MAC OS Version: macOS High Sierra Version 10.13.6
* Arduino Version: Version 2.0.4-nightly-20230119 CLI Version: 0.29.0

# Answer
I don't have Mac but I am working on Linux and I also had issues with Arduino IDE v2 (in the past). Because of this I'm still using IDE v1 with no issues and that's my suggestion: try older version of the IDE on your mac, you can still download it. If it won't work you can turn to PlatformIO or VSCode IDEs.
> 1 votes

---
Tags: arduino-ide, esp32
---


# Question
Title: why the p-mos is acting as a constant switch when the source is connect to any port in the circuit iam not able find the solution ?i
if my circuit has mistake please refer me the proper image.

```
#define pwm 6
void setup() {
  // initialize serial communication at 9600 bits per second:
  pinMode(6,OUTPUT);
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  //Serial.println(sensorValue);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  //Serial.println(voltage);
  float vol1=voltage*11;
  Serial.print("convertd voltageg ");
  Serial.println(vol1);
  int s=0;
  if (vol1>24){
  float duty=(24)/(vol1);
  Serial.print("Duty cycle ");
  duty=duty*100;
  Serial.println(duty);
   s=map(duty,0,100,0,255);
  Serial.print("maped values");
  Serial.println(s);
    analogWrite(6,s);}
  else if(vol1>18 && vol1<25){
    s=255;
    analogWrite(6,s);
    Serial.println(s);
  }
  //Serial.println(x);
}

```

# Answer
> -1 votes
You have to be careful with such a circuit because you risk applying 12 volts to an arduino pin. To switch that P channel mosfet off, 12 volts has to be applied to the gate. Search for "mosfet high side switch". Usual solutions use both a P channel mosfet and either an npn transistor or an N channel mosfet. A simpler alternative is to switch the motor using an N channel mosfet (low side switch). See https://gammon.com.au/motors for a full description.

Note: that circuit you have used appears to have come from here https://circuitjournal.com/how-to-use-a-p-channel-mosfet-with-an-arduino and is particularly risky because it relies on the grounds between the 5 volt and 12 volt circuits not being interconnected. It may work as shown, however not recommended for the reasons stated above, but your simulation does not appear to have the 12 volt power supply sharing a common positive rail with the 5 volt supply.

# Answer
> -1 votes
The Arduino when the output is High is ~5V referencing. The MOSFET gate sees it as -7V referencing the source. It is always best to use the source as the reference point for a MOSFET. Look at the data sheet and it shows it is doing what it is doing. The gate needs to about 0V referencing the source to be off. The exact value is dependent on the MOSFET used.You will need to add a transistor or mosfet to drive the P-Channel MOSFET with the Arduino. You could also use a opto isolator to switch the mosfet.

---
Tags: arduino-uno, pwm, mosfet
---


# Question
Title: strange behaviour with a single 7seg display
I'd like to display a sentence character by character on a single seven-segment display. What happens is that if my sentence is longer than 48 characters the central segment doesn't light up.

It works properly if I take out a letter from my string.

I have an Elegoo Uno R3, and am working on Windows, on the last version (2.0.3) of the Arduino IDE.

Is there a way to solve this issue?

Here's my code:

```
# include "SevSeg.h"

SevSeg  sevseg;
char    *str = "Per colpa di qualcuno non si fa credito a nessuno";
int     len = 50;

void setup(){
    byte numDigits = 1;
    byte digitPins[] = {};
    byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8, 9};
    bool resistorsOnSegments = true;

    byte hardwareConfig = COMMON_CATHODE;
    sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
    sevseg.setBrightness(90);
}

void loop(){
  int i = 0;

  while (i < len)
  {
    sevseg.setChars(&(str[i]));
    delay(1000);
    sevseg.refreshDisplay();
    ++i;
  }
}

```

Thanx in advance,

Fab

# Answer
> -1 votes
It looks like setChars is expecting a string, not a single character.

So I would be doing something like:

```
  while (int i = 0; i < len; i++)
  {
    char buf [2];
    buf [0] = str[i];
    buf [1] = 0;  // null terminator
    sevseg.setChars(buf);
    sevseg.refreshDisplay();
    delay(1000);
  }

```

See: https://github.com/DeanIsMe/SevSeg/blob/master/SevSeg.cpp

---
Tags: arduino-uno, display
---


title: ATTiny88 missing pulses - maybe

text:
# Question
Title: ATTiny88 missing pulses - maybe
I have been given to understand the ATTiny88 is very similar to the Arduino Uno / ATMega328 MCU. There does not seem to be a tag for the ATTiny88, so that is why I chose the tags I did. I do not have a high enough reputation to create a tag, yet. Thanks to the generous help of timemage, Edgar Bonet, and others, my MCU board is now responding, albeit very erratically, to pulses on pins 12 and 13, designated Phase\_B and Phase\_A, respectively, in the code below. I have not yet entirely ruled out a hardware issue (I will do so), but a software issue is still likely. I don't quite know what. The MCU is registering pulses, but it very often misses large numbers of turns in either direction. What's more, it frequently reports the wrong direction, strongly favoring a CW rotation, but sometimes reporting a CCW rotation when the knob is turned CW. It is definitely not an overflow issue, as the anomalous effects are seen in abundance when in the mid range of the variables.

```
#include <Arduino.h>
#include <TM1637Display.h>
#include "PinChangeInterrupt.h"

volatile uint8_t counter = 0;
volatile bool Update = false;
volatile int currentStatePhase_B;
volatile int lastStatePhase_B;
volatile int pulses = 0;

// Shutdown Output
#define SW 11

// Rotary Encoder Inputs
#define Phase_A 13
#define Phase_B 12
// TM1637 I/O ports
#define DIO 3
#define CLK 4
TM1637Display display(CLK, DIO);

void setup() {

  // Set encoder pins as inputs
  pinMode(Phase_A,INPUT);
  pinMode(Phase_B,INPUT);
  pinMode(SW, OUTPUT);

    // Read the initial state of Phase_B
    lastStatePhase_B = digitalRead(Phase_B);

    // Call updateEncoder() when any high/low changed seen
    // on interrupt 0 (pin 2), or interrupt 1 (pin 3)
    attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, RISING);
    attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, RISING);

  display.setBrightness(0x0f);
  display.clear();
  display.showNumberDec(0, false);
}

void loop() {
    if (Update){
        // Show decimal numbers with/without leading zeros
    display.showNumberDec(pulses, false);
    delay(1000);
    display.showNumberDec(counter, false);
        Update = false;
    }
}

void updateEncoder(){
    // Read the current state of Phase_B
    currentStatePhase_B = digitalRead(Phase_B);

    // If last and current state of Phase_B are different, then pulse occurred
    // React to only 1 state change to avoid double count
    if (currentStatePhase_B != lastStatePhase_B  && currentStatePhase_B == 1){
        // If the Phase_A state is different than the Phase_B state then
        // the encoder is rotating CCW so decrement
        if (digitalRead(Phase_A) != currentStatePhase_B) {
            counter --;
        } else {
            // Encoder is rotating CW so increment
            counter ++;
        }
    }
    if (counter > 1023){
      counter = 1023;
    }
    if (counter < 0){
      counter = 0;
    }
    pulses ++;
    // Remember last Phase_B state
    lastStatePhase_B = currentStatePhase_B;
    Update = true;
}

```

# Answer
> 0 votes
OK, I have an answer. The MCU is still missing a lot of pulses, but I am fairly certain this is a hardware issue, or at least mostly so. I found some code by Ralph S. Bacon and Marko Pinteric. The YouTube video can be found here

As should always be the case, the ISR is brief. Here it is a single line that merely sets a Boolean variable true. In the loop section, the code repeatedly checks to see if the interrupt has occurred. The checkRotaryEncoder function then verifies the pin values to make sure the encoder is in a valid state (not bouncing). If so, then the counter value is updated with the result.

```
#include <Arduino.h>
#include <TM1637Display.h>
#include "PinChangeInterrupt.h"

uint8_t lrmem = 3;
int lrsum = 0;
int num = 0;
unsigned int counter = 0;

// Shutdown Output
#define SW 11
// Rotary Encoder Inputs
#define Phase_A 12
#define Phase_B 13
// TM1637 Display I/O
#define DIO 3
#define CLK 4
TM1637Display display(CLK, DIO);

// A turn counter for the rotary encoder (negative = anti-clockwise)
int rotationCounter = 200;
// Flag from interrupt routine (moved=true)
volatile bool rotaryEncoder = false;

// Rotary encoder has moved (interrupt tells us) but what happened?
// See https://www.pinteric.com/rotary.html
int8_t checkRotaryEncoder()
{
    // Reset the flag that brought us here (from ISR)
    rotaryEncoder = false;

    static uint8_t lrmem = 3;
    static int lrsum = 0;
    static int8_t TRANS[] = {0, -1, 1, 14, 1, 0, 14, -1, -1, 14, 0, 1, 14, 1, -1, 0};

    // Read BOTH pin states to deterimine validity of rotation (ie not just switch bounce)
    int8_t l = digitalRead(Phase_A);
    int8_t r = digitalRead(Phase_B);

    // Move previous value 2 bits to the left and add in our new values
    lrmem = ((lrmem & 0x03) << 2) + 2 * l + r;
    // Convert the bit pattern to a movement indicator (14 = impossible, ie switch bounce)
    lrsum += TRANS[lrmem];
    /* encoder not in the neutral (detent) state */
    if (lrsum % 4 != 0)
    {
        return 0;
    }
    /* encoder in the neutral state - clockwise rotation*/
    if (lrsum == 4)
    {
        lrsum = 0;
        return 1;
    }
    /* encoder in the neutral state - anti-clockwise rotation*/
    if (lrsum == -4)
    {
        lrsum = 0;
        return -1;
    }
    // An impossible rotation has been detected - ignore the movement
    lrsum = 0;
    return 0;
}

void setup() {
  // Set encoder pins as inputs
  pinMode(Phase_A,INPUT);
  pinMode(Phase_B,INPUT);
  // Set Power Switch as output
  pinMode(SW, OUTPUT);
  // Initialize display
  display.setBrightness(0x0f);
  display.clear();
  display.showNumberDec(0, false);
  // Set up interrupt pins and vector
  attachPCINT(digitalPinToPCINT(Phase_A), rotary, CHANGE);
  attachPCINT(digitalPinToPCINT(Phase_B), rotary, CHANGE);
}

void loop()
{
  // Has rotary encoder moved?
  if (rotaryEncoder) {
    // Get the movement (if valid)
    int8_t rotationValue = checkRotaryEncoder();
    // If valid movement, do something
    if (rotationValue != 0) {
      counter += rotationValue;
      if (counter > 1023){
        counter = 1023;
      }
      else if (counter < 0){
        counter = 0;
      }
      display.showNumberDec(counter, false);
    }
  }
}

// Interrupt routine just sets a flag when rotation is detected
void rotary()
{
    rotaryEncoder = true;
}

```

Any comments are welcom. In addition, Ralph Bacon used the IRAM\_ATTR directive to create the rotary() ISR. My understanding of this directive is it is not necessary in most cases. On the other hand, presumably the code will execute faster if it is pushed into flash RAM. I could not make this work. The compiler complains, "expected initializer before 'rotary'" Is this by chance because the ATTiny88 does not have flash RAM? If not, then what?

---
Tags: arduino-uno, interrupt, atmega328, attiny, rotary-encoder
---


# Question
Title: ESP32 HTTP Request handles Go webserver response, but fails on node JS servers
I've set up an esp32 board (wemos d1 r32) to send a request to a server hosted on my local network. If I set up a very basic go server, the board handles the response fine (200 with the appropriate body content). Once I switch to a Node JS Server, it only responds with a `400` status code. Weirdest of all none of the `console.log` calls in the route handlers get called, which indicates that it quits before it even gets to the express server. I've tested that the server returns the body & status code I want using postman, all looks good.

I've tried different frameworks (Koa) to see if this is related to Express, but it doesn't work with that either. I assume its something to do with NodeJS?

**Express server**

```
import express from "express";

const app = express();
app.use(express.json());
app.post("/", (req, res) => {
  console.log(req.body);
  req.statusCode = 200;
  res.send("200");
});

app.get("/hello", (req, res) => {
  res.setTimeout(50000);
  console.log(req.body);
  res.setHeader("Location", "123");
  res.setHeader("Server", "123");
  req.statusCode = 200;
  res.send("200");
});

app.listen(8090, () => {
  console.log(`Example app listening on port ${8090}`);
});

```

**Go server**

```
package main

import (
    "fmt"
    "net/http"
)

func hello(w http.ResponseWriter, req *http.Request) {
    for name, headers := range w.Header() {
        for _, h := range headers {
            fmt.Fprintf(w, "%v: %v\n", name, h)
        }
    }
    fmt.Fprintf(w, "hello\n")
}

func headers(w http.ResponseWriter, req *http.Request) {

    for name, headers := range req.Header {
        for _, h := range headers {
            fmt.Fprintf(w, "%v: %v\n", name, h)
        }
    }
}

func main() {
    fmt.Println("?")

    http.HandleFunc("/hello", hello)
    http.HandleFunc("/headers", headers)

    http.ListenAndServe(":8090", nil)
}

```

**Arduino script**

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

// #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"

const char* ssid = "xxx";
const char* password = "xxx";

String webserver = "http://192.168.0.19:8090/hello";

String qrCode;

void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info){
  Serial.println("Connected to AP successfully!");
}

void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info){
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info){

  WiFi.disconnect(true);
  delay(1000);
  WiFi.mode(WIFI_STA);
  delay(1000);
  Serial.println("Disconnected from WiFi access point");
  Serial.print("WiFi lost connection. Reason: ");
  Serial.println(info.disconnected.reason);
  Serial.println("Trying to Reconnect");
  WiFi.begin(ssid, password);
  delay(5000);
}

void setup() {
  esp_log_level_set("*", ESP_LOG_VERBOSE);
  Serial.begin(9600);
  Serial2.begin(9600);
  Serial.println("Hello, ESP32!");
  Serial.println(WiFi.getMode());
  Serial.println(WiFi.macAddress());

  WiFi.onEvent(WiFiStationConnected, WiFiEvent_t::SYSTEM_EVENT_STA_CONNECTED);
  WiFi.onEvent(WiFiGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
  WiFi.onEvent(WiFiStationDisconnected, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);

  WiFi.begin(ssid, password);
}

int cnt = 0;

void loop() {
  while (Serial2.available()) {
    int  ch = Serial2.read();
    char character = ch;
    Serial.print(ch);

    // end char
    if(character == 13){
      Serial.print("\n");
      Serial.println(qrCode);
      Serial.println(cnt);
      qrCode = "";
      cnt = 0;
      send(qrCode);
    } else {
      cnt = ch + cnt;
      qrCode = qrCode + character;
    }
  }
}

void tryWifi() {
  WiFi.begin(ssid, password);
  int status = WiFi.status();
  while (status == 6 || status == 4 || status == 5 || status == 1) {
    Serial.print("Failed to connect:");
    Serial.print(status);
    Serial.print("\n");
    delay(1500);
    WiFi.begin(ssid, password);
  }
}

void send(String json) {
  HTTPClient http;

  if(http.begin(webserver)){

      int httpCode = http.GET();
      http.addHeader("Content-Type", "application/json");
      http.addHeader("Host", "something");
      // client.print("Content-Length: ");
      delay(1500);

      Serial.println(httpCode);
      Serial.println(http.getString());
      if (httpCode > 0) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
        if(httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = http.getString();
          if (payload != "false"){
            Serial.println(payload);
            delay(1500);
          } else {
          Serial.println("Bad Playload");
          }
        } else {

        }
      } else {
      Serial.println("Error sending to HTTP");
      }
      http.end();
    } else {
      Serial.println("?");
    }
}

```

# Answer
> 3 votes
Your Arduino code reads like this:

```
  int httpCode = http.GET();
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Host", "something");
  // client.print("Content-Length: ");
  delay(1500);

  Serial.println(httpCode);
  Serial.println(http.getString());
  if (httpCode > 0) {

```

The call `http.GET()` actually performs the HTTP request. You're adding headers *after* you perform the request. They need to be added before it. So your code should read:

```
  // http.addHeader("Content-Type", "application/json");
  int httpCode = http.GET();

  // delay(1500);   -- there's no need to call delay() here

  Serial.println(httpCode);
  Serial.println(http.getString());
  if (httpCode > 0) {

```

HTTP status code 400 means "bad request". Some web servers will return this code if headers that they expect to see are missing or have non-sensical values. The Go and Javascript web servers are different implementations and may behave differently with malformed requests.

I've removed "Host" header as `HTTPClient` does this for you. And there's no need for the `delay()` call after calling `http.GET()`.

**Edit**: I also commented out the "Content-Type" header as it makes no sense on a GET request, thanks to @EdgarBonet for mentioning that. I'm leaving it there as a comment to make it clear that that any headers should be added *before* the request is performed.

# Answer
> 1 votes
I've figured out after an unreasonable amount of time that the request fails with a 400 as it doesn't have a slash at the end of the URL (`http://192.168.1.208:8090` -\> `http://192.168.1.208:8090/`). This must be something specific to NodeJS, as it works ok on a go server.

---
Tags: esp32, http
---


title: ESPAsyncWebServer code not compiling

text:
# Question
Title: ESPAsyncWebServer code not compiling
# Error messages

```
    Arduino: 1.8.14 Hourly Build 2020/12/15 11:33 (Windows 10), Board: "Generic ESP8266 Module, 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, dtr (aka nodemcu), 26 MHz, 40MHz, DOUT (compatible), 1MB (FS:64KB OTA:~470KB), 2, nonos-sdk 2.2.1+100 (190703), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:62:18: error: 'HTTP_GET' conflicts with a previous declaration

       62 |   HTTP_GET     = 0b00000001,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:29: note: previous declaration 'HTTPMethod HTTP_GET'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                             ^~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:63:18: error: 'HTTP_POST' conflicts with a previous declaration

       63 |   HTTP_POST    = 0b00000010,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:50: note: previous declaration 'HTTPMethod HTTP_POST'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                                  ^~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:64:18: error: 'HTTP_DELETE' conflicts with a previous declaration

       64 |   HTTP_DELETE  = 0b00000100,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:83: note: previous declaration 'HTTPMethod HTTP_DELETE'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                                                                ^~~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:65:18: error: 'HTTP_PUT' conflicts with a previous declaration

       65 |   HTTP_PUT     = 0b00001000,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:61: note: previous declaration 'HTTPMethod HTTP_PUT'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                                             ^~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:66:18: error: 'HTTP_PATCH' conflicts with a previous declaration

       66 |   HTTP_PATCH   = 0b00010000,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:71: note: previous declaration 'HTTPMethod HTTP_PATCH'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                                                       ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:67:18: error: 'HTTP_HEAD' conflicts with a previous declaration

       67 |   HTTP_HEAD    = 0b00100000,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:39: note: previous declaration 'HTTPMethod HTTP_HEAD'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                       ^~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:68:18: error: 'HTTP_OPTIONS' conflicts with a previous declaration

       68 |   HTTP_OPTIONS = 0b01000000,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:96: note: previous declaration 'HTTPMethod HTTP_OPTIONS'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                                                                                ^~~~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:4:

    C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:69:18: error: 'HTTP_ANY' conflicts with a previous declaration

       69 |   HTTP_ANY     = 0b01111111,

          |                  ^~~~~~~~~~

    In file included from C:\Users\JUNAID\Documents\Arduino\iot_project_4\iot_project_4.ino:2:

    C:\Users\JUNAID\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:19: note: previous declaration 'HTTPMethod HTTP_ANY'

       47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };

          |                   ^~~~~~~~

    Multiple libraries were found for "ESPAsyncTCP.h"

     Used: C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncTCP

     Not used: C:\Users\JUNAID\Documents\Arduino\libraries\ESPAsyncTCP-master

    exit status 1

    Error compiling for board Generic ESP8266 Module.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

```

# Code

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
int Wifiled = 15;

ESP8266WebServer esp(80);

String HTML = "";

String FORM = "testing the second website";

void setup()
{
       HTML +="<html>";
       HTML +=  "<head>";
       HTML +=    "<title>MY SMART HOME</title>";
       HTML +="<style>";
       HTML +="body {background-color:#92e8e2;}";
       HTML +="#wrapper {background-color:#ebf5f4;width:93%;min-height:700px;margin:auto;barder:1px solid #ccc;padding:10px;}";
       HTML +="</style>";

       HTML +=  "</head>";
       HTML +=  "<body>";
       HTML +=  "<div id='wrapper'>";
       HTML +=    "<h3>WELCOME TO MY SMART SENSOR DATA</h3>";
       HTML +=    "<h2>PH SENSOR DATA   </h2>";
       HTML +=    "Serial.monitor";
       HTML +=    "<h2>EC SENSOR DATA </h2>";
       HTML +=  "</div >";
       HTML +=  "</body>";
       HTML +="</html>";
    pinMode(Wifiled,OUTPUT);
    delay(1000);
    Serial.begin(115200);
    WiFi.begin("LAPTOP","123456789");
    while(WiFi.status() != WL_CONNECTED)
    {
          Serial.print(".");
          digitalWrite(Wifiled,HIGH);
          delay(250);
          digitalWrite(Wifiled,LOW);
          delay(250);
    }
        digitalWrite(Wifiled,HIGH);
        Serial.println("wifi connected");
        Serial.println(WiFi.localIP());

        esp.on("/",sendHtml);
        esp.on("/process",sendform);
        esp.begin();
}
void sendform()
{
  esp.send(200,"text/html;",FORM);
}

void sendHtml()
{
  esp.send(200,"text/html;",HTML);

}

void loop()
{
   esp.handleClient();
   delay(200);
   char buffer[20]="";
   if(Serial.available()>0){
  //  char data=Serial.read();
   Serial.readBytesUntil('\n',buffer,20);
   Serial.println(buffer);
   }
}

```

# Answer
You've included \<ESP8266WebServer.h\> and \<ESPAsyncWebServer.h\>, it's one or the other, you can't have both. Hence you're getting error: 'HTTP\_GET' conflicts with a previous declaration
> 1 votes

---
Tags: esp8266, library
---


# Question
Title: Using 1.1Vf to read stable battery voltage and sensor voltage
After several tries, i was successful with reading stable battery voltage using internal voltage reference of 1.1v, now the issue i face is that i cannot read stable sensor voltage, could you please let me know how can i read my sensor voltage? or do i need additional voltage divider (my sensor goes directly to A0 and GND pin).

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

void loop() {
  //REFS1 AND REFS0 to 1 1 -> internal 1.1V refference
  ADMUX |= B11000000;
  //We read A1 (MUX0) for battery voltage
  ADMUX |= B00000001;
    //We read A0 for sensor voltage
  ADMUX |= B00000000;                // for my sensor
  // Start AD conversion
  ADCSRA |= B11000000;
  // Detect end-of-conversion
  while (bit_is_set(ADCSRA,ADSC));
  float val = ADCL | (ADCH << 8);
  val = val * 5.7; // Using 4.7k and 1k voltage divider
  Serial.println(val);
}

```

Something like the code below must workout but unfortunately it does not help!

```
  int sensorValue = analogRead(A0);
  voltage =  ((sensorValue/ val) * 1023.);
  delay(1000);
  Serial.println("voltage:  ");
  Serial.print(voltage);
  if (voltage<=215){
  digitalWrite (led, HIGH);
  }
  else if (voltage>=215){
  digitalWrite (led, LOW);
  }

```

I cannot find the issue, it should work, i believe.

//////////////////////new edit/////////////////////////////////////

```
const long internalReference = 1078L; //measured AREF to be 1.078 ~ 1.078*1000= 1078V

void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
}

void loop() {
 analogReference (INTERNAL);
 ADMUX |= B00000000;
 ADCSRA |= B11000000;    //ADEN and ADSC equal to 1   (Start conversion)
  while(bit_is_set(ADCSRA, ADSC));    //Wait for conversion to end
  long val = ADCL | (ADCH << 8);   //Get analog read value
  float voltage = (val/internalReference)*1024;
 Serial.println (voltage);

 }

```

# Answer
To measure the voltage at A0 with an internal reference of 1.1v, the formula is `float voltage = 1.1 * analogRed(A0) / 1023;`. Your code can be simplified as

```
float Vref = 1.1;

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

void loop() {
  analogReference (INTERNAL);
  float voltage = Vref * analogRead(A0) / 1023;
  Serial.print (“voltage at A0:”);
  Serial.println(voltage);
  Serial.print (“Solar panel voltage:”);
  Serial.println(voltage * 5.7);
  delay(1000);
}

```
> 1 votes

---
Tags: arduino-ide, sensors, analogread, voltage-level, adc
---


title: if statement with string comparison

text:
# Question
Title: if statement with string comparison
**Code Snippet:**

```
String a;

const int red_led_pin = 13;

void setup()
{
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S2!");
  pinMode(red_led_pin, OUTPUT);
}

void loop() {

    while (Serial.available())
    {
        a = Serial.readString();// read the incoming data as string
        Serial.print(" First: ");
        Serial.println(a);

        if (a.equals("on"))
        {
          Serial.println("LED ON");
          digitalWrite(red_led_pin, HIGH);

        }

        else  if (a == "off" || a == "OFF")
        {
          Serial.println("LED OFF");
          digitalWrite(red_led_pin, LOW);
        }

        Serial.print("Second: ");
        Serial.println(a);
    }
}

```

**`Serial.print` out:**

**Circuitry:**

**Issue:**

The code can't capture the `on` string or any other string (`on`, `off` or `OFF`) that I pass. However it does pick it up and `Serial.print` it.

What is going wrong?

**Things I have tried:**

I have tried as a comparison:

* `if (a.equals("on")){<>}`
* `if (a == "on")){<>}`
* `if (a.equalsIgnoreCase("on")){<>}`

**Due Diligence / Prior Research:**

# Answer
Your problem is the line ending. The Serial Monitor has an option to send a line ending after the data, that you input. This line ending can be different depending on this setting, though mostly in the Arduino world a simple newline character `'\n'` is used.

This line ending will be in your string, when using `Serial.readString()`, so the string is not equal to `"on"`, but to something like `"on\n"`.

You can solve this issue by two ways:

* Set the Serial Monitor to no line ending.
* Or better: Use something like `Serial.readStringUntil()` and pass the line ending character to it as parameter (for example `Serial.readStringUntil('\n')`). This will read from the Serial interface until the specified character is reached. The specified character will be discarded and you are left with only the data, which you can then do comparisons on. This also has the advantage, that your code will react much faster, since it doesn't wait for 1s for new data (as long as you actually send the needed line ending).
> 5 votes

---
Tags: string
---


# Question
Title: CircuitPython - how to connect Adafruit esp32 AirLift with Adafuit HttpServer - incompatible socket object
I am building a CircuitPython weather station based on Adafruit M4 board stacked with Adafruit ESP32 AirLift module. Both work fine together when it comes to making http calls (via Adafruit\_requests library). However I would like to build a HTTP server serving weather measures instead. And here is a problem: all Adafuit examples are based on ESP32 or Raspberry Pico boards natively fitted with WIFI. Adafuit M4 board doesn't have the same core python packages since it doesn't sport WIFI. So example written for Pico doesn't work on M4 with ESP AirLift, there are a number of packages missing to do so (like wifi and socket), adafuit\_esp package has to be used instead. This package however seems to be incompatible with Adafuit HTTPServer: https://docs.circuitpython.org/projects/httpserver/en/stable/index.html HttpServer requires socket object as a parameter to be initialized:

```
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
socket.set_interface(esp)
server = HTTPServer(socket)

```

this code fails when I'm trying to start the server:

```
try:
    server.start(esp.pretty_ip(esp.ip_address))
    print("Listening on http://%s:80" % esp.pretty_ip(esp.ip_address))
#  if the server fails to begin, restart the pico w
except OSError:
    time.sleep(5)
    print("restarting..")
    microcontroller.reset()

```

and the error is:

```
>>> %Run -c $EDITOR_CONTENT
Creating display
Creating server socket
ESP32 found and in idle mode
Firmware vers. bytearray(b'1.2.2\x00')
MAC addr: ...
...
Connecting to AP...
Connected to jama   RSSI: -27
My IP address is 192.168.0.24
Creating HTTP Server...
starting server..
Traceback (most recent call last):
  File "<stdin>", line 175, in <module>
  File "adafruit_httpserver/server.py", line 91, in start
AttributeError: 'socket' object has no attribute 'bind'
>>>

```

So it looks like that's not the right socket ? it works for ESP and Requests libs but not for HTTPServer.

Here are imports:

```
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_esp32spi.adafruit_esp32spi_socket as socket

```

My question then (or two) is if anyone know a workaround for this issue and/or a different socket or server packages I can use instead ?

Here is the full code for the reference, it is not finished and contains more stuff that described here but unrelated to the issue:

```
import os
import time
import busio
import board
import microcontroller
from digitalio import DigitalInOut, Direction
import adafruit_bh1750
# import adafruit_requests as requests
from adafruit_bme280 import basic as adafruit_bme280
from adafruit_httpserver.server import HTTPServer
from adafruit_httpserver.request import HTTPRequest
from adafruit_httpserver.response import HTTPResponse
from adafruit_httpserver.methods import HTTPMethod
from adafruit_httpserver.mime_type import MIMEType
from adafruit_epd.epd import Adafruit_EPD
from adafruit_epd.il0373 import Adafruit_IL0373
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_esp32spi.adafruit_esp32spi_socket as socket

try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

#  onboard LED setup
# led = DigitalInOut(board.LED)
# led.direction = Direction.OUTPUT
# led.value = False

i2c = board.I2C()  # uses board.SCL and board.SDA
bh1750 = adafruit_bh1750.BH1750(i2c)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76)
bme280.sea_level_pressure = 1012.50

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
ecs = DigitalInOut(board.D9)
dc = DigitalInOut(board.D10)
srcs = DigitalInOut(board.D6)  # can be None to use internal memory
rst = None #DigitalInOut(board.D1)  # can be None to not use this pin
busy = None #DigitalInOut(board.D5)  # can be None to not use this pin

esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

print("Creating display")
display = Adafruit_IL0373(
    128,
    296,  # 2.9" Tri-color display
    spi,
    cs_pin=ecs,
    dc_pin=dc,
    sramcs_pin=srcs,
    rst_pin=rst,
    busy_pin=busy,
)

display.set_black_buffer(1, True)
display.set_color_buffer(1, True)
display.rotation = 1
display.fill(Adafruit_EPD.WHITE)
# display.display()
# display.text(splash, 12, 12, Adafruit_EPD.BLACK, size=1)

#  connect to network
print("Creating server socket")
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
socket.set_interface(esp)

if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])

for ap in esp.scan_networks():
    print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))

print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except OSError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))

print("Creating HTTP Server...")
server = HTTPServer(socket)

#  font for HTML
font_family = "monospace"

#  the HTML script
#  setup as an f string
#  this way, can insert string variables from code.py directly
#  of note, use {{ and }} if something from html *actually* needs to be in brackets
#  i.e. CSS style formatting
def webpage():
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-type" content="text/html;charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    html{{font-family: {font_family}; background-color: lightgrey;
    display:inline-block; margin: 0px auto; text-align: center;}}
      h1{{color: deeppink; width: 200; word-wrap: break-word; padding: 2vh; font-size: 35px;}}
      p{{font-size: 1.5rem; width: 200; word-wrap: break-word;}}
      .button{{font-family: {font_family};display: inline-block;
      background-color: black; border: none;
      border-radius: 4px; color: white; padding: 16px 40px;
      text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}}
      p.dotted {{margin: auto;
      width: 75%; font-size: 25px; text-align: center;}}
    </style>
    </head>
    <body>
    <title>Pico W HTTP Server</title>
    <h1>Pico W HTTP Server</h1>
    <br>
    <p class="dotted">This is a Pico W running an HTTP server with CircuitPython.</p>
    <br>
    <p class="dotted">The current ambient temperature near the Pico W is
    <span style="color: deeppink;">{temp_test}°{unit}</span></p><br>
    <h1>Control the LED on the Pico W with these buttons:</h1><br>
    <form accept-charset="utf-8" method="POST">
    <button class="button" name="LED ON" value="ON" type="submit">LED ON</button></a></p></form>
    <p><form accept-charset="utf-8" method="POST">
    <button class="button" name="LED OFF" value="OFF" type="submit">LED OFF</button></a></p></form>
    <h1>Party?</h>
    <p><form accept-charset="utf-8" method="POST">
    <button class="button" name="party" value="party" type="submit">PARTY!</button></a></p></form>
    </body></html>
    """
    return html

#  route default static IP
@server.route("/")
def base(request: HTTPRequest):  # pylint: disable=unused-argument
    #  serve the HTML f string
    #  with content type text/html
    with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
        response.send(f"{webpage()}")

#  if a button is pressed on the site
@server.route("/", method=HTTPMethod.POST)
def buttonpress(request: HTTPRequest):
    #  get the raw text
    raw_text = request.raw_request.decode("utf8")
    print(raw_text)
    #  if the led on button was pressed
    if "ON" in raw_text:
        #  turn on the onboard LED
        led.value = True
    #  if the led off button was pressed
    if "OFF" in raw_text:
        #  turn the onboard LED off
        led.value = False

    #  reload site
    with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
        response.send(f"{webpage()}")

print("starting server..")
# startup the server
try:
    server.start(esp.pretty_ip(esp.ip_address))
    print("Listening on http://%s:80" % esp.pretty_ip(esp.ip_address))
#  if the server fails to begin, restart the pico w
except OSError:
    time.sleep(5)
    print("restarting..")
    microcontroller.reset()

#  text objects for screen
#  connected to SSID text
connect_text_area.text = "Connected to:"
ssid_text = "%s" % secrets('ssid')
# ssid_text_area = label.Label(terminalio.FONT, text=ssid_text, color=0xFFFFFF, x=0, y=offset_y+15)
#splash.append(ssid_text_area)
#  display ip address
ip_text = "IP: %s" % wifi.radio.ipv4_address
# ip_text_area = label.Label(terminalio.FONT, text=ip_text, color=0xFFFFFF, x=0, y=offset_y+30)
#splash.append(ip_text_area)
#  display temp reading
temp_text = "Temperature: %.02f F" % float(temp_test)
# temp_text_area = label.Label(terminalio.FONT, text=temp_text, color=0xFFFFFF, x=0, y=offset_y+45)
#splash.append(temp_text_area)

def get_weather_conditions():
    temp = bme280.temperature
    print("\nTemperature: %0.1f C" % temp)
    hum = bme280.relative_humidity
    print("Humidity: %0.1f %%" % hum)
    pres = bme280.pressure
    print("Pressure: %0.1f hPa" % pres)
    alt = bme280.altitude
    print("Altitude: %0.2f meters" % alt)
    light = bh1750.lux
    print("Light: %.2f Lux" % light)
    return [temp, hum, pres, alt, light]

clock = time.monotonic() #  time.monotonic() holder for server ping

while True:
    try:
        #  every 30 seconds, ping server & update temp reading
        if (clock + 30) < time.monotonic():
            if wifi.radio.ping(ping_address) is None:
                connect_text_area.text = "Disconnected!"
                ssid_text_area.text = None
                print("lost connection")
            else:
                connect_text_area.text = "Connected to:"
                ssid_text_area.text = "%s" % secrets('ssid')
                print("connected")
            clock = time.monotonic()
            #  comment/uncomment for desired units
            #  temp_test = str(ds18.temperature)
            temp_test = str(c_to_f(19.45))
            temp_text_area.text = "Temperature: %s F" % temp_test

#         display.show(splash)
        #  poll the server for incoming/outgoing requests
        server.poll()
    # pylint: disable=broad-except
    except Exception as e:
        print(e)
        continue

```

# Answer
> 0 votes
Official answer from Adafuit for this question is that HTTPServer lib is created for Raspeberry PICO and do not work on other boards like Feather M4 express indeed. Different set of libraries needs to be used instead, here is the relevant example: https://github.com/adafruit/Adafruit\_CircuitPython\_ESP32SPI/tree/main/examples/server

---
Tags: adafruit, python
---


# Question
Title: Unable to get my created library to work - while it compiles
I am experimenting with creating my own Arduino libraries. Unfortunately, while the program compiles, the end result does not work.

For purposes of experimentation, I have broken down the library in two parts. One that will handle blinking by controlling the `LED_BUILDIN` pin and one that will talk to the serial input.

Thus two `.h` and two `.cpp` files. Plus there is another file for the configuration that handles preprocessor directives that the library reads.

This is the code:

FILE 1

```
//header_config.h
#ifndef MY_CONFIGURATION
#define MY_CONFIGURATION

#include <Arduino.h>

#define SERIAL_DEBUG
#define LED_BLINK

#include <led_functions.h>
#include <serial_functions.h>

void my_setup()
{
  my_setup_led();
}

void my_loop()
{
    led_blinker();
    serial_transmit("Hello");
}

#endif

```

FILE 2

```
//led_functions.h
#ifndef MY_LED_LIBRARY
#define MY_LED_LIBRARY

  #include <Arduino.h>
  #include "header_config.h"
  #include "serial_functions.h"

  extern void led_blinker();
  extern void my_setup_led();

#endif

```

FILE 3

```
//led_functions.cpp
void led_blinker()
{
  #ifdef LED_BLINK
  digitalWrite(LED_BUILTIN, HIGH);
  serial_transmit("LED ON");
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  serial_transmit("LED OFF");
  delay(1000);
  #endif
}

void my_setup_led()
{
#ifdef LED_BLINK
pinMode(LED_BUILTIN, OUTPUT);
#endif
}

```

FILE 4

```
//serial_functions.h
#ifndef MY_SERIAL_LIBRARY
#define MY_SERIAL_LIBRARY

  #include <Arduino.h>
  #include "header_config.h"

  #ifdef SERIAL_DEBUG
  #include <SoftwareSerial.h>
  #define rxPin 2
  #define txPin 3
  SoftwareSerial mySerial(rxPin, txPin);
  #endif

  extern void serial_transmit(char*);

#endif

```

FILE 5

```
//serial_functions.cpp
void serial_transmit(char *str)
{
  #ifdef SERIAL_DEBUG
  //mySerial.begin(9600);
  //mySerial.println(str);
  //mySerial.end();
  Serial.begin(9600);
  Serial.println(str);
  Serial.end();
  #endif
}

```

Please note that while the serial code creates a `SoftwareSerial` object (in `serial_functions.h`), I do not use that (in `serial_functions.cpp`) and instead I make use of hardware Serial. The reason is debugging, so that I can see communication on the PC. I left the `SoftwareSerial` object inside, because that is what I ultimately want.

Finally, outside the library, in it's separate folder, is the `.ino` file that makes use of this library.

```
#include <header_config.h>
#include <led_functions.h>
#include <serial_functions.h>

void setup()
{
  my_setup();
}

void loop()
{
  my_loop();
}

```

As I said, the program compiles fine, but it does not work in the real world. Neither the blinking, nor the serial communication.

# Answer
Your cpp files don't include the header\_config.h file, so they don't have SERIAL\_DEBUG and LED\_BLINK defined.

The content of included file replaces the include directive so if you now include header\_config.h into both cpp, there will be 3 functions named my\_setup() and 3 functions named my\_loop() and the linker will complain. So you can't put functions definitions into an include file. And for the same reason you can't have variable definitions in .h file so the SoftwareSerial instance will cause problems too if used.
> 1 votes

---
Tags: library, c-preprocessor
---


title: NodeMCU wiring for Serial1?

text:
# Question
Title: NodeMCU wiring for Serial1?
I'm trying to get telemetry data to be sent out Serial1 on the NodeMCU board. I read that TX is (by default) mapped to pin D4.

Ultimately, there will be a Raspberry that will be listening for these messages, but I don't have it yet. So to quickly test this, I connected an oscilloscope with Serial decoding to D4 and the GND of the probe to GND on the NodeMCU. The problem is I'm not getting any indication of activity out D4 when I run the following code:

```
Serial1.begin(9600);
Serial1.printf("some text");

```

Am I wiring the probe correctly? Am I missing another serial command in the sketch?

When I move to the rPI, do I GND both boards together, then write TX (D4) to RX on the rPI?

# Answer
You can do Serial.swap() in setup() to swap Serial away from RX/TX pin. Serial is then on D7 as RX and D8 as TX (and you can wire some serial module there).

Bridge with jumper wire D4 pin with TX pin. the Serial1 output will go over the USB chip to Serial Monitor and you will see the prints to Serial1.

This will not disturb the flashing mode, because bootloader will still listen on standard Serial pins.
> 3 votes

# Answer
## This code worked for me as Modbus slave

Required this library \<ModbusRtu.h\>

```
#include <ModbusRtu.h>
unsigned long TIME = 0;
unsigned long LASTTIME = 0;
unsigned long INTERVAL = 5000;

int i = 0;
// data array for modbus network sharing
uint16_t au16data[16] = {
  3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : serial port
 *  u8txenpin : 0 for RS-232 and USB-FTDI
 *               or any pin number > 1 for RS-485
 */
Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

void setup() {
  Serial.swap();
  Serial.begin( 19200 ); // baud-rate at 19200
  Serial1.begin( 19200 );
  slave.start();
}

void loop() {

  if ((millis() - TIME) > INTERVAL) {
    i++;

    if(i == 16){
      i = 0;

      for (int ii = 0; ii < 16; ii++)
      {
        au16data[ii] = 0;
      }
    }

    au16data[i] = 1;

    TIME = millis();
  }

  slave.poll( au16data, 16 );
}

```
> 0 votes

---
Tags: serial, nodemcu
---


# Question
Title: How to prevent an Arduino connected to the Internet from being hacked?
I have an Arduino (with environmental sensors doing measurements) connected to the Internet via ethernet. Can it be hacked? Can someone access it via Internet and upload his own C/C++ code? If, yes how can I prevent this?

**Update (03/03/2023):** One final thought: Supposing that I have secured USB plug and nobody can access it. However, I am using the Serial interface of the Arduino MEGA 2560. So, Serial\_1 is continuously reading. Can someone with ***physical access*** to the Arduino inject malicious code via the Serial\_1 so that can alter the code inside my Arduino and have access to information?

# Answer
This depends on what you consider "hacked".

Do you care about someone reading the data, or changing it on its way to the target? Or do you provide endpoints to trigger something in your project from the internet, that only you should be able to do? Then you need to think about authentication and encryption. Though I guess that this data will be published either way, so that is not a big problem. But you should write down every endpoint, that you expose to the internet, and every request you are making. Then decide what level of security you need them to have individually. Exposed endpoints can easily be found and you have to decide yourself, if it is OK for others to use them.

If you mean getting into the device and executing malicious code from there: IOT devices are often vulnerable because of two reasons. They often have an OS (like a small linux OS), that is badly secured (often using standard password). And they often get updates via the internet. If someone can hijack the update process, malicious code might be delivered. An Arduino doesn't have an OS, so that isn't a problem. And hijacking the update process won't be possible, if you don't provide the possibility to update through the network. This makes updating your code a bit more complicated (since you need to connect the Arduino via USB or similar to program it), but more secure. That way no one (not even you) can inject malicious code into your project without physical access to the Arduino. To take up Jurajs comment: Updating through network is normally done by the Ethernet bootloader or the ArduinoOTA library (Over The Air updates). If you are not using those or similar projects, then you will be safe in that regard.

---

With strangers having physical access to the device it is a different story. To reprogram the Arduino one would need access to Serial (RX0 and TX0) and a possibility to reset the Arduino (either Reset pin or a way for power cycling it), or access to the ISP pins and the reset pin.

If you can secure the Arduino itself from physical access and only expose the Serial1 interface and ground/5V, then you will be safe, since the bootloader is only listening on Serial (RX0 and TX0). But keep in mind, that someone might still break into your project with brute force - depending on how you secured it physically. At that point nothing can stop them from overwriting your code. Only you can assess how big the chance for that is and how bad it would be.

Another point: If someone manages to break into your project, he can read out the program and push it through a deassembler. That doesn't give them the C++ code - they are not seeing C++ code, only assembler, and no meaningful variable names - but if they are determined enough they can read out credentials, that you might have hard coded or saved in EEPROM. Though especially for environmental sensors I would say the chance is very low, that someone would go to such lengths. If you think the danger to be big enough for some inconvenience, you can have a look at code protection (protecting the program memory from being read), though that still doesn't completely block reprogramming.

All in all: Preventing physical access is a big step in security. You yourself need to assess how much security you really need for your project.
> 1 votes

---
Tags: arduino-mega
---


title: Calibration of pH sensor

text:
# Question
Title: Calibration of pH sensor
I am working with pH sensor (https://wiki.seeedstudio.com/Grove-PH-Sensor-kit/ ) and arduino. The board provided with sensor is not having any potentiometer to set the voltage value when dipped in known buffer solution. I have read that when BNC connector is short then voltage value should be 2.5 V. But when I do the same voltage comes out to be 1.9 V. Also sensor gives wrong readings when put in known buffer solutions of 4.0pH, 7.0pH and 9.2 pH. I am not getting how to calibrate the sensor without having potentiometer on board. I have already done as per mentioned on website (in link given above).

# Answer
You probably need to do that in software. That is supported by step 7 in the chapter Software on your linked site.

In step 4 we see the proposed demo code, which contains the calculation of pH based on the read voltage:

```
pHValue = -19.18518519 * voltage + Offset;

```

The first number is probably `k`, so the calculation is

```
pHValue = k * voltage + Offset;

```

For the calibration you need to find the values for `k` and `Offset`. This is done with 2 buffer solutions with known pH. Step 7 shows the formulas for calculating these values based on the known pH values (removed the dollar signs):

```
k= (PH2-PH1)/(V2-V1)
Offset=[(PH2+PH1)-k*(V1+V2)]/2

```

And they even provide a link to an Excel sheet, which helps you with the calculation: https://files.seeedstudio.com/wiki/Grove-PH\_Sensor\_kit/Calibration\_for\_k&offset.xlsx

Here is an image of that sheet:

In column B behind PH1 and PH2 you can input the known pH values for your buffer solutions. In column E behind V1 and V2 you can input the resulting sensor voltages (! voltages, not wrongly calculated pH values) for each solution. Then you will get your values of `k` and `Offset` in the cells B4 and B5.

Input those values into the calculation for `phValue` in the code and you should get correct values.
> 1 votes

---
Tags: arduino-uno, sensors, calibration
---


title: I2C_Anything ++

text:
# Question
Title: I2C_Anything ++
a request for information has been formulated, how to say it?

in Ascii: i2C dialog: Tx -----\> Rx ----\> PCF8574

a drawing https://nsm09.casimages.com/img/2023/02/28/23022802163423870818122937.jpg

3 elements on the i2C bus

* an Arduino "Tx" to read values from an electric counter
* an Arduino "Rx" to recycle the values and also to dialogue on a Rs485 bus
* and a PCF8574 which receives the commands from the Arduino "Rx" to operate telestage relays

1st question:

```
I2C_writeAnything (foo1);
(foo2);
(foo3);
I2C_writeAnything (foo X?);

```

What is the maximum number of foo1 .. foo2 ...foo10 that I can put ?

Is this the right method? or do we have to group them by pack?

2nd question:

when we use several libraries, in their sketch we find calls to #include \<Wire.h\> that are added to the main sketch. Can this be a cause of problems?

thanks

```
Arduino "Tx" for electrical measurements (simulation with a "random")

void loop()  {

unsigned long foo1 = random(2294967295);
unsigned long foo2 = random(2294967295);
unsigned long foo3 = random(2294967295);
unsigned long foo4 = random(2294967295);
unsigned long foo5 = random(2294967295);

if (timer0.available()) {
Wire.beginTransmission (SLAVE_ADDRESS);

I2C_writeAnything (foo1);
I2C_writeAnything (foo2);
I2C_writeAnything (foo3);
I2C_writeAnything (foo4);
I2C_writeAnything (foo5);

Wire.endTransmission ();

if (!Wire.endTransmission ()) { Serial.println ("endTransmission () : "); }
timer0.restart();
}
} /*Loop*/

//Arduino "Rx" for reading and using the Electrical values
#include <Wire.h>
#include <I2C_Anything.h>           //http://www.gammon.com.au/i2c
const byte MY_ADDRESS = 42;

volatile boolean haveData = false;
volatile unsigned long foo1;
volatile unsigned long foo2;
volatile unsigned long foo3;
volatile unsigned long foo4;

#include "PCF8574.h"                //https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
PCF8574 PCF27a (0x3D);  // adjust addresses i2c pcf8574

//...setup
//...loop

void receiveEvent (int howMany)  {

// if (howMany >=  4)
if (howMany >=  (sizeof foo1))    {
I2C_readAnything (foo1);
I2C_readAnything (foo2);
I2C_readAnything (foo3);
I2C_readAnything (foo4);

haveData = true;
}
}  // end of receiveEvent

```

# Answer
A return on the module of Electrical measurements. with an i2C bus. (it can be useful for other people)

No more errors, no more blocking, it purrs like a kitten.

For the structure I copied the work of Peter\_n (thanks to you) it helped me a lot: https://forum.arduino.cc/t/i2c-not-sending-all-data-with-i2c\_anything/293609

and for the : Wire.setWireTimeout(3000,true); not sure where to put it, it's put on both parts.

a copy of the sketches

Master\_I2C\_Anything\_Linky\_uneStructure\_bigOctes.ino

```
  // base Written by Nick Gammon - May 2012 :
// struct de Peter_n : https://forum.arduino.cc/t/i2c-not-sending-all-data-with-i2c_anything/293609

//------------------ Dialogue on i2c bus between 2 ATMega328 - Arduino-Uno ------------
// --- 2x6 32-bit values  ou 1x 7
//------------------   functional test model ---------------------------
// Add in setup :  Wire.setWireTimeout(3000,true);

  #include <Wire.h>
  #include <I2C_Anything.h>   //http://www.gammon.com.au/i2c

  const byte SLAVE_ADDRESS = 42;

  #include "Timers.h"         //https://github.com/nettigo/Timers
  Timer timer0;   // delay

//------------  struct -------------------------
//------------ linky info ---- 7 types de variables --------//

  struct sensorData_STRUCT {
  byte sensorNumber;
    uint16_t A;   // uint16_t PAPP in VA
    uint32_t B;   // uint32_t BASE index in Wh
    uint32_t C;   // uint32_t HCHC index heures creuses en Wh
    uint32_t D;   // uint32_t HCHP Index heures pleines en Wh
    uint8_t E;    // uint8_t  IINST  Returns in Amp
    uint8_t F;    // uint8_t ISOUSC  Returns ISOUSC
    uint8_t G;    // uint8_t PTEC Periode tarifaire en cours (0 = HP, 1 = HC)
     uint8_t H;    // test
  } sensorData[1]; // [x] number of structures

//---------------------- SETUP --------------------
void setup() {
  Serial.begin (115200);
  Serial.println(F(" Master_I2C_Anything_Linky_structure_double.ino "));
  Serial.print(__DATE__); Serial.println(__FILE__);

  Wire.begin ();

  Wire.setWireTimeout(3000,true);

  // fill fixed data
  sensorData[0].sensorNumber = 0;
 // sensorData[1].sensorNumber = 1; //desactivé

  timer0.begin(SECS(3));  //delay transmission

  } /*Setup*/

//-------------------- LOOP -----------------------
  void loop()  {

//---------------- strucuture ------------
// collect new data
  sensorData[0].A = 10 ;
  sensorData[0].B = random(2000000000);
  sensorData[0].C = random(2000000000);
  sensorData[0].D =  random(2000000000) ;
  sensorData[0].E =  random(2000000000) ;
  sensorData[0].F =  random(2000000000) ; // valeur fixe
  sensorData[0].G = 70 ; // valeur fixe
  //     = 19 octes
//unsigned long : non-negative integer of  0 à 4 294 967 295 sur 32 bits de 4 octets

//------------------

  if (timer0.available()) {

 // 1; 2; choix du nbr de structre
  for( int sensor = 0; sensor < 1; sensor++)  {
    // transmit the data
    Wire.beginTransmission( SLAVE_ADDRESS);
    I2C_writeAnything( sensorData[sensor]);

    int error = Wire.endTransmission (); //(true) ?
     if( error != 0) {
      Serial.println(F("Error, no acknowledge from Slave"));
    }
  }

    timer0.restart();
  }

  } /*Loop*/

//---------------------- End pgm ----------------------------

```

Slave\_I2C\_Anything\_PCF8574\_4DO\_uneStructure\_bigOctes.ino

```
/*
 *  DESCRIPTION :
 *  un Arduino Uno en liaison avec un module i2c PCF8574 avec 4 Relais
 *  il recoi aussi d'un autre Arduino des valeurs en Kw pour le basculement des relay
 *
 *
 *  LIBRAIRIES:
 *    - Rob Tillaart pour PCF8574 https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
 *    - Nick Gammon  for bus i2c  http://www.gammon.com.au/i2c
 *    - Timers de Łukasz Tretyn   https://github.com/nettigo/Timers
 *
 *  ELEMENTS: sur le bus i2c
 *    - Expander PCF8574 avec module Metasys JC / 4DO - 0X3D  i2c adress
 *    - ATMega328  pour mesure Electrique
 *    - ATMega328  en Reception
 *
 *  MODIFICATION:
 *    -x- model de Peter_n : https://forum.arduino.cc/t/i2c-not-sending-all-data-with-i2c_anything/293609/11
 *    -o-
 *    -o-
 *
 *     RAS
*/

//------ Mars 2023 -------- Linky PCF8574 - 4DO / Bus i2c -----------------//

// -------------  Functional TEST BUS I2C -----------------------//
// une struct de 19 Octes, pour un maximum  de 32octes

//------ i2C Bus ------------
  #include <Wire.h>
  #include <I2C_Anything.h>
  const byte MY_ADDRESS = 42;

  // The struct must be the same in the Master and in the Slave
  //unsigned long:4 octet (32 bits) - max 4294967295
  struct sensorData_STRUCT {
  byte sensorNumber;
    uint16_t A;   // uint16_t PAPP in VA
    uint32_t B;   // uint32_t BASE index in Wh
    uint32_t C;   // uint32_t HCHC index heures creuses en Wh
    uint32_t D;   // uint32_t HCHP Index heures pleines en Wh
    uint8_t E;    // uint8_t  IINST  Returns in Amp
    uint8_t F;    // uint8_t ISOUSC  Returns ISOUSC
    uint8_t G;    // uint8_t PTEC Periode tarifaire en cours (0 = HP, 1 = HC)
     uint8_t H;    //
    };

/*  struct sensor2Data_STRUCT {
  byte sensor2Number;
    int G;
    int H;
    int I;
    int J;
    int K;
    int L;
    }; */

  // A special struct for the received sensor data
  volatile sensorData_STRUCT sensorDataNew;

  // A flag to indicate new data
  volatile boolean haveData = false;

  // The normal sensor data
  sensorData_STRUCT sensorData[1];  //nbr de structure [2]

//---------------- PCF8574 -------------------------------
  #include "PCF8574.h"
  PCF8574 PCF27a (0x3D);  // adjust addresses i2c pcf8574

  #define RELAY_ON  0    //
  #define RELAY_OFF 1    //

// -----------------------------------------------------------------------------
//      -----------------          SETUP          ---------------------
// -----------------------------------------------------------------------------

void setup() {

  Wire.begin (MY_ADDRESS);  // bus i2C
  Wire.onReceive (receiveEvent);

  Serial.begin (115200);
  Serial.println(F(" SlaveI2CAnythingPCF8574Structure_bigOctes "));
  Serial.print(__DATE__); Serial.println(__FILE__);

  // fill fixed data
  sensorData[0].sensorNumber = 0;

  Wire.setWireTimeout(3000,true);

  PCF27a.begin();           // i2C PCF8574

//--------- testing IsConnected i2c PCfx ------------
  Serial.print(F(" PCF8574_LIB_VERSION : \t")); Serial.println(PCF8574_LIB_VERSION);
  if (!PCF27a.begin())   {
    Serial.println(F("could not initialize..."));
    }
  if (!PCF27a.isConnected())   {
    Serial.println(F("=> not connected"));
  }
  else   {
    Serial.println(F("=> connected!!"));
    }

  } /* fin Setup */

// --------------------------------------------------------------------------
//         -----------------        LOOP      ------------------------
// --------------------------------------------------------------------------
 void loop() {

//---------------- i2C bus -------------------------------
  int sensor;  int sensor2;

    if( haveData)  {
    // New data has arrived, copy it in one of the two sensorData.
    // Disable interrups as short as possible
    // The interrupts are disabled to avoid an receiveEvent interrupt that writes new data.
    noInterrupts();
    sensor = sensorDataNew.sensorNumber;

  if( sensor == 0 || sensor == 1) {         // destination, source, size
  memcpy( &sensorData[sensor], (const void *) &sensorDataNew, sizeof( sensorData_STRUCT));

  }
  haveData = false;
  interrupts();

    printData(sensor) ; //print Data
    cmdRelay() ;        // Relay PCF8574
   }

 } /* fin Loop */

// -----------------------------------------------------------------------------
//   -------------------  Receiving messages I2C    ------------------
// -----------------------------------------------------------------------------
//howMany est le nombre d'octets reçus et par conséquent combien vous pouvez lire
//avec Wire.read(), pour un maximum de 32 octes.

 void receiveEvent( int howMany) {
  if( howMany == sizeof( sensorData_STRUCT)) {
    I2C_readAnything( sensorDataNew);
         haveData = true;
  }
  else {
    // something is wrong. Wrong number of bytes received.
    // it is possible to set a volatile variable to an error.
  }
 }

// -----------------------------------------------------------------------------
//   -------------------  Relay Control   ------------------
// -----------------------------------------------------------------------------
 void cmdRelay() {
//-------- Relay 1 ---------
  if (sensorData[0].A > 829308135 ) { PCF27a.write(0, RELAY_ON); }
  else { PCF27a.write(0, RELAY_OFF); }
     //Serial.println(PCF27a.read(0));
//-------- Relay 2 ---------
  if (sensorData[0].B > 304929158) { PCF27a.write(1, RELAY_ON); }
  else { PCF27a.write(1, RELAY_OFF); }
      //Serial.println(PCF27a.read(1));
//-------- Relay 3 ---------
  if (sensorData[0].C > 590793899 ) { PCF27a.write(2, RELAY_ON); }
  else { PCF27a.write(2, RELAY_OFF); }
     //Serial.println(PCF27a.read(2));
//-------- Relay 4 ---------
  if (sensorData[0].D > 304929158) { PCF27a.write(3, RELAY_ON); }
  else { PCF27a.write(3, RELAY_OFF); }
      //Serial.println(PCF27a.read(3));
 }

// -----------------------------------------------------------------------------
//   -------------------  Print data   ------------------
// -----------------------------------------------------------------------------
  void printData(int sensor) {

  if (sensor == 0 ) {
    Serial.print(F( "------ sensor["));
    Serial.print( sensor); Serial.println(F( "] ------"));
    Serial.print(F( "a PAPP  = ")); Serial.println( sensorData[0].A);
    Serial.print(F( "b BASE  = ")); Serial.println( sensorData[0].B);
    Serial.print(F( "c HCHC  = ")); Serial.println( sensorData[0].C);
    Serial.print(F( "d HCHP  = ")); Serial.println( sensorData[0].D);
    Serial.print(F( "e IINST = ")); Serial.println( sensorData[0].E);
    Serial.print(F( "f ISOUSC= ")); Serial.println( sensorData[0].F);
    Serial.print(F( "g PTEC  = ")); Serial.println( sensorData[0].G);
     Serial.print(F( "h test  = ")); Serial.println( sensorData[0].G);

Serial.println(sizeof( sensorData_STRUCT));
    }
    Serial.println();
  }
//------------------------------ End pgm -------------------------------------

```
> 0 votes

---
Tags: arduino-uno
---


title: Random artifacts on SSD1306 OLED screen

text:
# Question
Title: Random artifacts on SSD1306 OLED screen
I'm having a really strange problem with my screen. It's connected in i2c to my Arduino Nano and I'm using a rotary encoder to navigate through a menu.

At startup everything is fine, but when I change menus a couple of times, there are flickering artifacts that start showing up in the bottom right corner. Did anyone ever get that kind of localized noise?

I thought maybe it would be my refresh rate that was a bit too high, I only had 10ms. But I cranked it up to 50 and it didn't change a thing.

https://youtu.be/riwLRgtHG0g

EDIT: Thank you for your feedback! I tried a different approach, like you suggested, and got rid of all the calls to displayMenu() and the multiple while loops. The artifacts are smaller now, but they're still there...

They used to occur all the time and now they're just appearing during chooseValue() and action3() now. As if it was linked to the "value" variable. I don't get it...

Here's the updated code:

```
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_I2CDevice.h>
#include <math.h>

#include <RotaryEncoder.h>
#include <ButtonStates.h>

#define SCREEN_WIDTH    128
#define SCREEN_HEIGHT   64
#define OLED_RESET      -1                                                  // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS  0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

RotaryEncoder encoder(A2, A3);                                              // Rotary encoder connected to A2 and A3
ButtonSwitch button(2);                                                     // Rotary encoder button

int value = 0;                                                              // Value changed in one of the menus
int selection = 0;                                                          // Encoder position

struct menuItem {                                                           // Structure defining a menu item
  const char *name;                                                         // Item name
  void (*action)();                                                         // Pointer pointing to the function handling the action
};

struct menu {                                                               // Structure defining a menu
  char *name;                                                               // Menu name
  int items;                                                                // Number of items in the menu
  struct menuItem *collection;                                              // Array containing all the menu items
};

struct menuItem menu1collection[5];                                         // Array for the menu
struct menuItem item1, item2, item3, item4, item5;                          // Items of the menu
struct menu menu1 = { "Today's menu", 5, menu1collection };                 // Structure holding all the menu's info

struct menuItem menu2collection[4];
struct menuItem item6, item7, item8, item9;
struct menu menu2 = { "Tomorrow's menu", 4, menu2collection };

struct menu currentmenu = menu1;

enum screens { MENU, CHOOSEVAL };
enum screens screen = MENU;

void chooseValue(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.write( 17 );
  display.setCursor(45, 20);
  display.print(selection);
  display.print("g");
  display.setCursor(115, 20);
  display.write( 16 );
  display.display();
}

void displayMenu(){                                                         // Function displaying the menu passed in argument
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 5);
  display.println(currentmenu.name);                                        // Display menu title

  int div = floor((selection-0.5)/4);                                       // Handle menus with more than 4 elements

  for(int i=(4*div+1), j=0 ; i<=currentmenu.items && j<4 ; i++, j++){       // Cycle through 4 menu items
    if(i==selection){                                                       // Highlight selected item
      display.fillRect(0, 18+10*j, 128, 10, SSD1306_WHITE);
      display.setCursor(20, 20+10*j);
      display.setTextColor(SSD1306_BLACK);
      display.println(currentmenu.collection[i-1].name);
    }
    else{
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(20, 20+10*j);
      display.println(currentmenu.collection[i-1].name);                    // Display item
    }
  }
  display.display();
}

ISR(PCINT1_vect) {                                                          // Interrupt routine for the rotary encoder
  encoder.tick();                                                           // Check the state of the encoder
}

// Functions handling the actions for each menu item ------------------------------------------------------------------
void action1(){
  screen = CHOOSEVAL;
}

void action2(){
  currentmenu = menu2;
  encoder.setPosition(1);
}

void action3(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(45, 20);
  display.print(value);
  display.println("g");
  display.display();

  delay(1000);
}

void action4(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 4!");
  display.display();

  delay(500);
}

void action5(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 5!");
  display.display();

  delay(500);
}

void action6(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 6!");
  display.display();

  delay(500);
}

void action7(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 7!");
  display.display();

  delay(500);
}

void action8(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 8!");
  display.display();

  delay(500);
}

void action9(){
  currentmenu = menu1;
  encoder.setPosition(1);
}
// -------------------------------------------------------------------------------------------------------------------

void handleMenu(){
}

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

  // Creating a menu requires the following ----------------------------------------------------------------------------
  item1.name = "Choose a value";
  item1.action = action1;
  menu1collection[0] = item1;

  item2.name = "Go to menu 2";
  item2.action = action2;
  menu1collection[1] = item2;

  item3.name = "Display value";
  item3.action = action3;
  menu1collection[2] = item3;

  item4.name = "Item 4";
  item4.action = action4;
  menu1collection[3] = item4;

  item5.name = "Item 5";
  item5.action = action5;
  menu1collection[4] = item5;

  item6.name = "Item 6";
  item6.action = action6;
  menu2collection[0] = item6;

  item7.name = "Item 7";
  item7.action = action7;
  menu2collection[1] = item7;

  item8.name = "Item 8";
  item8.action = action8;
  menu2collection[2] = item8;

  item9.name = "< Back";
  item9.action = action9;
  menu2collection[3] = item9;
  // -------------------------------------------------------------------------------------------------------------------

  PCICR |= (1 << PCIE1);                                                  // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);                              // This enables the interrupt for pin 2 and 3 of Port C.

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {              // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                                              // Don't proceed, loop forever
  }

  // Init display
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Loading...");
  display.display();

  delay(500);
}

void loop() {
  switch(screen){
    case MENU:
      selection = encoder.getPosition();                                      // Get the encoder's position

      if (selection < 1) {                                                    // Stop the encoder on the min position
        encoder.setPosition(1);
        selection = 1;

      } else if (selection > currentmenu.items) {                             // Stop the encoder on the max position (number of items minus 1)
        encoder.setPosition(currentmenu.items);
        selection = currentmenu.items;
      }

      displayMenu();

      if (button.triggerSingle()){
        currentmenu.collection[selection-1].action();                         // If a click is detected do the item's action
      }
      break;
    case CHOOSEVAL:
      selection = value + encoder.getPosition() * 10;

      if (selection < 1) {                                                    // Stop the encoder on the min position
        encoder.setPosition(1);
        selection = 1;
      }

      chooseValue();

      if (button.triggerSingle()){
        value = selection;
        encoder.setPosition(1);
        screen = MENU;
      }
      break;
  }
}

```

# Answer
This is a solution that I accidentally came up with. I had a problem of strange artifacts corruption in bottom right corner of my SSD1306 display when I tried to print scrolled row of text.

It does its job, so if anyone come by this topic in the future feel free to test it:

```
int x, minX;
oled_dispMidTextScroll(F("SETPOINT REACHED! LONG PRESS LEFT TO SET UP A TIMER"));

void oled_dispMidTextScroll(String str){
  char text[50];
  int size = 1;
  str.toCharArray(text, 50);
  display.setTextSize(size);
  minX = (-1 * size * 6) * strlen(text);  // 12 = 6 (px/char) * 2 (textsize)
  display.setCursor(x,28);
  display.print(text);
  x -= 4; // speed
  if (x < minX) {x = display.width();}
}

```
> -1 votes

---
Tags: arduino-nano, i2c, oled
---


title: Fast digital IO

text:
# Question
Title: Fast digital IO
I have a device programmable via an 8 bit digital parallel bus. I would like an Arduino to translate from a parallel 4 bit output of an existing device to 8 bit by intentionally reducing the resuloution. Unfortunately, I can't just use the most significant bits as I want to change the step size. The idea is to use an Arduino that ready the 4 digital input bits and then computs the necessary 8 bit output which it output to the 8 bit bus. However, this need to be as fast as 1 us. Is this possible with an Arduino? If so which board would you recommend? I guess I can't use the digitalWrite command as this will be too slow though. Any suggestions?

# Answer
You can do this with an Uno, provided it has nothing else to do. I would program it low-level, skipping the Arduino core since, as you said, `digitalWrite()` would be too slow for this application.

Here is my proposed approach: read the 4-bit input from one port, use a look-up table to translate it to an 8-bit output, and write that output to another port. I would use PORTD (pins 0–7) for the output, as it is the only full 8-bit port on the Uno, then the first bits of PORTB (pins 8–11) for the input:

```
/* Translation look-up table (dummy example). */
const uint8_t lut[16] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};

int main() {
    DDRB = 0x00;  // set port B as input
    DDRD = 0xff;  // set port D as output
    for (;;) {
        uint8_t input = PINB & 0x0f;  // grab the lowest 4 bits
        PORTD = lut[input];  // set the output
    }
}

```

I compiled and disassembled this code to count the CPU cycles: the main loop takes 10 cycles per iteration. Given that the Uno is clocked at 16 MHz, this is one update of the output every 0.625 µs.

**Edit**: This is a straightforward approach. At the cost of some extra complexity, it could be optimized down to 7 cycles per iteration (0.438 µs), or even 6 cycles (0.375 µs) in assembly.
> 3 votes

---
Tags: digital, digitalwrite, digital-in
---


title: Arduino Modbus Slave Library Needed

text:
# Question
Title: Arduino Modbus Slave Library Needed
We are building a circuit based on ATMega328\* that :

1. Reads 32 current transducers, multiplexed into one Analog Input,
2. Reads 12 voltage transducers, multiplexed into one Analog Input,
3. Reads 6 temperature sensors, multiplexed into one Analog Input,
4. Manipulates all the readings with some math (like scaling, averaging etc.),
5. Calculates new variables (power, crest factor, etc.),
6. Tracks trends (max/min/avg) of certain (calculated) readings,
7. Stores some events (peaks/dips - max/min values) etc. with time stamps from RTC,
8. Generates Alarm Flags (by comparing readings to software-set thresholds),

The circuit should be connected as a ModBus Device (Slave) to an existing Modbus network with several other devices on an RS485 interface.

The circuit should communicate all these calculated values and alarms as well as some other info, like peak/max values with date and time stamps that were recorded at their time of occurrence, to the Modbus Master. We have the freedom of allocating the register numbers and their formats etc. (Modbus Map) to the controller's vendor (SAUTER). For example we tell them Register 30001 is the current sensor x, 30002 is voltage sensor y, etc.

We think that sending time stamps (of certain events) will be based on "agreed-upon" coding of register values (MM, DD, YYYY, etc.) and the same for alarms (to be sent as hex codes).

We have searched for libraries and got really confused from the multitude of libraries out there, as well as the lack of documentation -:)

Can you please kindly help us : select the proper Arduino Modbus Slave Library that :

1. Has MAX485 support,
2. Assigns Modbus registers to any arbitrary variables,
3. Issues Exception Responses to Modbus requests (e.g. non-existing registers or un-supported Function Codes.
4. Complies to Modbus Standards
5. Has a manual !!

We found the "yaacov" library on Github but it assigns registers directly to "Pins". Also we looked at its "issues" and one of them was very serious : in which frames coming from the Master with corrupted CRC gets responded to and causes collision with other slaves. We dont like that ! as it indicates that the library was not tested in true industrial environment.

We also found that the Library at :

https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/

somewhat fits to our requirements, however it lacks the RS485 support, and more important, it has no documentation.

We really appreciate any kind support.

* The ATmega328 will be probably replaced with a larger CPU, but we are still in development phase.

Thank you.

# Answer
> 1 votes
With my post approaching one month without a single reply :smiley-confuse: ! (for whichever reason) I would like to post for those who may need this library :

---

## https://drive.google.com/file/d/0Bx5wWRfN\_z7oMDlZMDhWbXM2VFU/view

The library is based on the original one written by Jason Vreeland \[CodeRage\] Released 3/7/2010 under GNU license

and was used (and possibly modified) by "jhottell" on electronhacks.com :

https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/

The major difference is the use of RS485.

I have written code and tested it on an "UNO" which worked perfectly with more than one ModBus Slave Simulator under windows, including DAQ Factory which is a professional package used in actual industry.

# Answer
> 0 votes
## This is an awesome Modbus slave and Master Library

Required this library \<ModbusRtu.h\>

```
#include <ModbusRtu.h>
unsigned long TIME = 0;
unsigned long LASTTIME = 0;
unsigned long INTERVAL = 5000;

int i = 0;
// data array for modbus network sharing
uint16_t au16data[16] = {
  3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : serial port
 *  u8txenpin : 0 for RS-232 and USB-FTDI
 *               or any pin number > 1 for RS-485
 */
Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

void setup() {
  Serial.swap();
  Serial.begin( 19200 ); // baud-rate at 19200
  Serial1.begin( 19200 );
  slave.start();
}

void loop() {

  if ((millis() - TIME) > INTERVAL) {
    i++;

    if(i == 16){
      i = 0;

      for (int ii = 0; ii < 16; ii++)
      {
        au16data[ii] = 0;
      }
    }

    au16data[i] = 1;

    TIME = millis();
  }

  slave.poll( au16data, 16 );
}

```

---
Tags: modbus
---


# Question
Title: localtime - executing one after the other- different time_t, but getting same results
When I try to comapre 2 `time_t` values I get unexplained behavour

```
time_t t = 12345;
time_t T = 67890;
struct tm *tm = localtime(&t);
struct tm *Tm = localtime(&T);

    char timeStamp[40];
    sprintf(timeStamp, "(1) %04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    Serial.println(timeStamp);
    sprintf(timeStamp, "(2) %04d-%02d-%02d %02d:%02d:%02d", Tm->tm_year + 1900, Tm->tm_mon + 1, Tm->tm_mday, Tm->tm_hour, Tm->tm_min, Tm->tm_sec);
    Serial.println(timeStamp);

```

I get the exact same date.

When commenting out one of each set, I get the correct answer for each one.

Workaround I did was, but i'm sure there is an elegant way to overcome:

```
        time_t t = 12345;
        time_t T = 12345;
        struct tm *tm = localtime(&t);
        uint8_t now_month = tm->tm_mon;
        uint8_t now_day = tm->tm_mday;

        struct tm *Tm = localtime(&T);
        uint8_t save_month = Tm->tm_mon;
        uint8_t save_day = Tm->tm_mday;

        if (now_month == save_month && now_day == save_day)
        {
        }

```

# Answer
> 1 votes
From the manual page of `localtime()` (emphasis mine):

> The `asctime()`, `ctime()`, `gmtime()`, and `localtime()` functions shall return values in one of two static objects: a broken-down time structure and an array of type `char`. **Execution of any of the functions may overwrite the information returned in either of these objects by any of the other functions.**

As a solution, I suggest you take a copy of the `struct tm` used by `localtime()` to store its result, rather than keeping a pointer to it:

```
struct tm tm = *localtime(&t);
struct tm Tm = *localtime(&T);

```

---
Tags: time
---


# Question
Title: USB serial communication arduino nano and jetson nano
I want to communicate between Jetson nano and arduino nano through serial.

I wrote a simple script to test functionality but I receive strange data

here is the arduino code

```
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

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

  Serial.println("work fine");
  delay(10000);
}

```

and this is the python code run on jetson nano

```
import serial
import time

arduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

while True:
  try:
     data = arduino.readline()
     if data:
        print(data)
        print('Hi Arduino')
  except:
     arduino.close

```

the output is

```
b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n'
Hi Arduino

```

if tried different baud rates but nothing change.

when is use serial monitor on windows it works fine.

# Answer
> 2 votes
I also belive its to do with the following line,

```
 data = arduino.readline()

```

Try the following,

```
while True:

try:
     arduino.flushInput() // Clear buffer

     data = arduino.readline()

     // decode the bytes into str format, 'utf-8' arg should work
     data.decode('utf-8')

     // strip the \r\t in the str output
     data.strip()
     if data:
        print(data)
        print('Hi Arduino')
  except:
     arduino.close

```

See if this resolves your problem.

Note: I used an ESP32 and python script with the above-mentioned changes and it worked for me.

Also, as mentioned in the comment section some of the information might be missing in the output `'b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n'` this is not something reproducible for me. Just for reference my byte string output without the modifications was `b'work fine\r\n'` not `'b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n'`

* double-check Arduino write speed,
* double-check python serial connection baud rate,
* include the py script correction

see if this helps resolve your problem.

# Answer
> 0 votes
This stackoverflow question/answer implies that .readline() needs to be converted to a string.

```
import serial
ser = serial.Serial("COM11", 9600)
while True:
     cc=str(ser.readline())
     print(cc[2:][:-5])

```

I agree w/one of the comments to that answer that it might be better written as:

```
import serial
ser = serial.Serial("COM11", 9600)
while True:
     cc=str(ser.readline())
     cc=cc.decode("utf-8")
     print(cc)

```

---
Tags: serial, arduino-nano
---


# Question
Title: Arduino not running code without connection to PC via USB
I have an Arduino UNO and esp8266 connected to it. Both devices has separate power lines. Each connected via USB cable, for Arduino USB used as power line and standard firmware uppload line, for esp8266 only as power suppli line. If I connect all to computer's USB ports, everything working fine. But, if I connect Arduino to separate charger that has USB port, then Arduino not running code. I can see it by Serial interface work, because code using it intensively, and when I'm turning Arduino on the RX and TX lines are down all the time, that I think indicates, that code is not running, and Arduino in boot mode, somehow.

I've made a search through same issues and nothing helped from theirs suggestions. I tried to pull RX line to GND through resistor, to make sure that there are no noise on the line, added capacitors for power supply line, to make exclude pulsations on the line. But nothing helped.

Arduino not running code independently from esp8266. I tried to run Arduino separately, without any other connections, but it not helped. Still not running.

# Answer
> 1 votes
This problem happened to me when I first started dealing with electronics.

Power supplies connected to the AC line usually have an "isolated transformer" inside them. What this does is both to lower the AC voltage down to a more operable AC voltage (which is then rectified to DC voltages) and also protect the user/equipment/(your house) in case of failure of the power supply (AC 230/110 V will seriously damage you!). You see, the transformer's output is "isolated" from the AC line.

Because of this, every power supply connected to the AC line has an "isolated/separate" GND and VCC level. So, if you wanted to power and use two or more PCB's together using separate power supplies, then you need to connect all of their (power supplies) GND's together so that you have a "common ground".

In your case, powering both "Arduino UNO and esp8266" from the same computer works because the computer is fed from a single power supply and that the computer's GND wires on the USB line are "common" i.e. not isolated.

When you power your Arduino from a separate supply, your Arduino and esp8266 has a different GND level so the RX and TX line between them must be floating. To solve your issue, connect a wire from Arduino GND port (it is next to Analog read pins) to Esp8266 GND pin (somewhere suitable, of course).

# Answer
> 1 votes
Have you made sure that the ground of both the arduino as well as esp8266 are connected together? Also since you are using esp8266 you must have connected it to rx and tx pins. Make sure you remove it while uploading the code and connect it afterwards.

# Answer
> 0 votes
I believe this is happening because of electrical interference between wires. If you are running somewhat long wires (100mm or longer), every wire you run acts as an antenna that can either transmit or receive singles to/from other close wires. If you separate your wires or better yet, shield your data wires from each other, your issues should resolve.

Signals out of an Arduino board are very weak and are easily susceptible to interference from your environment such as motors, radio waves, wifi, or even a microwave oven running.

Either shield your data wires, make your wires shorter, or add circuitry that can transmit/receive signals over long distances, even if it's only 100mm. At 3.3volts with very low amps doesn't take much to noise up your data signals.

Hope this helps!

---
Tags: esp8266
---


# Question
Title: integer overflow in expression of type 'int' results
i need to wake up my ESP every 60 min to read some data and post it to server, all process working fine when i use numbers of minute below 60 (converted in microsecond x 1000000) but when i use 60 min above i get the following message:

> src/main.cpp:137:49: warning: integer overflow in expression of type 'int' results in '-694967296' \[-Woverflow\] esp\_sleep\_enable\_timer\_wakeup(TIME\_TO\_SLEEP * uS\_TO\_S\_FACTOR);// set up next wake up after 30 sec

How can i make my ESP wake up every 60 min or above?

simplify code:

```
// for awake and sleep
#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP  60 // minute

void setup(){
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 60 * uS_TO_S_FACTOR);// error if time to sleep more than 60 min
}

```

# Answer
> 1 votes
Change that line to:

```
esp_sleep_enable_timer_wakeup((uint64_t) TIME_TO_SLEEP * 60 * uS_TO_S_FACTOR);

```

That forces the compiler to do 64-bit arithmetic on the constant rather than defaulting to "int" arithmetic.

---
Tags: c++, esp32, sleep, integer
---


# Question
Title: HC-05 Bluetooth module; two serial ports, COM4 and COM5
I'm learning how to use the Arduino HC-05 Bluetooth module. After pairing to it with my laptop I saw that I was getting two serial links, COM4 and COM5, as can be seen from the picture below.

On COM4 everything is working fine, but on COM5 nothing is happening. Can somebody explain why this is so?

NOTE: I only have one Bluetooth device (the HC-05).

# Answer
I found this answer in Microsoft Technet helpful:

> * when connecting your terminal program to the first you are actually instructing Windows to attempt to establish the Bluetooth connection to the remote paired device, and if the connection is established the RFCOMM channel will be opened for the exchange of data
> * when connecting your terminal program to the second you are actually instructing Windows to load the SPP SDP record and to remain waiting for incoming connections from the remote paired device.
> 2 votes

---
Tags: arduino-uno, serial, bluetooth, hc-05
---


# Question
Title: Difference between (*(volatile unsigned int *) and (volatile unsigned int)?
I have been watching tutorials on **STM32 bare metal programming**. I couldn't understand the purpose of the below code

```
 #define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + AHB1EN_R_OFFSET))

```

and why it's different from

```
#define RCC_AHB1EN_R (volatile unsigned int)(RCC_BASE + AHB1EN_R_OFFSET))

```

I understand `(volatile unsigned int *)` is used to typecast any data, so it code will get its address value, not the data itself, then adding `(*)` will pick the data value of the address. I know why volatile is used to tell not to optimize this code for this data.

That's my basic knowledge of pointers, if I wasn't right till now please correct me.

**So my question are**

1. Why and what's the purpose of typecasting the data to address(pointer) and then use its value?
2. Why not we directly use the value itself (of course with volatile typecasting) like

`#define RCC_AHB1EN_R (volatile unsigned int)(RCC_BASE + AHB1EN_R_OFFSET))`

3. If we can use whichever we can, are there any benefits of one over the other?

# Answer
> 2 votes
Judging from the context, `RCC_BASE` seems to be a preprocessor macro that expands to the base address of some peripheral called “RCC”, and `AHB1EN_R_OFFSET` a similar macro for the offset of the `AHB1EN_R` I/O register relative to this base address. Then,

```
RCC_BASE + AHB1EN_R_OFFSET

```

is the memory-mapped address of the register. This address is just a number. If you cast it to `volatile unsigned int`, you still get the same number. If you want to access the I/O register, you have to tell the compiler that this number is actually an address (i.e. the numeric value of a pointer), and then access the memory bus at that address (i.e. dereference the pointer):

* `(volatile unsigned int *)` converts the numeric value to a pointer (because of the `*`), that points to a `volatile unsigned int`
* the `*` at the front of the macro dereferences the pointer and thus performs the actual access to the I/O register.

# Answer
> 1 votes
In the first line, RCC\_AHB1EN\_R is a pointer to location. you got that from the casting.

#define RCC\_AHB1EN\_R (\*(volatile unsigned int \*)(RCC\_BASE + AHB1EN\_R\_OFFSET))

In the second line, RCC\_AHB1EN\_R holds a base address which is an integer.

#define RCC\_AHB1EN\_R (volatile unsigned int)(RCC\_BASE + AHB1EN\_R\_OFFSET))

hope this give you clarity?

---
Tags: pointer, stm32
---