text:
How to set ALPN ProtocolName when negotiating SSL using ArduinoBearSSL
I am trying to set up an Arduino MKR Wifi 1010 to push MQTT messages to AWS IOT. I am following this tutorial https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-an-arduino-mkr-wifi-1010-to-aws-iot-core-a9f365 but I run into problems when the standard (secure) MQTT port (8883) seems to be filtered out somewhere between me and AWS. So I try to switch to 443, but AWS advises that you have to use the TLS extension ALPN and set ProtocolName to to "x-amzn-mqtt-ca" (see https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html).
I am at a loss how I am to do this in ArduinoBearSSL (https://github.com/arduino-libraries/ArduinoBearSSL).

Are you 100% sure your network drops conenctions between you and AWS on port 8883? You shouldn't work on a workaround for the wrong problem. What entitity drops your packets? Can you do something against that?

Also, bearssl already has the ALPN function, see https://github.com/arduino-libraries/ArduinoBearSSL/blob/555ec30550cfc7bc6ddf5739cd999e314a6e4f0d/src/bearssl/bearssl_ssl.h#L1293-L1328. You can set give br_ssl_engine_set_protocol_names a list of strings, but you would need to modify your MQTT client to call that function.


text:
Problem to Setting up i2c OLED wemos D1 mini shiled (64*24)
Hi
I used this shield before well. But it didn't work when I wanted to work with him last night!
this is my wireing :

Now I want to know how to test that it is healthy? Is i2c address missing or not?
I tried this code to find i2c address but no answer appeared on Arduino Serial monitor !! nothing ..
and i uploaded any more example code on Uno but OLED not worked .
//     ~~~~~~~~~~~ i2c Address Scanner ~~~~~~~~~~~

#include <Wire.h>

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

while (!Serial) {}

Serial.println ();
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;

Wire.begin();
for (byte i = 8; i < 120; i++){
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0){
  Serial.print ("Found address: ");
  Serial.print (i, DEC);
  Serial.print (" (0x");
  Serial.print (i, HEX);
  Serial.println (")");
  count++;
  delay (1);
   }
  }
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
  }
  void loop() {}

.
   .
What is the problem ?

As the Wenos D1 is a 3.3V device and the Uno a 5V device, you might get in trouble when using I2C between them without level conversion

When you write "nothing", do you mean, that you really see nothing on the serial monitor, not even the "I2C scanner. Scanning..." message?

I mean it doesn't find an address and therefore doesn't show anything as an address.@chrisl

Does this mean if I use 3.3v the problem will be resolved? Can you tell what connection the i2c has to the supply voltage?@chrisl

whats this mean the 3.3v ground must be the same for both until i2c connections is done! if is 5v , what happen doesnt work i2c connections? @chrisl

I2C has to do with the supply voltage, that the lines are pulled up to the supply voltage. The Uno pulls up to 5V, the OLED shield to 3.3V. Depending on how exactly the I2C protocol is implemented in detail on both sides (which sometimes breaks the rules of the interface definition), there might flow a big current through the lines, because of the different voltages. Also it might be, that the OLED board cannot tolerate 5V. It might break. You might need a bidirectional level converter (or build one yourself with 2 MOSFETS)

The main problem is, that the module does not get any supply voltage. You connected the Unos 5V to the OLED boards 5V. But this pin doesn't seem to be connected on the OLED shield. It is marked with 5V there, because this board is a shield to be stacked onto the Wemos D1. When you do this, you have 5V on this pin from the Wemos and can access it on the OLED shield for adding further components. (This is the principle of shields. Making even unused pins available on the shield, so that these pins don't get covered by the shield)
The shield needs to be supplied through the 3.3V pin, as it is a 3.3V device and it does not have an own voltage regulator (see the schematics of the shield).
Thus the shield cannot be found, because it is not turned on. It does not have a supply voltage.

That said, you may also get into trouble because of the communication voltage. The Uno works with 5V on the I2C lines, while the OLED shield works with 3.3V. The shield might get damaged by the higher voltage. The schematics the shield don't mention part names, so I cannot know, if they are 5V tolerant (there are 2 ICs in the schematics).
If the shield is not 5V tolerant on the I2C lines, you need to use a bidirectional level converter for both lines (or you can build your own with 2 MOSFETS for each line).

Yes you're right. I connected the 3.3v to the OLED , upload a sketch on Uno and OLED worked.@chrisl

source: Stack Exchange

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

sort: votes


text:
How to get text to flash on ssd1306 i2c screen
I am trying to alternate a string back and forth on the SSD1306 oled screen.
So I want the display to show "test1" for 0.5 seconds, then "test2" for 0.5 seconds, repeating. the code below is just showing "test1" for 0.5 seconds then going blank...
I am using a ssd1306 128_32 i2c screen, and using the adafruit library.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

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

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

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);

  display.setTextSize(4);             // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);

}

void loop() {
 testdrawstyles1();
 testdrawstyles2();
}

void testdrawstyles1(void) {
 display.clearDisplay();
 display.print(F("test1"));
 display.display();
 delay(500);
}

void testdrawstyles2(void) {
 display.clearDisplay();
 display.print(F("test2"));
 display.display();
 delay(500);
}

Perhaps you have to reset the cursor. I don't know if clearDisplay handles that for you.  Could you please try: display.setCursor(0,0); above each print statement. Perhaps, actually you print the text to "nirvana".

That did it! Thanks! Convert your comment to an answer please :)

As approved by the OP, the error was caused by not having reset the cursor to a visible position on the display. The text was written outside of the OLED.
It seems as the clearDisplay() method does not reset the cursor.
The solution is to change the following methods
void testdrawstyles1(void)
{
  display.clearDisplay();
  display.setCursor(0,0);
  display.print(F("test1"));
  display.display();
  delay(500);
}

void testdrawstyles2(void)
{
  display.clearDisplay();
  display.setCursor(0,0);
  display.print(F("test2"));
  display.display();
  delay(500);
}

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


text:
Adding WiFi to my Arduino Keypad Lock
I'm a really passionate beginner with arduino and electronics and I've built a Keypad lock for my room's door (inside the house).
I've used an arduino that activates a motor using a transistor to open the door if the correct pin is entered.
I want to add wifi control to my project. I have a few transistors, relays and ESP01s lying around for the upgrade. I want to use the blynk app and use the ESP01 independently without disturbing or modifying the arduino code. I'll program the ESP01 directly.
These are my requirements:
-A failsafe so I can open the lock via blynk if I forget the pin
-A kill switch that will turn off the arduino if I suspect somebody knows my PIN.
These are my ideas:
-Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected? By doing this can I control the transistor to switch the motor via both the arduino and the ESP 01?
-Can I put a relay module between the arduino and the battery pack and connect it to the ESP? I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?
Any suggestions and ideas about how to go about this will be highly appreciated.

Can I directly connect an ESP GPIO pin to the base of the transistor where the arduino is connected?

No. You will effectively be connecting two outputs together, and that is very bad.
Instead you will need to add a second transistor in parallel to the first - one controlled by the Arduino and one controlled by the ESP-01.

Can I put a relay module between the arduino and the battery pack and connect it to the ESP?

Sure. No problem with that.

I will connect the relay so that it will disconnect power to the arduino only when powered on. Is this a viable solution for a kill switch?

As long as the kill switch doesn't also shut off power to the ESP-01 - otherwise it will just switch on again straight away...

Thanks a lot. Can you please tell me about the parallel transistor arrangement in more detail? Also, how do I operate a 5V relay using 3.3v ESP01? Is it ok if I power the relay separately from the battery pack and only connect the signal pin to the ESP8266?

You can't drive a 5v relay from any microcontroller. If you have a relay module, not a relay, then it will most probably work. Otherwise you will be building a transistor driver circuit regardless of the voltage.


text:
Communication between arduino nano and MCP3424 over I2c pt. 2
I'm am completing a project of mine that uses an MCP3424 i2c 18bit ADC and an arduino nano to measure temperature with an NTC thermistor but am having trouble with the arduino wire library. This is my first project using i2c so I'm not very knowledgeable about the subject but I have rigorously read the datasheet of the MCP3424 that can be found at (http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf) and tried many different ways to get it working. Also I'm new to posting on this stackexchange so pardon me if my syntax and what not is not right(I'm doing my best). Here is the code I have so far that is on my arduino.
#include<Wire.h>
//#include<LiquidCrystal.h>
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define MCP 0x6E //Device will output conversion data (7 bits, device address. 1 bit, Read/Write mode)
#define CH1 0x8c //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define CH2 0xac //channel 2
#define CH3 0xcc //channel 3
#define CH4 0xec //channel 4

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  //lcd.begin(16, 2); not used yet
  Wire.begin();//Initiate Wire library
}

void loop() {
  // Read data from
  int pins[] = {CH1, CH2, CH3, CH4};
  long results[] = {0, 0, 0, 0};
  for (int i = 0; i < 4 ; i++) {
    results[i] = ReadMCP(pins[i]);
    Serial.print(i+1);
    Serial.print(": ");
    Serial.print(ReadMCP(pins[i]));
    Serial.print(" ");
    delay(500);
  }
  Serial.print("\n");

}
long ReadMCP(int channel){
  //conversion takes the three bytes and converts to number between 0 and 131071
  int x, y, z;
  long result = 0;

  Wire.beginTransmission(MCP);//begin transmission with ADC in Write mode
  Wire.write(channel);//configure the ADC with settings found in either CH1, 2, 3 or 4
  Wire.endTransmission();
  //delay(500);
  Wire.requestFrom(MCP, 3);//request 6 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  y = Wire.read();
  z = Wire.read();

  if (x>1) {
    if (x%2){
      result += (1 * 65536L);//x * 65536 = x * 2^16
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }else{
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }

  } else {
    result += (x * 65536L);//x * 65536 = x * 2^16
    result += (y * 256L);//y * 256 = y * 2^8
    result += z;
  }
  return result;
}

My program reads the measurements from each of the 4 channels of the ADC and prints them in the serial monitor.
The issue I am having is that when this code is run without the "delay(500);" function in the ReadMCP() function my measurements from each channel of the MCP3424 are in the wrong place. It prints the measurement from channel 1 as channel 2, the measurement from channel 4 as channel 1 and etc. However, with the delay between endTransmission() and requestFrom() the values are in the correct place. I have looked all over the datasheet and experimented a lot with the issue but cannot see what is causing it. Does anyone know why?
For reference when I have something to measure attached to channel 2 the output without the delay is
1: 131071 2: 131071 3: 66891 4: 131071
and with the delay is
1: 131071 2: 66843 3: 131071 4: 131071

You have to wait for the conversion to be complete. Check the RDY bit as detailed in the datasheet.

Don't leave the unused channels floating...you may read random values caused by noise or, worse, get crosstalk from adjacent channels. Tie unused channels to ground or some known reference voltage.

Why do you read MCP a second time Serial.print(ReadMCP(pins[i])); instead of using the the result you received 3 lines above (results[i] = ReadMCP(pins[i]);)?


text:
Connecting Audio Jack to Arduino
So I started working on a project of mine that is mostly software based which I have no problems with, but it includes electronics too. Where I am still learning a lot. Anyways, I have been trying to figure out why I couldn't properly communicate over serial to a hardware device over serial with my Arduino. Basically, I am connecting my hardware device to the Arduino using an Audio Jack.
The hardware device is running on 3.3v and the Arduino at 5v, which is probably the issue. But
Here the current Wiring:
[
Audio Cable:

Rx = Green Wire
Tx = White Wire
GND = Blue Wire

I would really appreciate if someone helps me out with the following questions:

Is ground connected to where it's supposed to be?
Is the voltage a problem? If so, what kind of converter should I add?

Regards.

Define: "talk".

Communicating over Serial. I just want to be sure I am not missing something obvious and that the cable is not the issue.

What is the "hardware device" you are "talking" to with that cable?

you've connected Blue wire, which you nominated as GND to a socket on the arduino that is labelled GND - so, yes, that blue wire is connected to GND - of course, since your three wires seem to be connected to a lump of what looks like chewing gum, there's no way to know if the blue wire is connected to the right place

if voltage is an issue, you want to look for a logic level converter

@JaromandaX, lol,  possibly conductive chewing gum

It's blue tack, and yeah it is connected.

@JaromandaX Where would I place it? I was worried that GND would have an voltage issue.

erm, where would you place the logic level converter? at a guess, on the logic level connections

This is something completely new, I'll do my studies on it. Thanks a lot.

Upvoted for the interesting idea to use an audio jack for Rx/Tx.

Assuming your hardware device wasn't damaged by feeding a 5V signal into it. You need to lower the voltage of the Arduino's TX pin. I'd suggest using a voltage divider (this only requires two resistors). Also keep in mind that with serial communication, you need to connect the Arduino's TX pin the the devices RX pin (using the voltage divider). And the Arduino's RX pin to the devices TX .pin.


text:
File.read() always returns -1
I'm trying to print a txt file from an SD card to a SSD1306 using the u8x8 library.
Here's the current code:
#include <SD.h>

#include <Arduino.h>
#include <U8x8lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

  U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

/*
  This example will probably not work with the SSD1606, because of the
  internal buffer swapping
*/
#define maxChar  128
#define rows 8
#define cols 16

File myFile;
int x = 0;
int y = 0;
char c;

void setup()
{
  /*Serial.begin(9600);
  Serial.print("Initializing SD... ");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");*/

  u8x8.begin();
  delay(500);
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);

  myFile = SD.open("target.txt", FILE_READ);
  u8x8.clear();
  u8x8.print("ciao");
  u8x8.print(myFile.read());
  delay(2000);
  printNewSet();
}
void loop()
{

}

void printNewSet()
{
  u8x8.clear();
  x = 0;
  y = 0;
  while (myFile.available() && y<rows)
  {
    c = (char) myFile.read();
    if (c == '\n') c = 'a';
    u8x8.print(c);
    stepCoords();
  }
}

void stepCoords()
{
  x++;
  if (x >= cols) newLine();
}
void newLine()
{
  u8x8.print('\n');
  x = 0;
  y++;
}

The function printNewSet() is supposed to print a batch of characters until either the file ends or the display limit is reached.
The file displayed correctly until i switched from while(myFile.available()) u8x8.print( (char) myFile.read()); to printNewSet(), at which point myFile.read() only returns -1 and myFile.available() is always false.
What is going wrong?
EDIT: While debugging i discovered that myFile fails to be initialized. Am I running out of memory?

what Arduino and what are the reported memory usage values?

I'm on an Uno with 54% rom and 62% ram usage

I had accidentally commented out the SD initialization along with the serial initialization. After uncommenting it it works correctly


text:
Slow refresh rate on I2C OLED screen
I'm trying to create a small handheld console with 6 buttons and an I2C 0.96" OLED display:
https://i.sstatic.net/gWqZP.jpg
The directional buttons use the analog pin and different resistors technique to save space while the two remaining buttons use a digital pin each.
However, despite using the same libraries as other projects, the sketch seems to run very slowly, resulting in a lowered screen refresh rate.
Here is the code:
#define wid 64  // Defines half of the width of the screen for graphic reference
#define hei 32

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display;  // Create display

int av;
const float sp = 3;
float pos[2]={0,0};  // Cursor position

void setup() {
   delay(100);  // Gives the screen time to setup
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
   display.clearDisplay();
   display.setTextColor(WHITE);
   display.display();   // Clears the screen of any remaining images
  }

void loop() {
  av=analogRead(A0);  // Reads the directional input
  av=inputRefine(av); // Assigns it to a direction
  switch (av)         // Changes the cursor position accordingly
  {
    case 1:
    pos[1]-=sp;
    break;

    case 2:
    pos[0] += sp;
    break;

    case 3:
    pos[1] += sp;
    break;

    case 4:
    pos[0] -= sp;
    break;
  }
  display.clearDisplay();

  display.setCursor(5,5);
  display.print(millis());  // Prints the system time on the corner of the screen

  display.drawCircle(wid + pos[0], hei + pos[1], 5, WHITE);  // Draws a circle on the cursor position
  display.display();
  }

int inputRefine(int av)
{
  int a=0;
  if (av>500&&av<600) a=2;
  else if(av>1000) a=3;
  else if(av>920&&av<950) a=4;
  else if(av>680&&av<720) a=1;

  return a;
}

What is slowing the execution down?
EDIT: Even commenting out any unnecessary line doesn't remove the lag
EDIT 2: The problem might reside in the screen itself. Unfortunately, I don't have a backup one. I'll order one as soon as possible and test this theory.

I'd suggest using int instead of float for float pos[2]={0,0};. I'd suggest adding some code that measures how many ms each part of your code uses, and prints it to the serial console.

Here's a great way to debug this kind of thing, especially since the sketch is pretty simple. Comment out everything but the lines which update the display. Leave them in using dummy values for pos. Now you know how fast it can update. Then add things back, one by one, and when it slows down you'll know where the problem is. Also, I second @Gerben's comment about floats - never use them on this kind of processor unless you absolutely have to; they're very very slow compared to integers.

I edited out any unnecessary lines and only left the display.print(millis());
 graphical command, but the lag still remains. Could it be a hardware issue?

Did you calculate the possible update frequency? Check what happens on "display.display();", https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.cpp#L886. How many bytes are transferred? How long time will this take?

I'm terribly inexperienced in how library source code is handled, but i did try to swap every piece of equipment involved in the console (the only piece i don't own at least two copies of is the screen) and the lag didn't cease. I think the screen could be the problem.

Solved by updating the Adafruit sdd1306 library and the Adafruit GFX library
EDIT: Why am I being downvoted?

Your question was down voted automatically by the "system" because there is very little content. I have up voted it to cancel the down vote. Please edit your answer to remove the EDIT and add just a little bit more information. Perhaps the version numbers of the libraries that didn't work and the version numbers that you are using now.


text:
Problems compiling with enum value PORT1-7
So I have this enum in a header file:
enum class ServoPort {PORT1 = 1, PORT2, PORT3, PORT4, PORT5, PORT6};

The trouble is that when I try to use it in the primary file (by doing MyClass::ServoPort::PORT1) I get a compile error:
exit status 1
expected unqualified-id before numeric constant

However, if I change the enum to be like so:
enum class ServoPort {PORT8 = 1, PORT9, PORT10, PORT11, PORT12, PORT13};

Then I do not get a compile error. What the heck? Can someone please shine some light on why this is happening?

Board: UNO R3
IDE: v1.8.5

Please add which Arduino board and IDE version.

If you are using an AVR based Arduino board it might be a conflict with the AVR header file pinsport.h.

@MikaelPatel done

Please see the file: arduino-xxx/hardware/tools/avr/avr/include/avr/portpins.h. If you really want to use these symbols you could undef them in your header file.

@MikaelPatel hmm, ok yeah I could see that being a problem if I was trying to do a #define PORT2 or something, but in this case I'm creating an enum that has a a member of that name. It seems to me that shouldn't cause a conflict? I'm from a Java background so maybe I don't know what I'm talking about...

The defines are pre-processed symbols before compiling. Your definition gives an illegal syntax when replaced. PORT1 = 1, PORT2, becomes, 1 = 1, 2.

@MikaelPatel I see, but shouldn't the preprocessor be smart enough to not do that?

Some reading: https://softwareengineering.stackexchange.com/questions/309389/what-is-the-origin-of-the-c-preprocessor, https://en.wikipedia.org/wiki/C_preprocessor, https://gcc.gnu.org/onlinedocs/cpp.pdf

Should add that #define, #undef, #include, etc, are not part of C/C++. It is the tools cpp, c pre-processor, that handles them before handling the resulting file to the compiler, cc/gcc.


text:
How to subtract the current analog value from previous one
I pretty new to the Arduino. I am working on project that find the power by reading your

Why would you want to subtract it? Do you maybe want to sum / integrate it over time to get total energy consumption?

I have this fourmal S=(V2-V1)/(P2-P1)

I have no idea what S is supposed to express here. But in the code you can take two measurements in predifened interval and then compute S.

S means the voltage sensitivity. Can you express what you said in code?

you do it by coding the sketch.

The formula should read P= U x I, V is for velocity and U is for voltage.

I think you need something like the following :
int lastTime;

void loop(){
  int thisTime = analogRead(A1);
  int diff = thisTime - lastTime;
  lastTime = thisTime;
  Serial.println(diff);
}


text:
Millis() is Not Working
I have a sketch that uses two timers using millis() from a library I created to keep time. The timers seem to be working correctly, but when I print the start time of each timer, it is clearly wrong.
E.g. the timer is set to run for 3 seconds. When I start the timer the first time, it reads that it started at 0. The next time I start the timer, right after it has finished running once, it reads that it started at 2 seconds. This should not be possible.
I have even tried timing it on my phone, and have seen the timerStart value read 5 seconds, when the sketch has been running for 10.
Does anyone have any idea what could be going wrong? Code below.
Here is the library's .h file:
#ifndef Timer_h
#define Timer_h

#include <Arduino.h>

class Timer {
  public:
    Timer(unsigned long timerLength);
    unsigned long timerStart;
    unsigned long timeElapsed;
    boolean isFinished = true;
    boolean timerStarted = false;
    void startTimer();
    void checkTimer();
  private:
    unsigned long _timerLength;
};

#endif

Here is the library's .cpp file:
#include <Arduino.h>
#include <Timer.h>

Timer::Timer(unsigned long timerLength) {
  _timerLength = timerLength;
}

void Timer::startTimer() {
  if (!timerStarted) {
    timerStart = millis();
    timerStarted = true;
  }
}

void Timer::checkTimer() {
  timeElapsed = millis() - timerStart;
  if (timeElapsed >= _timerLength) {
    isFinished = true;
    timerStarted = false;
  } else {
    isFinished = false;
  }
}

And here is part of my sketch code, where the timerStart value is wrong:
#include <Timer.h>

Timer breathTimer(3000);
Timer betweenTimer(1000);

// this part determines if a turbine is spinning or not
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);

  //if the turbine is spinning
  if (x == HIGH) {

    //start the breath timer
    if (betweenTimer.isFinished) {
      if (breathTimer.isFinished) {
        Serial.print("Breath Timer Started @ ");
        Serial.println(breathTimer.timerStart);
      }
      breathTimer.startTimer();
    }
  }
}

void setup() {
   Serial.begin(9600);
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   betweenTimer.isFinished = true;
}

void loop() {

  // check the breath timer
  if (breathTimer.timerStarted) {
    breathTimer.checkTimer();
    if (breathTimer.isFinished) {
      Serial.println("Breath Timer is Finished");
      betweenTimer.startTimer();
      Serial.println("Between Timer Started");
    }
  }

  if (betweenTimer.timerStarted) {
    betweenTimer.checkTimer();
    if (betweenTimer.isFinished) {
      Serial.println("Between Timer is Finished");
    }
  }
}

Sorry, I just edited my post to hopefully include all the necessary information

Where is Timer.h? Which arduino board do you use, or is this in a simulation?

Timer.h is included in the libraries folder along with Timer.cpp. I can include it here if you'd like to see it. I am running this on an Arduino Uno. Not a simulation.

I would like to see it, for example to see the type of the variables in the class.

I just edited my original post to include it

The c++ variable is a 'bool', we prefer that. The 'boolean' is made up by Arduino, we think that is silly. You have isFinished and timerStarted, yet the timer is busy or not. The class is initialized with isFinished as true, but the timer has not run yet. In the ISR you check the isFinished (which is true at start) and the value is printed. There is somehow a wrong way in the logic of that. Start over and first figure out what you want to know and what you want to do with the timer. Using the Serial library inside an ISR is never a good idea, try to move that to the loop() if possible.

It helps (for us and for yourself) if you explain in words what the purpose of the library is. You can add that to your question.

Why use an ISR when the timer is on milli-second level and the sketch uses seconds? The BlinkWithoutDelay-pattern would work just as well and would, in this case, be easier to get working. You could use the Timemark library to make this even easier. https://github.com/mikaelpatel/Arduino-Timemark


text:
Can HC-05 Continuously Stream data and read data at the same time?
I am trying to have my Arduino Stream an Analog Signal using Bluetooth Module (HC-05) while being able to read commands from another Micro-controller using the same Bluetooth Module.
Currently, I am using Arduino Uno for this.

What you are asking for really depends on the underlying hardware.  There are so many different Arduino platforms using so many different processors.  And you didn't even specify which Arduino you have.  You didn't even specify the data rate you require for your project.

If you're using SoftwareSerial then probably no, you can't. SoftwareSerial is strictly half duplex. You can't receive while sending, and if you're sending a lot then you never have time to receive.


text:
SPI Slave Programming for Arduino
In my application Arduino Due is configured as master and instead of the actual slave device I am making use of Arduino Uno as Slave.I will share the Master code which I have worked out. Can Anyone please help me with respect to slave code of Arduino Uno to display the data in serial monitor at slave side. Any Help With respect to this aspect will be greatly greatly appreciated.
#include <SPI.h>

SPISettings mySettting(125000, MSBFIRST, SPI_MODE0);
const uint8_t ss = 10;

void setup() {
  pinMode(ss, OUTPUT);

  SPI.begin();

  digitalWrite(ss, LOW);
  SPI.beginTransaction(mySettting);
  SPI.transfer(0x00);
  SPI.transfer(0x25);
  SPI.transfer(0x1C);
  SPI.endTransaction();
  digitalWrite(ss, HIGH);
}

void loop() {
}

Thanks for the reply.
Referring to the code attached below at the slave side as you have mentioned that HEX to be displayed in serial monitor window, Do I need to add the HEX at the master side I mean Do I need to load the Hexadecimal data (0x00251C) into HEX buffer??
Thanks in Advance
#include <SPI.h>

SPISettings mySettting(125000, MSBFIRST, SPI_MODE0);
const uint8_t ss = 10;

void setup() {
  pinMode(ss, OUTPUT);

  SPI.begin();

  digitalWrite(ss, LOW);
  SPI.beginTransaction(mySettting);
  SPI.transfer(0x00);
  SPI.transfer(0x25);
  SPI.transfer(0x1C);
  SPI.endTransaction();
  digitalWrite(ss, HIGH);
}

void loop() {
}

Please edit your question to add more information if required.

SPI.h library by default only support Master mode, the SPI.begin() will automatically set slave select (ss) pin to HIGH whether you have pinMode(ss, OUTPUT) in your setup() code or not and set the Arduino as an SPI master. This can be see on SPI library source code.
As the SPI library does not contain the functionality for slave mode, in order to use Arduino as a Slave, you will need to do some customised setup, mainly on 1) setting MISO as OUTPUT for slave to send data; 2) enable slave mode by setting the SPCR register; 3) enable interrupt when data is received. Here is an example for an SPI slave on Arduino.
#include<SPI.h>

volatile boolean received;
volatile byte receivedData;

ISR (SPI_STC_vect)        //Inerrrput routine function
{
  receivedData = SPDR;   // Get the received data from SPDR register
  received = true;       // Sets received as True
}

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

  pinMode(MISO,OUTPUT);   //Sets MISO as OUTPUT
  SPCR |= _BV(SPE);       //Turn on SPI in Slave Mode
  received = false;
  SPI.attachInterrupt();  //Activate SPI Interuupt
}

void loop()
{
  if(received) {
    SPDR = receivedData;    // send back the received data, this is not necessary, only for demo purpose
    received = false;
    Serial.print(receivedData, HEX);
  }
}

Thanks for the reply. Now the data is transferred on MOSI line at Master end. I would like to monitor that MISO pin incoming data in slave side. In the above code which you have posted once I define MISO pin and in place of HEX  in the last line of the code I don't want the HEX value to be written in the last line.  I just want to display the HEX value written at MASTER side. I don't want to include it at slave side.


text:
UNO R4, cannot open dfu device
New UNO R4 Minima,  Aduino IDE 2.3.2 AppImage,  Linux Fedora 40
Blink example compiles, but fails to upload.  Tried swapping cables, ports, rebooted, reset twice fails to produce a dfu port.
Here are the messages from the attempted build and upload:
Sketch uses 38780 bytes (14%) of program storage space. Maximum is 262144 bytes.
Global variables use 3940 bytes (12%) of dynamic memory, leaving 28828 bytes for local variables. Maximum is 32768 bytes.
dfu-util 0.11-arduino4

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Cannot open DFU device 2341:0069 found on devnum 14 (LIBUSB_ERROR_ACCESS)
dfu-util: No DFU capable USB device available
Failed uploading: uploading error: exit status 74

Well. how about that.  2 down votes, and my first post on arduino.  And, not a word of explanation or opportunity to respond.   I was hoping this group would be better than the other stack exchanges.    I stopped contributing in other forums and will stop here too.  That sort of behavior makes the forum unwelcoming and not worth my time.

The answer to the question is that the user does not have privileges to access the device.  It turns out that is the meaning of the exit status 74.
The solution, as kindly provided by ptillisch here is a missing udev rules file.
With an editor, echo, or any means you like, create this file:
/etc/udev/rules.d/60-arduino.rules

and give it the following single line of content:
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", MODE:="0666"

After creating this file, run the following two commands:
# sudo udevadm trigger
# sudo udevadm control --reload-rules


text:
lcd not display
is it my coding wrong or my board have problem because my lcd does not display anything.
here my coding
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 6, 2, 3, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C add 27 / 3F

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600); //
  lcd.begin(16,2);         // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.backlight();

}

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{

  lcd.setCursor(0, 0);
  lcd.print("HELLO");

  delay(200);

  lcd.setCursor(0, 1);
  lcd.print ("HI");

  delay(2000);

  lcd.clear();

  delay(2000);

  lcd.setCursor(0, 0);
  lcd.print("NICE");

  delay(200);

  lcd.setCursor(0, 1);
  lcd.print ("GOOD ");

  delay(2000);

  lcd.clear();

  delay(2000);
}

this is how i wirring it. what should i do?

You should add some Serial.println() to know if the program is running (or at least make a LED blinking in the loop). Looking at the dispay, it seems to me that either the iniialization is not correct, or the contrast is not set properly (I can't see the external potentiometer/resistor, but that particular display might not require it).

but when i compile and upload in arduino it did not show any error. can you tell me where should i add Serial.println(). because this is my first time using this.

Well, put some lines after each time you call an lcd method. For instance, after lcd.begin(16,2); you could write Serial.println("After lcd.begin()"); Etc. If, on the serial monitor, you don't see "After Begin", then even the begin method does not succeed. This might be due to incorrect wirings.

the black bars indicate that the lcd isn't correctly initialized.
check the hardware / connection and make sure that your software initializes it correctly.

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


text:
Arduino nano with 128x64px OLED freezing
I have an arduino nano, MCP3424 i2C ADC and a 128x64px i2C OLED display. The function is quite basic; the arduino receives information from the ADC and prints it to the screen as described in the code below.
#include <Fonts/FreeSerif9pt7b.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define MCP 0x6E //7bit MCP3424 address
#define CH1 0x8C //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define CH2 0xAC //channel 2
#define CH3 0xCC //channel 3
#define CH4 0xEC //channel 4

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  Wire.begin();//Initiate Wire library
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    //Serial.println("SSD1306 allocation failed");
    for(;;);
  };
  delay(2000);
}

  int count = 0;
void loop() {

 RunProgram();
 count++;
 Serial.println(count);

}

int RunProgram(){
  int pins[] = {CH1, CH2, CH3, CH4};
  long results[] = {0, 0, 0, 0};
  //int count = 0;
  for (int i = 0; i < 4 ; i++) {
    Serial.println(F("Reading from MCP..."));
    results[i] = ReadMCP(pins[i]);
    Serial.print(F("Read from MCP channel: "));
    Serial.println(i);
    //delay(500);
  }
 Serial.println(F("Printing results..."));
 PrintResults(results[0], results[1], results[2], results[3]);
 //count++;
 //Serial.print(count);
 Serial.print(F(" Results printed: "));
}

int PrintResults(long res1, long res2, long res3, long res4) {

  //PrintResults(); takes 4 long ints, divides the oled display into 4 segments and prints the results on screen

  display.clearDisplay();
  Serial.println(F("Display cleared"));
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(2, 3);
  display.print(F("Ambient"));
  display.setCursor(66, 3);
  display.print(F("Probe 1"));
  display.setCursor(66, 35);
  display.print(F("Probe 3"));
  display.setCursor(2, 35);
  display.print(F("Probe 2"));
  Serial.println(F("text printed"));
  display.setCursor(3, 15);
  display.print(res1);
  display.setCursor(3, 47);
  display.print(res3);
  display.setCursor(66, 15);
  display.print(res2);
  display.setCursor(66, 47);
  display.print(res4);
  Serial.println(F("results printed"));
  /*display.setTextSize(2);
  display.setCursor(3, 15);
  if (x >= 1000) {
    display.println(x, 0);
  } else if (x >= 100) {
    display.println(x, 1);
  } else {
    display.println(x, 2);
  }*/
  display.drawRect(0, 0, 128, 64, WHITE);
  display.drawLine(0, 32, 128, 32, WHITE);
  display.drawLine(64, 0, 64, 64, WHITE);
  Serial.println(F("Borders printed"));
  display.display();
  Serial.println(F("Display updated"));
  delay(50);
  return 0;
  Serial.println(F("Return printed"));
}

long ReadMCP(int channel){
  //conversion takes the channel from which the reading is to be taken from and returns a number between 0 and 131071
  int x, y, z;
  long result = 0;

  Wire.beginTransmission(MCP);//begin transmission with ADC in Write mode
  Wire.write(channel);//Write the settings and channel for the ADC to the wire buffer
  Wire.endTransmission();//Send information in the buffer to the ADC
  delay(300);//wait for the ADC to take reading ( only 3.75 samples per second, roughly takes 266 milliseconds per reading)
  Wire.requestFrom(MCP, 3);//request 3 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  y = Wire.read();
  z = Wire.read();

  //conversion of the three binary bytes to decimal
  if (x>1) {
    if (x%2){
      result += (1 * 65536L);//x * 65536 = x * 2^16
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }else{
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }

  } else {
    result += (x * 65536L);//x * 65536 = x * 2^16
    result += (y * 256L);//y * 256 = y * 2^8
    result += z;
  }
  return result;
}

The issue is, after a period of time (which so far has varied between 622 to 6 full loops of the program) the arduino freezes. I have found online that other people have experienced a similar problem. For example this page and this page this page seem to have others who are having the same issue. The fix offered on these pages, and others like it, were issues with memory. So I looked around for ways to reduce memory usage and came across this page. So I followed the advice and put all my strings in the F() function (or whatever it is, I'm not sure what it is or does) and segmented all my code into functions outside of the main loop. So I removed the majority of functions and variables from the main loop() function(before, all the functions in RunProgram() were in the main loop). However I am still encountering freezing issues. Can someone suggest reasons my arduino would freeze and ways to fix it?

Chances are it's the I2C communication that's locking up. I2C is not intended to be used over wires, and the internal pullup resistors in the MCU that are often used are far too high a value for proper I2C communication.  Add 1kΩ resistors between each of SCL and SDA and the 5V pin of your Arduino.

Thanks for the suggestion @Majenko. For clarification all three parts of the circuit are soldered on to perforated board and the longest wire run is a few centimeters at most. I tried your suggestion, I had 10k pullups added to my circuit and changed them to and tested 4.6k, 2k, 560 and 220 ohm pullups all which had no effect on the locking up. I then also tried with the 2k ohm resistors changing the Wire clock speed to 50,000, half the speed. Still same issue.

When the code is blocking, is at least one of the I2C lines (most probably the clock line) at low level? That would proof, that it is an I2C problem (since a released I2C bus has both lines at high level). If so, it is a difficult to debug problem. You can try to use another Arduino and try to mock one of the devices with it (so it sends the same data format, behaves about the same). Then check, if the problem goes away, if not try with the other device, then maybe with both devices replaced by Arduinos. Otherwise you would need an oszilloscope to analyse the data transmission.

@chrisl I removed the screen from the circuit and wired it in with just an arduino on a breadboard.  after the arduino and screen froze while cycling through a very simple display program I measured both the SCA and SCL lines which were both high while frozen. I don't have an oscilloscope, though I have ordered another OLED to see If I just got a bad screen.

@chrisl the screen by itself on the breadboard however is far more stable than on the circuit I made is there a way to find a difference between my circuit and the circuit on the breadboard

I just experienced the same problem. A simple Arduino Nano sketch printing "Hello World" lines to one of those small 128x64 OLED I2C monitors trough SSD1306AsciiWire class provided by SSD1306Ascii library would freeze randomly (freezing the whole sketch, not just ceasing to display). Class SSD1306AsciiWire communicates through Wire. And it appears that in my case I2C through Wire was getting stuck forever. In my case replacing the OLED monitor helped: after the replacement the whole thing started working fine (I'm still testing it though).

However, there's one peculiar thing: if I used SSD1306AsciiAvdI2c class from the same library instead of SSD1306AsciiWire, the first allegedly "defective" monitor would run the same sketch perfectly and flawlessly. No freezes or glitches of any kind. Class SSD1306AsciiAvdI2c uses it own implementation of I2C maser interface instead of relying on the native TwoWire Wire. So, it appears that there's some sort of sensitive moment in TwoWire implementation that makes it act up with some of these OLED monitors.

@AnT Interesting, for my specific case I just purchased another more expensive and obviously higher quality display and that solved the problem for me.

@Asyu7: You know, it is quite embarrassing, but I found the problem in my case: I simply forgot to call Wire.begin() before starting to communicate over Wire. Once I added a Wire.begin() call at startup, everything started to work perfectly. This is basically the difference between TwoWire and AvrI2c classes: AvrI2c apparently manages to self-initialize properly, while for the standard TwoWire making a call to begin() is the user's responsibility. Without Wire.begin() the Wire "kinda works" more-or-less... it might work with some devices and freeze with others.


text:
Communication between arduino nano and MCP3424 over I2c
I'm am completing a project of mine that uses an MCP3424 i2c 18bit ADC and an arduino nano to measure temperature with an NTC thermistor but am having trouble with the arduino wire library. This is my first project using i2c so I'm not very knowledgeable about the subject but I have rigorously read the datasheet of the MCP3424 that can be found at (http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf)
and tried many different ways to get it working. Also I'm new to posting on this stackexchange so pardon me if my syntax and what not is not right(I'm doing my best). Here is the code I have so far that is on my arduino.
#include<Wire.h>

#define ReadMode 0xDD //Device will output conversion data (7 bits, device address. 1 bit, Read/Write mode)
#define WriteMode 0xDC //Device expects config byte (7 bits, device address. 1 bit, Read/Write mode)
#define ConfigByte18 0x8c //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define ConfigByte16 0x88 //PGA = 1, SPS = 15, One-Shot mode, channel 1, initiate new conversion.

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  Wire.begin();//Initiate Wire library
  Wire.setClock(100000);//make sure clock speed is standard mode
  delay(500);//Allow boot up and settle of ADC
  Wire.beginTransmission(WriteMode);//begin transmission with ADC in Write mode
  Wire.write(ConfigByte18);//configure the ADC with settings found in "ConfigByte18"
  Wire.endTransmission();
  Serial.print("Everything worked\n");

}

void loop() {
  unsigned char x, y, z, a, b, c;
  //Serial.println("Bytes ready to be read:");
  Wire.begin();
  Wire.setClock(100000);//make sure clock speed is standard mode
  Wire.beginTransmission(ReadMode);//begin transmission with ADC in write mode
  Wire.requestFrom(0x6E, 6);//request 6 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  delay(10);
  y = Wire.read();
  delay(10);
  z = Wire.read();
  delay(10);
  a = Wire.read();
  delay(10);
  b = Wire.read();
  delay(10);
  c = Wire.read();
  Serial.print(x);//print bytes
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.print(z);
  Serial.print(", ");
  Serial.print(a, HEX);
  Serial.print(", ");
  Serial.print(b, HEX);
  Serial.print(", ");
  Serial.println(c, HEX);
  Wire.endTransmission();
  delay(1000);

}

So an explanation of my understanding: In the “void setup” section I begin transmission in write mode (see page 21 of datasheet to follow along with my explanation figure and table 5-3) in the begin transmission function I address the slave with 0xDC because the device address begins with 1101 (pre programmed) and then 110 as I have the two Adr pins tied to +5v and finally 0 as I want to change configuration settings. This translates to 0xDC in hexadecimal. Then I send the slave a byte of information for the configuration register (see page 18 section 5.2). I send 0x8C as I want my settings to be PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion. Which should mean I need to send the slave 10001100 or 0x8c. This communication then ends as “Any byte sent after this second byte will be ignored” according to page 21. Then in the loop I begin transmission the same way apart from now I open transmission in read mode which is 0xDD as the last bit (R/W bit) is now 1. I then request six bytes of information and read the six bytes. If you now go to page 23 of the datasheet you can follow along again. Here I should get three data bytes from the slave and every subsequent byte should be the configuration register settings repeated. For now I am uninterested in the first three data bytes as I first of all just want to know how to change the configuration settings. What gets printed by the arduino instead is three data bytes from the slave, as expected, and then three of the exact same value, also as expected as they should all be the configuration settings. What is being printed in the second three bytes is “90”. Not what I expected. Now I’ve tried to figure out what has happened (hard without an oscilloscope). 90 converted from hex to binary is 10010000 and I believe the default settings are (which can be found on page 18) 00001001 could this be the default settings if so can anyone tell me whats going on and how to fix it? Thank you in advance for the help and thank you for taking the time to read my problem.

do not initialize the library in every loop. remove begin and setClock. and requestFrom should not be wrapped in transaction

sorry transaction = beginTransmmition
endTransmmition

use a library. for example https://github.com/bersch/MCP3424

The problem is, that you misunderstood, how the Wire library handles addresses.
I2C uses an address byte, where the first 7 bits are the actual address and the last bit (Read/Write bit) dictates the direction of the communication. The Wire library gives you different functions for both directions (in your case: Wire.beginTransmission() for master write and Wire.requestFrom() for master read) and hides away the complexity of the Read/Write bit. So what you have to give as an address is the pure address of the device without the Read/Write bit. To write the configuration you used the address 0xDC, but the actual address of the device is 0x6E as you used it in the Wire.requestFrom() call.
Also in your loop() you try to start a master write with Wire.beginTransmission(), though you are starting a master read directly after it. Wire.beginTransmission() and Wire.endTransmission() are purely for master write transactions. So you should delete these lines here. For master read the call to Wire.requestFrom() and the corresponding reading is enough.
What happens in your code: In setup() you write the new configuration data to a wrong address (0xDC instead of 0x6E). The transmission fails, as there is most likely no device with this address at the bus, but you don't notice, since you are not checking the return value of Wire.endTransmission(), which would show an error code. Then in the loop() function you reinitialize and reconfigure the whole Wire library again, which makes no sense, as Juraj mentioned in his comments. Though it will only cost some cycles of computation time. Then the library get's set to master write mode (no actual I2C action here, just interal to the library) and then to master read mode (actual I2C action. The provided number of bytes get's read here from the slave). At the end you say to the library, that is should finish the master write transmission from before, which is not there anymore (since you've done a master read). So this will do nothing. Also you are doing many delays between the reads, which is not necessary. When the Wire.requestFrom() function returns, all the I2C communication is finished. The bytes, that could be received, are received and written into the libraries buffer. Wire.read() will only read the next value from the buffer, remove it from there and return the value. No I2C action at that point, so the delay(10) is useless
TL;DR:

Always use the correct address without Read/Write bit: 0x6E
Initialize and configure the Wire library only once in setup()
Remove Wire.beginTransmission() and Wire.endTransmission() from the loop() function, as you are only doing master read there.
Remove the delay(10); lines between the calls to Wire.read()

Thank you for the answer chrisl this clears up a lot! One more question if i may, to initiate a read from the MCP3424 I need to update a bit in the configuration register. Does that mean every time I want a reading I need to execute the three wire functions beginTransmission(0x6E), Wire.write() and endTransmission?

Yes, when in One Shot mode you need to always do beginTransmission(), write(), endTransmission(), requestFrom() and read() for every measurement. But as you currently are reading contineously from the ADC, you should consider to use the contineous measurement mode, so that the measurement is automatically started at a fixed interval and you only have to request the data from the ADC.

Okay I see how I could do that yes, but in the future I plan on reading from all 4 channels so I would have to change the config byte everytime and use all 5 commands every change anyway right?

Yes, when you change the channels on each request, you must use all the above commands to first set the correct config byte, start the conversion and then actually request the data.


text:
ESP32 OTAWebUpdater only works on mobile
I'm experiencing something strange. I opened the default ESP32 example "OTAWebUpdater" in the ArduinoIDE and modified just the network part (I created a soft AP instead). The problem is, when I connect my Android phone to the AP, I can OTA update just fine, but when I connect a laptop and try to update, it gives me an error saying "not found: serverIndex". The error occurs after selecting the .bin file and clicking the "update" button. I already tried with 3 different laptops. Any thoughts?
Below is the code:
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>

const char* host = "esp32";
const char* ssid = "OTAWebUpdater";
const char* password = "123456789";

WebServer server(80);

/*
 * Login page
 */

const char* loginIndex =
 "<form name='loginForm'>"
    "
"
        "
"
            ""
                "ESP32 Login Page"
                "
"
            "	"
            "
"
            "
"
        "
"
        "Username:	"
        "<input type='text' size=25 name='userid'>
	"
        "
"
        "
"
        "
"
        "
"
            "Password:	"
            "<input type='Password' size=25 name='pwd'>
	"
            "
"
            "
"
        "
"
        "
"
            "<input type='submit' onclick='check(this.form)' value='Login'>	"
        "
"
    "
"
"</form>"
"";

/*
 * Server Index Page
 */

const char* serverIndex =
""
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
   "<input type='file' name='update'>"
        "<input type='submit' value='Update'>"
    "</form>"
 "
progress: 0%
"
 "";

/*
 * setup function
 */
void setup(void) {
  Serial.begin(115200);

  // Connect to WiFi network
  WiFi.softAP(ssid, password);

  Serial.print("IP address: ");
  Serial.println(WiFi.softAPIP());

  /*use mdns for host name resolution*/
  if (!MDNS.begin(host)) { //http://esp32.local
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
  /*return index page which is stored in serverIndex */
  server.on("/", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", loginIndex);
  });
  server.on("/serverIndex", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", serverIndex);
  });
  /*handling uploading firmware file */
  server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      /* flashing firmware to ESP*/
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true to set the size to the current progress
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
  });
  server.begin();
}

void loop(void) {
  server.handleClient();
  delay(1);
}

Are you sure you wanted to use window.open('/serverIndex')? I would have thought document.location='/serverIndex' would be a better choice.

Just changed it, thanks.

Did it change the behaviour at all?


text:
What are these wires called?
I'm currently developing a quad copter for my school project and I am coming to the part where I am collecting all the parts before I assemble everything.
I have recently encountered a roadblock. I am going to solder an Arduino nano onto a strip board, but the problem is I cannot seem to find cables/wires to connect the nano to the module.
Excuse my ignorance, but where can I find these cables for soldering and what are they called?

Just wires? make sure they are copper and a smallish gauge and you'll be fine

"magnet wire" or "wrapping wire" is cheap and works well for bodging. ~30awg. old solid-core phone cables are another good source when on a budget.

If they are an intentional part of the design they are jumper wires. If they are to correct a mistake in the design they are bodge wires.
They aren't anything special, just wire. They look to be in the range of 24 to 30 AWG and PVC jacketed.
You can buy it in any electronic store.
You can also salvage it from things like old SCART cables and similar things.

If you want to wire your board with stranded wire, you can ask for NYAF and solder the edges with the tip. Otherwise you can ask for hook-up wires.
But if you are using breadboard, which i recommend you to use solid wire, you can ask it as wire wrap.
You can find them at an electronic store.

but where can I find these cables for soldering and what are they called?

hook-up wires.
pretty much any hardware stores should have it.

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


text:
use button to select variable
i have a need to use 3 buttons a a simple option/variable selector at sketch start up ...
Pretty much at startup , script must wait for button press ( one of 3 ) , when button is pressed , use that buttons predefined string value as a variable for the loop script further down .. if wanting to change the "variable" then a reboot is required ..
i know how to digital read in the buttons , but not sure how to
1) wait for one of the buttons to be pressed to then jump to main loop
2) Associate a "string" variable to each button
thinking about it i suppose a If/Else loop will be required for the Input 'wait" and then just if the digital input (button) is pushed then continue .. am i correct ?
Ideas or better way to do it ?
Thx
Greg

1) One solution is to create a function that loops repeatedly, eg while(1), until one of the buttons is pressed. It then returns the button "number", eg 0,1 or 2.
2) In C you would usually remember the index into a string table. So one solution is to store the button number in a global variable and use it to index a "string array", something like char * buttonStrings["B1","B2","B3"]; and to get the string for a button use buttonStrings[buttonNumber];

When I am searching for something inside a loop, I find that the
simplest thing to do is to just break out of the loop once I found it.
This was frowned upon in the days when structured programming was a hot
thing, but as long as it makes things simpler, you should not be ashamed
to break:
const int button_pins[] = {2, 3, 4};
const char * const urls[] = {"foo.com", "bar.org", "baz.net"};
const char * url;  // the selected URL

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

    // Configure input pins.
    for (int i = 0; i < 3; i++)
        pinMode(button_pins[i], INPUT_PULLUP);

    // Find first button pressed.
    int i;  // button index
    for (i = 0; ; i = i==2 ? 0 : i+1) {
        if (digitalRead(button_pins[i]) == LOW)
            break;
    }

    // The button index selects the URL.
    url = urls[i];

    Serial.print("Selected URL: ");
    Serial.println(url);
}

void loop() {}

The for loop above is written as an endless loop (no end condition).
The expression i = i==2 ? 0 : i+1 means: “if i is 2, make it 0,
otherwise make it i+1”. In other words, we are endlessly looping i
over 0, 1 and 2.
Now, it may well happen that you actually do not care about which button
was pressed once you have selected the proper URL. In this case, you can
use the URL pointer as a “flag” that tells you when you can end the
loop:
// First button pressed selects the URL.
for (int i = 0; !url; i = i==2 ? 0 : i+1) {
    if (digitalRead(button_pins[i]) == LOW)
        url = urls[i];
}

Where !url means “the URL has not been found”. This works because the
C runtime initializes url to zero, which is interpreted as false in
boolean context.
Addendum: If you are likely to add new button/URL pairs, you can
make this easier by structuring the list as an array of structs:
const struct {
    int pin;          // pin number
    const char *url;  // associated URL
} buttons[] = {
    {2, "foo.com"},
    {3, "bar.org"},
    {4, "baz.net"}
    // etc. just add to this list as needed.
};
const size_t button_count = sizeof buttons / sizeof buttons[0];

Then the search becomes:
for (int i = 0; !url; i = i==button_count-1 ? 0 : i+1) {
    if (digitalRead(buttons[i].pin) == LOW)
        url = buttons[i].url;
}

You can try this. The comments in the program explain quite well.
const int buttons[3] = {2,3,4}; // buttons pins

int butStatus = 0;

void setup() {
  pinMode(buttons[0], INPUT); // declaring pins as inputs
  pinMode(buttons[1], INPUT);
  pinMode(buttons[2], INPUT);

  while(butStatus<=0) //waiting for a button to be pressed
  {
    for(int i=0; i<3; i++) //running trough the 3 buttons
    {
      if(digitalRead(buttons[i]) == HIGH)
      {
        butStatus = i+1; //set variable to the button that has been turned on
      }

      else
      {
        butStatus = 0; //if there is no button press, keep the variable at 0
      }
    }
  }
}

void loop() {
  //variable butStatus is now equal to the button that has been pressed
}

Thanks , this looks good .. one question , for the variable .. i require the variables to be URL strings  (example www.google.com) , how can i map this ?? so something like button 1 = www.google.com , button 2 - www.yahoo.com , button 3 = somesite.com

use string urls[3] = {"www.google.com", "www.yahoo.com","www.somesite.com"}. Then you can call string something = urls[butStatus];.

perfect :-) let me go play :-)

Better make that string something = urls[butStatus-1]; butStatus is 0 for no button or 1-3 for a button pressed, you need to subtract one to get back to a zero based array index.

Your code can only sense the last button.

@EdgarBonet, mind explaining a bit...

If button 2 is not pressed, you butStatus = 0; and stay in the loop.

Did you see this? butStatus = i+1

canadiancyborg,  @EdgarBonet is correct: in your code as shown, the only way the while(butStatus<=0) loop can exit is if the third button is pressed, regardless of the state of the other two buttons. Get rid of the silly-error code else { butStatus = 0; }.  Also, in string urls[3] ... perhaps you meant to capitalize string


text:
Can Atmel Studio 6 Simulator simulate SPI?
I am trying to do PAL composite video output with Arduino Nano. I am using Atmel Studio 6, not the Arduino IDE. I am sending out the picture data via SPI. On the TV I could not see the text I tried to produce, so I tried to run my program in the Atmel Studio simulator (to use it as a logic analyzer). But in the resulting stimuli file I also do not see the MOSI pin changing.
I am using the A0 pin (PORTC bit 0) to send out the sync signal, that appears correctly in the output .stim file: PORTC changes exactly at the right time. But PORTB does not change at all.
My program can definitely be buggy, but that is another topic... the question is, can Atmel Studio Simulator simulate the SPI at all?

How is this even related to Arduino?

An IDE doesn't simulate SPI. I don't understand your question. My program can definitely be buggy - without posting any code your question is very vague.

No Atmel Studio cannot simulate SPI.
The fact that you are using SPI makes me think that you are using the MAX7456 IC or even the SparkFun On Screen Display Breakout which uses this same IC.
You can generate composite video just by using a few resistors and an Arduino.
I have found a number of sites on Google who have used the Arduino to output PAL composite video to display the Pong game on an old TV.

http://searle.hostei.com/grant/AVRPong/index.html
http://www.makeuseof.com/tag/how-to-recreate-the-classic-pong-game-using-arduino/
http://www.instructables.com/id/2-player-Pong-using-Arduino/
http://forum.arduino.cc/index.php?topic=8708.0
http://apcmag.com/arduino-project-7-build-a-retro-gamebox.htm/
http://electronics.divinechildhighschool.org/Home/electronics-spring-2012-1/arduino-pong

Arduino PAL output is bad, takes a LOT of processing power and doing overlays is even harder. Using MAX7456 is just a lot of easier, although you might have a few other problems with it.


text:
Arduino Pro Mini name in CMakeList.txt in CLion
I recently try to get my Arduino Pro Mini (5v 16mhz)running in Clion.
I tried to set up the CMakeList.txt but I get the following error:

Error:Can not find f_cpu in boards.txt for Arduino board ID (pro),
  aborting.

I used the following configuration:
set(${CMAKE_PROJECT_NAME}_BOARD pro)

In the boards text, located at C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt I found the following lines:
pro.name=Arduino Pro or Pro Mini

pro.upload.tool=avrdude
pro.upload.protocol=arduino

pro.bootloader.tool=avrdude
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F

pro.build.board=AVR_PRO
pro.build.core=arduino
pro.build.variant=eightanaloginputs

## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
## -------------------------------------------------
pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)

pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.16MHzatmega328.upload.speed=57600

pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0x05
pro.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

pro.menu.cpu.16MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L

So I'm wondering what Boardname to use, to get the Pro Mini working. Thanks in advance!

There is some pretty similar GitHub issue.

The problem here is that the Pro Mini comes in a number of variants for different voltages / speeds etc. The different variants are selected using a menu in the IDE.
CLion doesn't know about those menus, nor how to find the f_cpu from the right one for your board.
So there are two solutions:

Create your own board entry for the Pro Mini without the menu entries.
Use an earlier version of the IDE that has the Pro Mini boards as separate entries (basically any version before the menu system was created).

If you want the latest API then you will have to go route 1. That could be as simple as modifying the existing pro.* entries to remove the menu and replace that section with just the flags that are set by the correct menu (basically remove all the pro.menu.* entries except the ones for your board, then remove the menu.cpu.<whatever>. from each of the lines, as well as the entire menu entry name line.)
So you would basically change these lines:
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
## -------------------------------------------------
pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)

pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.16MHzatmega328.upload.speed=57600

pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0x05
pro.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

pro.menu.cpu.16MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L

to this:
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
## -------------------------------------------------
pro.upload.maximum_size=30720
pro.upload.maximum_data_size=2048
pro.upload.speed=57600

pro.bootloader.low_fuses=0xFF
pro.bootloader.high_fuses=0xDA
pro.bootloader.extended_fuses=0x05
pro.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

pro.build.mcu=atmega328p
pro.build.f_cpu=16000000L

and delete all the other pro.menu entries.


text:
Arduino IDE + ESP32 Webserver - how to redirect to root after click on button
I'm trying to use ESP32 + Arduino IDE to control a relay.
I've started by using the  library and the code below.
The problem I'm having:
after clicking on the button and activating the pin, if the browser is left like this, and then the page gets refreshed by mistake, the action will be repeated.
What I thought might help, is if for any click on the button, the pin activates, and then I get a redirect back to the root of the page. so refreshing will not pose any issue.
I've searched allover the internet and could not find anything conclusive, except for this piece of code, which doesnt seem to make any difference nomatter where I place it in the main code
client.println("HTTP/1.1 307 Temporary Redirect");
client.println("Location: /");
client.println("Connection: Close");
client.println();
client.stop();

and this is the main code:
// Load Wi-Fi library
#include <WiFi.h>

// Replace with your network credentials
const char* ssid     = "WalrusnTiny";
const char* password = "994483329I";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";

// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;

void setup() {

  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output26, OUTPUT);
  pinMode(output27, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output26, LOW);
  digitalWrite(output27, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /26/on") >= 0) {
              client.println();
              output26State = "on";
              digitalWrite(output26, HIGH);

            } else if (header.indexOf("GET /26/off") >= 0) {
              Serial.println("GPIO 26 off");
              output26State = "off";
              digitalWrite(output26, LOW);

            } else if (header.indexOf("GET /27/on") >= 0) {
              Serial.println("GPIO 27 on");
              output27State = "on";
              digitalWrite(output27, HIGH);

            } else if (header.indexOf("GET /27/off") >= 0) {
              Serial.println("GPIO 27 off");
              output27State = "off";
              digitalWrite(output27, LOW);
            }

            // Display the HTML web page
            client.println("<!DOCTYPE html>");
            client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("");

            // Web Page Heading
            client.println("
ESP32 Web Server
");
            // Display current state, and ON/OFF buttons for GPIO 26
            client.println("
GPIO 26 - State " + output26State + "
");
            // If the output26State is off, it displays the ON button
            if (output26State=="off") {
              client.println("
<button class=\"button\">ON</button>
");
            } else {
              client.println("
<button class=\"button button2\">OFF</button>
");
            }

            // Display current state, and ON/OFF buttons for GPIO 27
            client.println("
GPIO 27 - State " + output27State + "
");
            // If the output27State is off, it displays the ON button
            if (output27State=="off") {
              client.println("
<button class=\"button\">ON</button>
");
            } else {
              client.println("
<button class=\"button button2\">OFF</button>
");
            }
            client.println("");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable

    header = "";
    // Close the connection

    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

Any help would be greatly appreciated.
Thank you in advance.

Solved:
Just needed to add this code to every button press,
 client.print("");
 client.print("<meta http-equiv=\"refresh\" content=\"0;url=/\">");
 client.print("");

First probably mention this is too much overhead for a webserver
adding
include <WebServer.h>

you can handle those endpoints easily
See https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/
Basically:
setup() {
  ...
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
  ...
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status));
}

Anyway this is still wrong, as you end with same problem, /led1on renders as your main page
A better solution would be to use this endpoint handlers to set the variable and just redirect:
Here a complete solution
#include <WiFi.h>
include <WebServer.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "password";

// Set web server port number to 80
WebServer server(80);

uint8_t led1Pin = 12;
uint8_t led2Pin = 13;

bool led1State = LOW;
bool led2State = LOW;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  // Set outputs to LOW
  led1State = LOW;
  led2State = LOW;
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_root);
  server.on("/led/1/on", handle_led1on);
  server.on("/led/1/off", handle_led1off);
  server.on("/led/2/on", handle_led2on);
  server.on("/led/2/off", handle_led2off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP Server started");
}

void handle_root() {
  server.send(200, "text/html", sendHTML());
}

void handle_led1on() {
  led1State = HIGH;
  Serial.println("led1 state: ON");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led1off() {
  led1State = LOW;
  Serial.println("led1 state: OFF");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led2on() {
  led2State = HIGH;
  Serial.println("led2 state: ON");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led2off() {
  led2State = LOW;
  Serial.println("led2 state: OFF");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_NotFound() {
  server.send(404, "text/html", sendPageUnknown());
}

String sendPageUnknown() {
    String ptr = "<!DOCTYPE html> \n";

  ptr += "";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  //ptr += "<meta http-equiv=\"refresh\" content=\"0;url=/\">";

  ptr += "<title>Page unknown</title>\n";

  ptr += "\n";

  ptr += "\n";
  ptr += "
Page unknown
\n";

  ptr += "Return to main page\n";

  ptr += "\n";
  ptr += "\n";
  return ptr;
}

String sendHTML() {
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  String ptr = "<!DOCTYPE html> \n";

  ptr += "";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>LED Dashboard</title>\n";

  ptr += "\n";
  ptr += "\n";

  ptr += "\n";
  ptr += "
ESP32 Web Server
\n";

  if (led1State)
  {
    ptr += "
LED1: ON
OFF\n";
  }
  else
  {
    ptr += "
LED1: OFF
ON\n";
  }

  if (led2State)
  {
    ptr += "
LED2: ON
OFF\n";
  }
  else
  {
    ptr += "
LED2: OFF
ON\n";
  }

  ptr += "\n";
  ptr += "\n";
  return ptr;
}

void loop() {
  server.handleClient();
}

Even that is suboptimal, as led endpoints shouldn't be GET endpoints but POST (really PUT as it only updates info, but let's stick to POST for simplicity)
Here a version using POST and unique endpoint /led to handle any number of less to manage:
#include <WebServer.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "password";

// Set web server port number to 80
WebServer server(80);

uint8_t led1Pin = 12;
uint8_t led2Pin = 13;

bool led1State = LOW;
bool led2State = LOW;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  // Set outputs to LOW
  led1State = LOW;
  led2State = LOW;
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_root);
  server.on("/led", HTTP_POST, handle_led);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP Server started");
}

void handle_root() {
  server.send(200, "text/html", sendHTML());
}

uint8_t evaluate_led_state(String ledState) {
  uint8_t state;
  if (ledState == "on") {
    Serial.println("led state: ON");
    state = HIGH;
  } else if (ledState == "off") {
    Serial.println("led state: OFF");
    state = LOW;
  } else {
    Serial.println("unknow led state: "+ledState);
  }
  return state;
}

void handle_led() {
  String ledPin = server.arg("ledPin");
  String ledState = server.arg("ledState");

  if (ledPin == "1") {
    Serial.println("setting led1");
    led1State = evaluate_led_state(ledState);
  } else if (ledPin == "2") {
    Serial.println("setting led2");
    led2State = evaluate_led_state(ledState);
  } else {
    Serial.println("led unknow: "+ledPin);
  }
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_NotFound() {
  server.send(404, "text/html", sendPageUnknown());
}

String sendPageUnknown() {
    String ptr = "<!DOCTYPE html> \n";

  ptr += "";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>Page unknown</title>\n";

  ptr += "\n";

  ptr += "\n";
  ptr += "
Page unknown
\n";

  ptr += "Return to main page\n";

  ptr += "\n";
  ptr += "\n";
  return ptr;
}

String build_led_form(String ledPin, uint8_t ledState) {
  String ptr = "<form action=\"led\" method=\"post\">\n";
  ptr += "  <input type=\"hidden\" name=\"ledPin\" value=\""+ledPin+"\">\n";

  String ledStateStr;

  if (ledState)
  {
    ledStateStr = "off";
  }
  else
  {
    ledStateStr = "on";
  }

  ptr += "  <input type=\"hidden\" name=\"ledState\" value=\""+ledStateStr+"\">\n";
  ptr += "  Led"+ledPin+"\n";
  ptr += "  <input type=\"submit\" class=\"button button-"+ledStateStr+"\" value=\"";
  ledStateStr.toUpperCase();
  ptr += ledStateStr+"\">\n";

  ptr += "</form>\n";
  return ptr;
}

String sendHTML() {
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  String ptr = "<!DOCTYPE html> \n";

  ptr += "";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>LED Dashboard</title>\n";

  ptr += "\n";
  ptr += "\n";

  ptr += "\n";
  ptr += "
ESP32 Web Server
\n";

  ptr += build_led_form("1", led1State);
  ptr += build_led_form("2", led2State);

  ptr += "\n";
  ptr += "\n";
  return ptr;
}

void loop() {
  server.handleClient();
}

For non trivial management you probably want to use spiffs
https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/


text:
Using pointer to a Global function
I am trying to store and use a pointer to a global function.
The function global_f returns a String and takes an object as parameter:
String global_f(Request r){
    // ...
    return "This is it";
}

I have also declared a type:
typedef String (*f_type)(Request);

And this is the class that stores the function:
class T {
    f_type f;

    void setF(f_type fFunc){ // called as: setF(&global_f)
        f = fFunc;
        f(Request());        // This Works
    }

    void callF(){
        f(Request());       // This Freezes the arduino
    }
}

So I can call f in the instructor, but it freezes the Arduino in other methods.
Follow-up: It runs in all methods, that the function is being passed as a parameter and stored in the object.
This is where this functions is called in the actual code: GitHub

//called as: T(&global_f)? it should be T(global_f)

how do you know it is freezing the Arduino? or even working in the first case? You don't do anything with the return value in either case!; can you make a complete, minimal sketch that shows the problem?

@Juraj I tried both of them and they give the same results, also PlatformIO compiles both

@esoterik I am using Serial.print to know how it runs. This is just the most important part of the code for this problem. I can provide a link to github if it is needed.

the snippets are OK. the problem is in the code you didn't show

@Juraj This is the actual code I'm using https://github.com/kachatzis/ArduinoWebServer/blob/758ba6eae7ab1a9fccdbdb3606bdfbfa980be742/lib/EthernetWeb/src/ApiEndpoint.cpp#L47


text:
Help decrypting AES string from arduino rf module in python
Please excuse any glaring errors in my code, I'm new to both C and python.
I'm trying to send an encrypted message from my arduino uno via a DHT22 sensor and an rf module using the radiohead ask and AESlib libraries to a raspberry pi with a usb RTL-SDR using the rtl_433 library and a python script.
I think (but I could very well be wrong) I have the Arduino side working properly and it feels as though I'm pretty close on the python side, however I don't seem to be decrypting the message properly.
An example of the string before being encrypted might be:
"55.55,24.99,0001"
Here is the code on the Arduino side:
#include <AESLib.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "DHT.h"
#include <RH_ASK.h>
#include <Base64.h>

#define DHTPIN 2

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
RH_ASK driver;

bool takeSensorReading = true;
float h;
float t;
String str_humid;
String str_temp;
String str_out;
uint8_t key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
char data[32];
char endChar[1] = "Ʊ";

void setup() {
  driver.init();
  dht.begin();
  Serial.begin(9600);
}

void loop() {
  delay(5000);

  int messagelength = sizeof(str_out);
  byte plain[messagelength];

  h = dht.readHumidity();
  // Read temperature as Celsius
  t = dht.readTemperature();

  // Convert Humidity to string
  str_humid = String(h, 2);

  // Convert Temperature to string
  str_temp = String(t, 2);

  // Combine Humidity and Temperature
  str_out = str_humid + "," + str_temp + ",0001";

  str_out.toCharArray(data, 32);
  aes256_enc_single(key, data);

  /*aes256_dec_single(key, data);*/
  Serial.println(data);
  int encryptedStringLength = sizeof(data);

  int encodedLength = Base64.encodedLength(encryptedStringLength);
  char encodedString[encodedLength];
  Base64.encode(encodedString, data, encryptedStringLength);
  Serial.print("Encoded string is:\t");
  Serial.println(encodedString);

  driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);
  driver.waitPacketSent();

  takeSensorReading = !takeSensorReading;
}

and here is the python code:
import subprocess
import json
import base64
from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

def decrypt(enc):
    private_key = str(bytearray([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]))
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

p = subprocess.Popen(['rtl_433', '-f', '433720000', '-F', 'json'],stdout=subprocess.PIPE,bufsize=1)
# rtl_433 -f 433720000 -F json
try:
    for line in iter(p.stdout.readline, ""):
        lineStripped = str(line).strip()
        try:
            jsondata = json.loads(lineStripped)
            time = jsondata["time"]
            payload = jsondata["payload"]
            if len(payload) == 33:
                payloadstring = ''
                for a in range(len(payload)):
                    payloadstring += chr(payload[a])
                payloadstring += "AAAAAAAAAA="
                print payloadstring
                encrypted = base64.b64decode(payloadstring)
                print encrypted
                decrypted = decrypt(encrypted)
                print decrypted
        except Exception as err:
            print "oh no, something went wrong"
            print("error: {0}".format(err))
except KeyboardInterrupt:
    p.kill()

p.wait()
p.stdout.close()
Here is an example of the erroneous output of the decrypt function:
"@g�އ�6S���25zD"
Any help you could give me in decoding the message from the Arduino in the python script would be really appreciated.
Thanks
Richard
*EDIT
I thought if it helps I could provide a bit more context around the transmission stages that the message goes through:
After the initial data string is constructed from the temperature and humidity sensor eg "55.55,24.99,0001" that 16 byte message is added to a 32 byte char array and encrypted using the aes128_enc_single method. The encrypted message is then base63 encoded The encrypted char array is then combined with an extra unencrypted character "Ʊ" (which I thought I could use to crudely validate the message) and sent via the radiohead ask send method:
driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);
On the pyhton/reciever end I run a sub process rtl_433 -f 433720000 -F json
and listen for the output line by line. A example of the output of the rtl_433 command would look something like this:
{"time": "2019-03-05 00:00:00", "model": "RadioHead ASK", "len": 33, "to": 255, "from": 255, "id": 0, "flags": 0, "payload": [111, 110, 109, 57, 120, 86, 52, 79, 121, 78, 71, 52, 48, 122, 117, 88, 67, 52, 77, 118, 85, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65], "mic": "CRC"}
rtl_433 converts the message into an array of ASCII or Unicode characters.
I have then tried to convert the characters in the recieved array back into standard characters:
payloadstring += chr(payload[a])
added padding to the message:
payloadstring += "AAAAAAAAAA="
then base64 decoded the result:
encrypted = base64.b64decode(payloadstring)
and then finally decrypt that:
decrypted = decrypt(encrypted)
Hopefully that info might be helpful in flagging up where I have gone wrong.

payloadstring += "AAAAAAAAAA=" that looks rather arbitrary

First error: int messagelength = sizeof(str_out); no that is not the length of the String. It is the number of bytes for a String instance. The correct way to retrieve the string length is to use the member function, int messagelength = str_out.length();https://www.arduino.cc/en/Tutorial/StringLength

By inspection only:
You are using an Initialization Vector and CBC mode in your Python code, but no IV and single block encryption in your Arduino code.
I think if you use MODE_ECB in your Python it will ignore the IV and match the Arduino code.
From a look at the AESLib github it appears your key should be exactly 16 bytes - yours is 32. I haven't looked at the code to see whether it will just ignore the rest, but the Python code definitely won't, so you should probably do what it says and use 16, and adjust your Python code to match.
Since the above wasn't enough to get it working, I would suggest divide-and-conquer: Use an online AES-128 encyrptor/decryptor such as aesencryption.net or encode-decode.com or infoencrypt.com to validate and cross-check your Arduino encryption and Python decryption functions. With a bit of luck you can at least fix them one-by-one, against a known-good reference.  Perhaps with a bit of fiddling you may be able to work out where it's going wrong.
I presume the humidity value may not change much, and I have a feeling that sending several messages with the same start can substantially weaken the encryption but I'm no crypto expert and perhaps it's still adequate for your purposes.

Hi Mark, Thanks very much for taking the time to help out. I've had a go at implementing your suggestions by changing the uint8_t key to have only 16 values and called aes128_enc_single instead of aes_256_enc_single. On the python side I removed the iv, reduced the private_key length to 16 and changed the AES mode to AES.MODE_ECB.
Unfortunatley I'm still not able to decrypt the message correctly.
I have edited my original post to include some context around the stages the message goes through in transit, I hope that helps shed some light into where I am going wrong.
Thanks again

Hey, thanks very much for the links ... encode-decode.com did throw up something interesting.
If I use the string HelloIamamessage and the secret abcdefghijklmnop and set up the corresponding values in the Arduino script uint8_t string_key[] = {97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112}; and String test_message = "HelloIamamessage";
I get the following output from the site:
k7yooB6Mj6bgxJ2ywaZj0rRDy5XLQ8VcZMRo2jfU2Ok=
and the following from the Arduino IDE:
k7yooB6Mj6bgxJ2ywaZj0gAAAAAAAAAAAAAAAAAAAAA=

The output starts the same but then diverges. Could this be a padding issue (or lack of it on the Arduino side) and if so would you have any idea how to solve this?

I might have worked out what's going wrong. Change your message to "HelloIamamessag" (i.e. 15 chars) and see if it matches.  If so, I'll edit the answer and explain why.

Hey Mark, thanks for taking another look. I changed the message to HelloIamamessag unfortunately I still can't get the encrypted string to match that on encode-decode.
Perhaps I have made a simple error. Here is a pastebin with my latest attempt (If this ever works I'll edit the question and post the working code there).
The Arduino IDE is returning:
0P3iW9FSrni+evrhrWaiMQ==
and encode-decode is returning:
bs3Uzmhox9ARIPliQRxawQ==
Both using the string HelloIamamessag


text:
Adafruit Feather ESP32 - GPIO power drain during deep sleep
I have an Adafruit Feather ESP32 whose GPIOs I use to control an external device. I don't want the device to drain the power of the ESP32 sometimes, so I set the GPIOs to INPUT. When I go into deep sleep though, the GPIOs suddenly get some random voltages and start drawing power. A few GPIOs are 3.3V, others are 0.7V, and some are near 0V.
What is the correct/standard way to make the microcontroller not leak any power to that external device.
One way is obviously physically disconnecting that device, but I want an automated way. Is it solvable by software or do I need special hardware to achieve my goal?

measure the current flowing at the GPIO pins when the ESP32 is in deep sleep .... measuring the voltage tells you nothing about the current, unless you know the value of the resistance

the board has a pull-up on some pins

@jsotola Certainly I also measured the current. When I disconnect the external device, the current drops significantly.

@Jurai that is true. So I moved away from those pins. This does not entirely solve my problem though. I want the current to the external device be the same as when I disconnect the external device: 0A. How can I achieve this?

Please provide some more information. What is the external device? How do you power this device? How is it connected? PS setting a pin to input, means it's now "floating" so it could be any voltage.

Sorry I'm not expert in the ESP32, but I know it can come out of deep sleep based on inputs from the pins. Maybe that's what's happening. The Espressif IDF at least has a way to read the reason the chip came out of deep sleep. Are you using the arduino image or micro/circuitpython?