text:
Not seeing frames returned from client when using ESP8266 Wifi Shield
I'm trying to make a web server using an Arduino R3 and Sparkfun ESP8266 Wifi Shield. I've built a webpage that has a form I would like to control the Arduino with.
Currently my sketch can successfully send the webpage, but when I use the form, 9 / 10 times I see no output on the serial monitor, and the 1/10 times I see the frame from the client the sketch seems to hang and the client keeps waiting for more data.
I'm using the Sparkfun ESP8266 libraries for the product I bought.
I don't think this is a hardware problem, I've visually inspected the Arduino and ESP pins and they seem ok. I don't think it's a memory problem.
I've put the salient part of the sketch below:
void serverDemo()
{
  // available() is an ESP8266Server function which will
  // return an ESP8266Client object for printing and reading.
  // available() has one parameter -- a timeout value. This
  // is the number of milliseconds the function waits,
  // checking for a connection.
  ESP8266Client client = server.available(1000);
  char clientline[BUFSIZ];
  int index = 0;

  if (client)
  {
    Serial.println(F("Client Connected!"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();

        if( index < BUFSIZ ) {
          clientline[index++] = c;
        } // end of if

        if (c == '\n' && currentLineIsBlank)
        {
          clientPrintProgmemArray(htmlHeaderTable, htmlHeaderTableSize, client);
          clientPrintProgmemArray(webpageTable, webpageTableSize, client);
          Serial.println(F("Page sent"));
          break;
        } // end of if

        if (c == '\n')
        {
          currentLineIsBlank = true;
        } // end of if

        else if (c != '\r')
        {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        } // end of if
      } // end of if( client.available() )
    } // end of while ( client.connected() )
    delay(10);
    client.stop();
    Serial.println(F("Client disconnected"));
    Serial.print(F("Index: "));
    Serial.println(index);
    Serial.print(F("Clientline: \""));
    for( int i = 0; i <= index; i++)
    {
      Serial.print(clientline[i]);
    }
    Serial.print(F("\"\r\n"));
    if( strstr(clientline, "e=1") != 0) {
      Serial.println("hooray!");
    }
  }
}

The header and webpage the Arduino sends to the client is:
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close
<!DOCTYPE HTML>
<html>
<body>
<form action="/?" method="get">
    <input name="e" type="submit" value="0">
    <input name="e" type="submit" value="1">
</form>
</body>
</html>

The output I get on the serial monitor is:
ESP8266 Shield Present
Mode set to station
Connected to: XXXXX
My IP: 192.168.0.13
Server started! Go to 192.168.0.13

Client Connected!
Page sent
Client disconnected
Index: 2
Clientline: "
 "
Client Connected!
Page sent
Client disconnected
Index: 2
Clientline: "
 "

I'd be very grateful if anybody has any advice on where the problem lies.
Thanks in advance

At for( int i = 0; i <= index; i++), I don't believe you've initialized clientline[index] anywhere, so the final iteration will print an undefined character. I don't know if this is the error, but I think it is an error. You could instead set clientline[index] = \0; (i.e. NUL-terminate the line), and replace the for-loop with Serial.print(clientline);, letting Serial.print() print the whole string for you.

Hi @JRobert, thanks for the advice. I've made those changes, but the serial output is still the same.

You're welcome. I wasn't convinced that was it, but now it's one less possibility! So now you know that coming out of the while loop, clientline contains two characters, one of which is some kind of whitespace, likely a space, and a '\n' (because the terminal line-feeds). You may need to be debugging the client at this point. Are you sure it is sending what you think it should be?

@JRobert I've checked communication on Wireshark and it looks OK. Every time the client refreshes the webpage it should send a message to the ESP8266 that should be picked up by client.read()
I think the problem lies in getting the frame from the ESP8266 to the Arduino, as the system is successfully sending the webpage as requested.

It looks like I have the same problem. I used the "ESP8266_Shield_Demo_Sparkfun" and often the webpage shows not a proper output ("AT.." commands instead). How did you adapt the baud rate in the "SparkFunESP8266WiFi.h"?
Thanks!

Hi, sorry for taking so long to reply, I haven't looked on here in a while. If it's still helpful to say, I didn't change the header file, I use the setBaud function from SparkFunESP8266WiFi.h straight after using begin()

So I figured out the answer to my own question.
It turns out there must be a mistake in the example sketches that come with the ESP8266 shield I bought, as the function to begin Arduino/ESP8266 communications didn't have any arguments when the function expected parameters. So it appeared to be trying to set their baud rate to 0!!
I edited the library to have a hard value of 57600 and now it seems to work far more reliably.


text:
Black screen when using higher SPI-speed for RA8857 LCD-controller
I'm using an Arduino Due that talks via SPI to an LCD (800x480) with the RA8875 controller chip.
The most recent datasheet I could find is: RA8875 datasheet.
Everything works as expected when using the Adafruit library. But, for my project, I want to maximize the communication speed between the LCD and the Arduino DUE.
Page 60 of the datasheet tells me that the maximum SPI speed to perform a SPIread is

system clock / 6.

Page 39 gives the formula for the system clock:

SYS_CLK = FIN * ( PLLDIVN [4:0] +1 ) / (( PLLDIVM+1 ) * ( 2^PLLDIVK [2:0] ))

There are some constraints:

From page 39:
FPLL = FIN * ( PLLDIVN [4:0] +1 ) must be equal to or greater
than 110 MHz

From page 91:
For an LCD of dim 800x480 2 layers 8bit color depth 60Hz framerate the pixel clock should be between  30 and 33MHz. (Registers are set to have 2 layers and 8 bit color depth).

A crystal of 20Mhz is soldered on the LCD ( FIN = 20 Mhz)
I have set the registers as follows:

Register
Value

PLLC1[88h]
24

PLLC1[89h]
1

PCSR[04h]
3

So, I expect:

SYS_CLK  = 20 Mhz * ( 24 +1 ) / (( 0+1 ) * ( 2^1 )) = 250 Mhz
Pixel clock = SYS_CLK / ( 2^3 ) = 31.25 Mhz
Max. spi speed = 250 Mhz / 6 = 41.66 Mhz.

I think to obey every given constraint.
But when I use an spi-speed of 30 Mhz, which is below 41.66 Mhz, I get a black screen.
I've put the Arduino sketch and the modified Adafruit library (Sven_RA8875) on google drive:
Arduino sketch + modified library.
The same data but on a pastebin:
Image: Working LCD at 20 Mhz
Example code RA8875
Modified library .cpp
Modified library .h
Edit by PPK:
I add the pictures from paste pics to this post after I scaled and croped them.

You computed the max speed of the display, but what about the Due. Can it handle 30 MHz SPI speed? Source from the internet claim that more than 20 MHz is not possible. Another thought: Even if the Due manages the 30 MHz, the endpoints need a fairly good shaped clock signal. If you use unshielded wires to connect the devices, that could disturb the signal form and makes the communication unreliable. I fear you need an osci the check that. And, does the display uses PWM to dim the backlights of the LCD? Then, did you configured the PWM signal bright enough?

Thanks @PeterPaulKiefer for your ideas! The Due seems to be able to have an spispeed of 84Mhz (https://www.arduino.cc/en/Reference/SPISetClockDivider). I attached a scope to the SPI clock signal once with and once without my changes for the spispeed. I've added them to the Google drive link above. The 30 Mhz spi clock seems okay. For the backlight, that is indeed pwm and it is bright enough (I dont change it between the example code and the modified code)

Sorry, I have no access to google drive and prefer not to log in. It would be better if you add the code and pictures direct to the question, in order to keep it if your google account would be deleted. --- The function you use is deprecated. --- Even if you set the clock speed to 84MHz, the send register must be filled with the picture data. That normally involves index computation and so on. After 8 Cycles the send register is empty, can you fill it within 8 CPU cycles? Or do you use DMA? I have some more ideas, but I'm busy at the moment. I'll come back.

I have added the code and images using pastebin links so no account is required. I tried to attach them directly but the size is to big. Okay it makes sense that I have actually a 30 Mhz clock but the data doesnt have enough time to load into the registers. I am not using DMA. Thanks for this, I did not think about it!

When I saw the pictures, my first thought was: The 30 MHz signal is useless. The slope is not steep enough.  But then I saw the blue wires (soldered?) to the board. Do you use them to connect the probes of the osci? That's not a good idea, as this long wires disturb reshape the signal at these frequencies; the wire acts as a low pass filter.

Try to put the probe direct to the clock pin and GND on the board if my assumption is correct, and you used the blue wires for the scope. If that does not change the signal form, then I would say the connection between the Due and the LCD is not sufficient for this frequency.

I thought about what you try to do: You had to configure the display to a clock frequencies of 250 MHz to achieve the refresh rate of 60 Hz with the given resolution. Then you try to deliver 60 frames per second over the SPI bus. That means the Due must be capable of generating or reading 60 frames with 768 kBytes per second and send it over the bus. I doubt the Due can handle this with its 84 MHz. So the demand of delivering 60 frames per second seems undoable to me.

The LCD has a 768 kB RAM to hold a picture frame. I asume it is possible to display it with 60 Hz but transfer only 25 frm/sec.  But I'm not really sure if the RAM can be filled asynchrounously.

Thanks @PeterPaulKiefer ! Indeed it wil probably not be possible, thanks for having a look at it. I remeasured the clock pin with my probe directly and changed the images for 30Mhz in here.

source: Stack Exchange

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

sort: votes


text:
Writing a 1Mb bitmap to an SDcard with only 96kB RAM
My goal is to have an Arduino Due (96 KB RAM) write a +-1MB bitmap to an SD card.
I have an array of a several coordinates on my Arduino Due and I would like to generate the bitmap where all the coordinates have a certain color and all the other pixels/background have another color.
I do have code to write a bitmap to an SD card (see below) but the problem is that the bitmap is dynamically generated and allocated in ram and then written to the SD card. So as soon as the bitmap I do want to write to the SDcard becomes bigger than the RAM available I get an error:
"xx.elf section '.bss' is not within region 'ram'.
Could anyone advice me on how to put parts of the bitmap in ram and write them to the sdcard one after another. Or would there maybe be another better approach?
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10;

char name[] = "9px_0000.bmp";       // filename convention (will auto-increment)
const int w = 800;                   // image width in pixels
const int h = 400;                    // " height
const boolean debugPrint = true;    // print details of process over serial?

const uint32_t imgSize = w*h;
int px[w*h];                        // actual pixel data (grayscale - added programatically below)

File file;

const int amount_CT_samples = 20;
int Yarr[amount_CT_samples];
int Xarr[amount_CT_samples];

void setup() {

  // SD setup
    SerialUSB.begin(9600);
  while (!SerialUSB) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  SerialUSB.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    SerialUSB.println("initialization failed!");
    return;
  }
  SerialUSB.println("initialization done.");

  // if name exists, create new filename
  for (int i=0; i<10000; i++) {
    name[4] = (i/1000)%10 + '0';    // thousands place
    name[5] = (i/100)%10 + '0';     // hundreds
    name[6] = (i/10)%10 + '0';      // tens
    name[7] = i%10 + '0';           // ones
    file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
    if (file) {
      break;
    }
  }

  // set fileSize (used in bmp header)
  int rowSize = 4 * ((3*w + 3)/4);      // how many bytes in the row (used to create padding)
  int fileSize = 54 + h*rowSize;        // headers (54 bytes) + pixel data

  // create image data; heavily modified version via:
  // http://stackoverflow.com/a/2654860
  unsigned char *img = NULL;            // image data
  if (img) {                            // if there's already data in the array, clear it
    free(img);
  }
  img = (unsigned char *)malloc(3*imgSize);

  for (int y=0; y<h; y++) {
    for (int x=0; x<w; x++) {
      int colorVal = px[y*w + x];                        // classic formula for px listed in line
      img[(y*w + x)*3+0] = (unsigned char)(colorVal);    // R
      img[(y*w + x)*3+1] = (unsigned char)(colorVal);    // G
      img[(y*w + x)*3+2] = (unsigned char)(colorVal);    // B
      // padding (the 4th byte) will be added later as needed...
    }
  }

  // create padding (based on the number of pixels in a row
  unsigned char bmpPad[rowSize - 3*w];
  for (int i=0; i<sizeof(bmpPad); i++) {         // fill with 0s
    bmpPad[i] = 0;
  }

  // create file headers (also taken from StackOverflow example)
  unsigned char bmpFileHeader[14] = {            // file header (always starts with BM!)
    'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0   };
  unsigned char bmpInfoHeader[40] = {            // info about the file (size, etc)
    40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0   };

  bmpFileHeader[ 2] = (unsigned char)(fileSize      );
  bmpFileHeader[ 3] = (unsigned char)(fileSize >>  8);
  bmpFileHeader[ 4] = (unsigned char)(fileSize >> 16);
  bmpFileHeader[ 5] = (unsigned char)(fileSize >> 24);

  bmpInfoHeader[ 4] = (unsigned char)(       w      );
  bmpInfoHeader[ 5] = (unsigned char)(       w >>  8);
  bmpInfoHeader[ 6] = (unsigned char)(       w >> 16);
  bmpInfoHeader[ 7] = (unsigned char)(       w >> 24);
  bmpInfoHeader[ 8] = (unsigned char)(       h      );
  bmpInfoHeader[ 9] = (unsigned char)(       h >>  8);
  bmpInfoHeader[10] = (unsigned char)(       h >> 16);
  bmpInfoHeader[11] = (unsigned char)(       h >> 24);

  // write the file (thanks forum!)
  file.write(bmpFileHeader, sizeof(bmpFileHeader));    // write file header

}

void loop() { }

UPDATE
With the following code my problem was solved.
Credits to those who answered my question below!
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;

struct Pixel {
    uint8_t r, g, b;
};

char name[] = "CT_0000.bmp";       // filename convention (will auto-increment)
const int w = 800;                   // image width in pixels
const int h = 400;                    // " height
const boolean debugPrint = true;    // print details of process over serial?

const uint32_t imgSize = w*h;
int px[w*h];                        // actual pixel data (grayscale - added programatically below)

File file;

const int amount_CT_samples = 50;
int Xarr[amount_CT_samples];
int Yarr[amount_CT_samples];

Pixel getPixel(int x, int y) {
    const Pixel black = {0, 0, 0},
                green = {0, 255, 0};

    for(int i=0; i < amount_CT_samples; i++){
      if(Xarr[i] == x && Yarr[i] == (h - y))return green;
    }
    return black;
}

void writeBitmap(File &file, int w, int h) {
    size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
    size_t fileSize = 54 + h*rowSize;    // includes header

    // Write image header.
    uint8_t header[54] = {
        // File header.
        'B','M',
        (uint8_t)(fileSize >>  0),
        (uint8_t)(fileSize >>  8),
        (uint8_t)(fileSize >> 16),
        (uint8_t)(fileSize >> 24),
        0,0, 0,0, 54,0,0,0,

        // Image info header.
        40,0,0,0,
        (uint8_t)(w >>  0),
        (uint8_t)(w >>  8),
        (uint8_t)(w >> 16),
        (uint8_t)(w >> 24),
        (uint8_t)(h >>  0),
        (uint8_t)(h >>  8),
        (uint8_t)(h >> 16),
        (uint8_t)(h >> 24),
        1,0, 24,0
    };
    file.write(header, sizeof header);

    // Write image data.
    uint8_t row[rowSize];
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Pixel pix = getPixel(x, y);
            row[3*x + 0] = pix.b;
            row[3*x + 1] = pix.g;
            row[3*x + 2] = pix.r;
        }
        file.write(row, sizeof row);
    }

    file.close();
}

void setup() {
    Serial.begin(9600);
    Serial.print("Initializing SD card...");

    //create dummy X and Y points
    for(int i = 0; i < amount_CT_samples; i++){
        Xarr[i] = i;
        Yarr[i] = i;
    }

    if (!SD.begin(chipSelect)) {
      Serial.println("initialization failed!");
      return;
    }
    Serial.println("initialization done.");

  // if name exists, create new filename
  for (int i=0; i<10000; i++) {
    name[3] = (i/1000)%10 + '0';    // thousands place
    name[4] = (i/100)%10 + '0';     // hundreds
    name[5] = (i/10)%10 + '0';      // tens
    name[6] = i%10 + '0';           // ones
    file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
    if (file) {
      break;
    }
  }

  Serial.println("start writing bitmap.");
  writeBitmap(file, w, h);
  Serial.println("done writing bitmap.");

}

void loop() { }

Would it be doable to create and write the headers first, and then generate the image row by row, and save each row to to the SD card before generating the next one? Should be under 3kB/row. The for loops suggest this could be doable. Don't know where the padding goes, though. Also, maybe you could generate directly to the flash memory instead of to the RAM, but I don't know what can be done there on the Due.

@ocrdu, thanks for your comment. Indeed a line by line write or a direct write to flash would solve my problem. But I don't know how I could practically implement this.

Well, roughly, you would use a int px[] the size of one row, fill it in the inner for loop, so for one value of h, then write it to the SD card at the end of the outer for loop, and then do the same for the next row i.e. the next h in the outer loop. Grofweg.

Thanks this is indeed a good idea!

You can write the file in chunks. As suggested by ocrdu in a comment,
writing line by line is a good strategy. In order to keep the complexity
of the code manageable, I would put the logic of deciding the color of a
pixel in its own function, and use another function for managing writing
the bitmap. For example:
struct Pixel {
    uint8_t r, g, b;
};

// Dummy example. Replace with your own logic.
Pixel getPixel(int x, int y) {
    const Pixel black = {0, 0, 0},
                green = {0, 255, 0};
    if (((x - y) & 0x0f) == 0) return green;
    return black;
}

void writeBitmap(File &file, int w, int h) {
    size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
    size_t fileSize = 54 + h*rowSize;    // includes header

    // Write image header.
    uint8_t header[54] = {
        // File header.
        'B','M',
        (uint8_t)(fileSize >>  0),
        (uint8_t)(fileSize >>  8),
        (uint8_t)(fileSize >> 16),
        (uint8_t)(fileSize >> 24),
        0,0, 0,0, 54,0,0,0,

        // Image info header.
        40,0,0,0,
        (uint8_t)(w >>  0),
        (uint8_t)(w >>  8),
        (uint8_t)(w >> 16),
        (uint8_t)(w >> 24),
        (uint8_t)(h >>  0),
        (uint8_t)(h >>  8),
        (uint8_t)(h >> 16),
        (uint8_t)(h >> 24),
        1,0, 24,0
    };
    file.write(header, sizeof header);

    // Write image data.
    uint8_t row[rowSize] = {0};
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Pixel pix = getPixel(x, y);
            row[3*x + 0] = pix.b;
            row[3*x + 1] = pix.g;
            row[3*x + 2] = pix.r;
        }
        file.write(row, sizeof row);
    }
}

Then after opening the file, you just have to:
writeBitmap(file, 800, 400);

Note that the getPixel() function above is just a dummy example that
draws green diagonal lines across the image. See timemage's answer for
ideas on how to implement your own pixel-generating function.

@SvenOnderbeke, this is a good starting point for you.  Just so you're not caught off guard, I wanted to mention that the BMP format stores its images in a way that most of us would call up-side-down.  The rows appearing first in the file are content that appears at the bottom of the image when displayed.

Perfect, thanks a lot! This answer solved my problem, I also edit my question so it now contains the solution.

Normally I'd write this a differently, but I've kept in relatively simple just to illustrate the basic idea:
struct point {
  int x;
  int y;
};

const point points_of_interest[] = {
  { 7, 11},
  {23, 17},
  {13, 19},
  { 3,  5},
  {17,  3},
};

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

void loop() {
  delay(4000);
  Serial.println("\n\n\n");

  for (int i = 0; i < 24; ++i) {
    for (int j = 0; j < 24; ++j) {
      bool coordinate_of_interest = false;

      for (const auto poi: points_of_interest) {
        coordinate_of_interest = j == poi.x && i == poi.y;
        if (coordinate_of_interest) {
          break;
        }
      }

      if (coordinate_of_interest) {
        Serial.print("XX");
      } else {
        Serial.print("..");
      }
    }

    Serial.println();
  }
}

It's printing a 24x24 or 576 "pixel" grid.  But only five coordinates are stored.
It would matter if it were a 2400x2400 grid, but it would not print nicely on a maximized Serial Monitor for example purposes.
With your bitmap, you could get more sophisticated.  E.g. checking that distance (or more efficiently distance squared; no sqrt() operation) from the pixel under consideration (i, j) to any point in the list is less than or equal to some amount, and coloring based on that.  This would result in solid circles centered on your points in your bitmap.  Or color gradient around the point if you base the color on the distance.
If you have a lot of points you will need to do something like sort them by their vertical coordinates and advance an index that represents the points on or below your horizontal sweep line, etc.  That is, if you have a lot of points you don't want to have to be taking the distance to all of them for every pixel under consideration.

Thank you for that advice! The solutions given here really helped me to generate the code I needed. (I edited my question so it now contains the solution).

@SvenOnderbeke, Nice.  If this was actually helpful you can mark it up.  But as I understand it, it is fitting that you should mark Edgar's answer as "accepted" because you have described it as solving your problem.

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


text:
How to convert an int to const int in Arduino?
For a specific project, I need to convert an int to a const int variable type.
int i = 10;
boolean ShiftRegister[i] //Throws error

const int i = 10;
boolean ShiftRegister[i]// Works Fine

as i am making my own custom library where the size of boolean can be defined by creating an object by the user
myLib Library(20); // user defined boolean size

and the size is stored to a struct like this as it can't directly be converted to a const int.
The header file ...
#ifndef myLib_h
#define myLib_h
#include "Arduino.h"

class myLib{

public:
myLib(int input);
private:
int input;

};
#endif

the C++ code
#include "myLib.h"
#include "Arduino.h"

 struct Data {
  int BoolSize;
 }Data[0];

 myLib::myLib(int input){
 Data[0].BoolSize=input
 }

 const int boolSize = Data[0].BoolSize;

 bool DataBoolean[boolSize];

Whenever i run this library, it throws an error untill i dont predefine the boolean size in cpp code like this..
bool DataBoolean[20];

that means there is something error converting the int to const int in this line
const int boolSize = Data[0].BoolSize;

so what i want is, i dont want to predefine the boolean size in the cpp code. i would rather like to
define boolean size by creating an object(where the code crashed), storing the size to a structure then assigning the structure integer to the const int variable. I need an efficiant way to
turn this struct variable
Data[0].BoolSize;

into a const variable and assign to it like this without any errors
const int boolSize = Data[0].BoolSize;

so how can i convert an integer to a const int so that i can continue to my project?
any helps please? thanks for your kind support.

struct Data { int BoolSize; } Data[0]; declares an array of zero elements. You need to change that 0 to (at least) a 1.

For this you should look at template classes.

@Mat an array starts from number 0, and I don't want more memory for data so I have given array length 0 only . Can I not be able to access data at array position 0 then ?

@Majenko please spend a little more time for me and write an example code here that will be easier for me to understand

I will, but I'm cooking breakfast at the moment.

Yes, sure , I am not in a hurry but when you are free, please do me this favor

If you declare T Data[length] (where T is a type), valid array indices run from 0 to length-1. With the declaration T Data[1], the only valid index is 0 (in which case using an array is pointless). With T Data[0], there is no valid index at all, as the array contains absolutely nothing.

@Edgar Bonet OK...

At the time the constructor of your class is called, its size must be already defined, because the memory allocation takes place before. But you try to give it as a parameter to the constructor. This cannot work.
You have at least these alternatives. (Note: This is an invitation to edit this answer and add more, if you know some serious solution.)
1. Use a template for the size
Please be aware that each different size will generate another implementation in machine code.
template<size_t size>
class myLib {
public:
    inline myLib<size>() {}
private:
    bool data[size];
};

2. Allocate the requested memory dynamically
class myLib {
public:
    inline explicit myLib(size_t size) : data(new bool[size]) {}
    inline ~myLib() {
        delete[] data;
    }
private:
    bool* data;
};

Note: Depending on the version of C++ you're using, you need to consider the Rule of Three (before C++11) or the Rule of Five (beginning with C++11). Since the implementation of the missing methods depends on specific details, it is left as an exercise to the reader.

There is a memory leak in the second example: you should delete[] data in a destructor. But see also the rule of three.

@EdgarBonet Absolutely correct, thanks! My current project is an embedded system that never destructs objects… misleading me. Therefore we don't need any of the additional methods.

If you want variable length of an array, then you can use malloc.
With same conext, if you want to initiate an array with specific length of value you have to use malloc.


text:
LMT01 temperature sensor code does not run - need help
Apr 06, 2018, 09:52 pm
I hope this is appropriate.  I posted this question on the Arduino/Sensor site, got 42 views, but no reply.
I had no success getting help with any earlier post on this subject, so I am starting over with new code by Kevan Darrah. He is a good  programmer, so the code should work, but it doesn't.  I did a lot of reading and I understand how it should work, so let me spend few words explaining what I learned and maybe someone can take it from there. The LMT01 output is 0.6V to 1.6V pulses 10 usec wide, I verified this using a scope, the total number of theses pulses is proportional to the temperature. This repeats every 100 msec.  This signal is input to pin D2, but that is a digital pin: High=5V, Low= 0V, but Arduino IDE does something sneaky when you use the special function "attachInterrupt(pin,ISR,Falling)" - It redirects the signal internally to pin A0N of the positive side of an Analog Comparator, and attaches to AN1 internally a stable reference voltage of 1.1V. Now the 0.6V to 1.6V pulses are exactly centered on the comparator so it puts out a perfect 1's and 0's for easy counting.
So to repeat myself only Pin2 is attached with the LMT01 to the Arduino. Why doesn't this  &!#^-thing work, it compiled and uploaded correctly.  If I had  a debugger on this software, moving one line at a time I could fix it myself.  Code follows:
 //Sample Code for LMT01 Temperature Sensor
//LMT01ELPGQ1
//Kevin Darrah

//TempPins
#define pulsePin 2 //D2 on arduino D5 on esp8266 **This is the output from the LMT01

//globals for the LMT01 temp sensor
volatile unsigned int pulseCount = 0;//pulses out of the sensor
float temperatureC = 0, temperatureF = 0;//converted temperatures
float tempHIGH, tempLOW = 1000;

//functions
void pulseDetect();//interrupt function
float getTemperature();//call this to get temperature from the LMT01 - returns a float for the temperature in (C)

void setup() {
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);//output from LMT01 sensor circuit

}

void loop() {
  temperatureC = getTemperature();// call getTemperature() to return temp in C
  if (temperatureC != 1000) {//returns 1000 if anything went wrong
    temperatureF = temperatureC * 9.000 / 5.000 + 32;
    if (temperatureF > tempHIGH)
      tempHIGH = temperatureF;
    if (temperatureF < tempLOW)
      tempLOW = temperatureF;
    Serial.print(temperatureC);
    Serial.print("C  ");
    Serial.print(temperatureF);
    Serial.print("F  HIGH=");
    Serial.print(tempHIGH);
    Serial.print("F  LOW=");
    Serial.print(tempLOW);
    Serial.print("F  DIFF=");
    Serial.print(tempHIGH - tempLOW);
    Serial.print("F  ");
    Serial.print(pulseCount);
    Serial.println("pulses  ");
    for (int i = 0; i < random(50, 200); i++)
      delay(1);
  }

}

float getTemperature() {// *********  GET TEMPERATURE FUNCTION *** returns the temperature C
  attachInterrupt(digitalPinToInterrupt(pulsePin), pulseDetect, FALLING);//using interrupt pin tp trigger on falling edge

  unsigned long conversionStartTime = millis();//keeps track of timing

  while (millis() - conversionStartTime < 10) { //looking for silence, in case we go to read temperature mid-measurement, ride it out till next one
   // yield();//for the ESP8266 to keep other tasks happy
    if (pulseCount > 0) {
      pulseCount = 0;
      conversionStartTime = millis();
    }
  }

  pulseCount = 0;//reset pulse count
  while (millis() - conversionStartTime < 150) {//wait for first pulse
   // yield();//for the ESP8266 to keep other tasks happy
    if (pulseCount > 0)
      break;
  }
  if (pulseCount == 0)
    return 1000;//FAIL - never got a pulse

  conversionStartTime = millis();//conversion done, so reset time
  unsigned int oldPulseCount = pulseCount;//just to help keep track of timings when pulse pin goes idle
  unsigned long pulseTime = millis();
  while (millis() - conversionStartTime < 60) { //measure pulses
   // yield();//for the ESP8266 to keep other tasks happy

    if (pulseCount != oldPulseCount) {//new pulse, so update timer
      oldPulseCount = pulseCount;
      pulseTime = millis();
    }
    else if (millis() - pulseTime > 5) {//no pulses for a while, must be done.
      break;
    }
  }
  //^^^ Stays stuck here counting pulese for 60ms

  if (pulseCount < 5) { //this is just noise, false trigger... I mean only 5 pulses, that can't be right
    return 1000;//FAIL
  }

  detachInterrupt(digitalPinToInterrupt(pulsePin));//done with the interrupt
  temperatureC = 256.000 * pulseCount / 4096.000 - 50;//conversion
  //see 7.3.2 Output Transfer Function in Datasheet

  return temperatureC;//throw the temp back
}

//change this function to look like this if using the ESP8266
//void ICACHE_RAM_ATTR pulseDetect()

void pulseDetect() {// *********  PULSE COUNTER INTERRUPT FUNCTION
  pulseCount++;
}

start by reducing your code to just count pulses and print out the value of pulseCount every second or so  .... you are also making an assumption that all the Arduino processors behave the same way internally ............. your question is too wordy ... you wrote a bunch of text that has nothing to do with the problem ... makes people lose interest before they get to the problem description .... everything before The LMT01 output is 0.6V to 1.6V pulses 10 usec wide is just fluff

does not work is a description that provides no information about the failure

This is added 15 months after the OP but there is very little information on this sensor.
You have not included your schematics which would be useful. For this setup TI gives you four options: transistor level shifting, isolation, multiple devices to one MCU pin, and common ground with high-side signal. Kevin Darrah uses the transistor level shifting method in his videos. Please refer to the TI datasheet for connections, pages 3 and 21 are relevant in setting that up. There is also this sample code supplied with a video that shows setup using the comparator.
NOTE: Ensure you do not have your sensor reverse biased or it will not work and may wreck it. Diodes are a good idea here.
Try commenting this out:
if (pulseCount < 5) { //this is just noise, false trigger... I mean only 5 pulses, that can't be right
return 1000;//FAIL

}
I found this sensor gives very low pulse readings if you have something setup incorrectly which will come out around -50C and this line may be causing it to read a fail. If that is the case you will need to rewrite the getTemperature() function, possibly using the comparator method supplied by TI which will require you to rewire, see their training code which includes a video. TI notes the first couple of readings may be incorrect. In my code I have my function perform several throwaway tests before spitting out a reading.
TL;DR If you use the TI comparator method, you can use the digital pins for power instead of the +5VDC like they do but use a diode (needed also for multiple sensors) to isolate the sensor to prevent reverse bias. If you do this you can shut the sensor off by switching it to INPUT but be aware, OUTPUT mode goes to ground by default which can cause reverse bias and fry your sensor. Use digitalWrite(pin,HIGH) prior to switching to OUTPUT to change default behaviour to +5V rather than GND (true, the diode should protect you here but adding this line is necessary anyway so do it in this order, safety first). I needed multiple sensors in my build so this is what I found, I used the Arduino-based comparator method quite successfully.
I don't have the necessary components to connect with transistor level shifting and actually test this at the moment but you could try this code if you want. I trimmed it down, eliminated most of the ESP8266 stuff you weren't using anyway and modified the getTemperature function to resemble what I have working right now.
//Sample Code for LMT01 Temperature Sensor
//LMT01ELPGQ1
//Kevin Darrah
// Ben Nesbitt, 2019

// For LMT01 if using transistor method of connection

//TempPins
#define pulsePin 2 //D2 on arduino  **This is the output from the LMT01

//globals for the LMT01 temp sensor
volatile unsigned int pulseCount = 0;//pulses out of the sensor
float tempC = 0;//converted temperatures
float tempHigh = 151;
float tempLow = 151;
unsigned long timeMillis = millis();

//functions
void pulseDetect();//interrupt function

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

  pinMode(pulsePin, INPUT);//output from LMT01 sensor circuit

}

void loop() {
  timeMillis = millis();
  tempC = getTemp(pulsePin);// return temp in C

  Serial.print(tempC); Serial.print("C  ");
  Serial.print(pulseCount); Serial.println("pulses  ");

  while (millis() - timeMillis < 5000) {} // Change this for how often you want to sample the temperature.

}

float getTemp(int pin)
{
  attachInterrupt(digitalPinToInterrupt(pin), pulseDetect, FALLING);//using interrupt pin tp trigger on falling edge
  float temperature = 0;
  unsigned long timeMillis = millis();//keeps track of timing
  int counterRef = 0; // Pulse count reference

  while (millis() - timeMillis < 10) { //looking for silence, in case we go to read temperature mid-measurement, ride it out till next one
    if (pulseCount > 0) {
      pulseCount = 0;
      timeMillis = millis();
    }
  }

  pulseCount = 0;//reset pulse count
  for (int i = 0; i < 3; i++)
  {
    while(pulseCount < 1) {}  //* TI recommends aborting the first one or two tests as inaccurate

    if(pulseCount != 0){
      //Wait for counting to be complete
      counterRef = 0;
      while(pulseCount != counterRef)
      {
        counterRef = pulseCount;
        timeMillis = millis();
        while (timeMillis == millis()){}
      }
      if (i < 2)
      {
        pulseCount = 0;
      }
      else
      {
         temperature = 0.0625 * pulseCount -50; // Pulses to temperature conversion
      }
    }
  }

  detachInterrupt(digitalPinToInterrupt(pin));//done with the interrupt

  //see 7.3.2 Output Transfer Function in Datasheet

  return temperature;
}

void pulseDetect() {// *********  PULSE COUNTER INTERRUPT FUNCTION
  pulseCount++;
}

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


text:
Runtime Error when using array of structs of unknown size as variable within class - some kind of overflow issue?
I have a class defined as below, it's basically a simple ring buffer, with some methods for getting useful statistics from the data held in the buffer.
enum BalanceMsgType{
  BAL_MSG_NOT = 0,
  BAL_MSG_READING = 1,
  BAL_MSG_SPECIAL = 2,
  BAL_MSG_ERROR = 3
};

typedef struct MeasuredMass{
  float mg;
  unsigned long time;
  bool steady;
  BalanceMsgType type;
};

class RingBuffer{
  private:
  unsigned int _size = 0;
  unsigned int _pos = 0;
  MeasuredMass *_array;
  void LinearRegression(){
    //... left out for simplicity
  }
  public:
  float lin_reg_m = 0;
  float lin_reg_c = 0;
  float lin_reg_r = 0;
  float est_current_mg = 0;
  //methods
  RingBuffer(unsigned int size){
    _size = size; //forgetting to put this line ->div0-> >1hr debugging :(
    _array = new MeasuredMass[_size];
    for (int i = 0; i < _size; i++){
      _array[i].mg = 0.0;
    }
  }
  void Add(MeasuredMass in_element){
    _array[_pos] = in_element;
    _pos = (_pos + 1)%_size;
    LinearRegression();
    est_current_mg = lin_reg_m*(in_element.time+BALANCE_DELAY) + lin_reg_c;
  }
  void ReadInOrder(MeasuredMass *pdata){  //Call with
                                          //my_buffer.ReadInOrder(data)
    for(int i = 0; i < _size; i++){
      pdata[i]=_array[(_pos+i+1)%_size];
    }
  }
  float Sum(){
    //...
  }
  float Mean(){
    //...
  }
  float StdDev(){
    //...
  }
  bool SteadyEnough(float max_sd){
    //...
  }
};

It compiles fine, and runs nicely in test programs. However, if I include it in larger programs (something like progmem 117404 of 122880 bytes, global vars 13604 of 32768) I get a "Board at COM8 not available" warning when using the Arduino Serial Monitor after uploading to my Fubarino Mini. (Even without actually interacting with those programs beyond creating an instance of the class.) Recent experience tells me this is some kind of crash due to a runtime error.
Fiddling around with the code, I've found that the issue doesn't occur in a version of the library which holds an array of floats instead of my MeasuredMass. That my MeasuredMass struct is obviously much larger than a float suggests to me that this is due to some pointer/array overflowy behaviour.
I've also managed to show that if I alter the class such that it uses a fixed length array rather than a pointer to one, the issue disappears.
i.e. RingBuffer's private member MeasuredMass *_array; becomes MeasuredMass _array[25];
and
RingBuffer(unsigned int size){
  _size = size; //forgetting to put this line -> div0 -> >1hr bugtracking
  _array = new MeasuredMass[_size];
  for (int i = 0; i < _size; i++){
    _array[i].mg = 0.0;
  }
}

becomes
RingBuffer(){
  for (int i = 0; i < _size; i++){
    _array[i].mg = 0.0;
  }
}

I'd rather maintain the ability to set the size of the ring buffer at runtime (in my case it's set based upon the number of seconds' worth of data requested), so can anyone help me in figuring out how I can achieve this without running into the overflow / memory problems I seem to be having?
Thanks

The problem is most likely here:
_array = new MeasuredMass[_size];

You're allocating _size * sizeof(MeasuredMass) bytes in the heap. If _size is too big the amount of memory allocated becomes too great and it fails to allocate. You should check if _array is NULL or not after the new.  If it's NULL then it failed to allocate.
The problem is that heap allocation is limited to 2kB. This is regardless of the amount of memory you actually have in the chip. This is a limit imposed by the compiler (actually the libraries bundled with the compiler) and is set by a value in the linker script.  It's something I've been campaigning to have removed from the libraries for many years, but it's always fallen on deaf ears. So much so that I provide a "fixed" version of the compiler in UECIDE that removes this hard limit.
The best thing you can do is to not use dynamic allocation. Instead have a statically created array which you then pass to the constructor.
MeasuredMass massBuffer[25];
RingBuffer massRing(massBuffer, 25);

and:
RingBuffer(MeasuredMass *buf, unsigned int size){
  _size = size; //forgetting to put this line ->div0-> >1hr debugging :(
  _array = buf;
  for (int i = 0; i < _size; i++){
    _array[i].mg = 0.0;
  }
}

Thank you! I was just in the middle of adding a comment to my original question, wondering if allocating a buffer just before calling the constructor and passing it through would work. But you beat me too it.
On the compiler hard limit - the more I use the Arduino IDE, the more I find that I don't want to use it anymore...

You should move over to uecide for chipKIT stuff... You get better support ;)


text:
Timer to control 1.5V clock
I want to make either an alarm clock or countdown timer whose alarm is loud enough to notice, but soft enough to not wake me up when asleep. My idea is to use the sound of an analog clock that I have - powered by a single AA 1.5V battery. I like this sound. So, I'd like to create an alarm or a timer that can turn on the power to this analog clock for a few minutes at least. Ideally, it would be something I could use daily for a couple hours without replacing the timer/alarm battery too often.
I've looked at these programmable relay timers: http://www.amazon.com/dp/B00P0TZ5CY/ but the voltage seems kindof overkill.
I've also considered an arduino board, but I'd like to be able to set the time on the device without plugging it into a computer.
I'm a developer, so I could do arduino programming if needed, but I don't know much about circuitry & hardware. I've also never done an arduino project, so I'm starting from 101.
Any ideas where I could start? The timer I mentioned above would be perfect if it didn't require 12V power. My knowledge is limited, so maybe that's less of a big deal than I think.

If I understand your question, you could use a relay to switch the 1.5V supply.

That's what I'm thinking, but a 12V relay seems like alot. I know it doesn't have to be the same voltage as what it's controlling, but I was wondering if there was something more light-weight.

Mainly because I don't want to power it with a car battery and I don't know anything about converting from AC to DC. I guess I could buy a 12V AC->DC adapter...

Not all relays are 12V...

I used to wake up by the relay clicking on inside my stereo, even before the music started. So if you are a light sleeper (which it sounds like), you might not want to use a relay.

I realized I actually have an old variable 1.5V-12V AC->DC wall-wart that I can probably use.

I suggest a simple setup (similar to my temperature and humidity sensor but less complex).
You can run from 3 x AA batteries, and have an RTC clock to keep track of the time. You can use a MOSFET to turn on your analog clock when required.
The processor can be asleep most of the time, using the watchdog timer to wake up and check the time from the RTC. Don't use an Arduino "board" unless you are running from a wall-wart because the voltage regulator, USB interface, and power LED, will consume too much power.

Thanks, that's a great writeup. I'm a beginner with this stuff, so I think that is probably a little more advanced than I'm looking for. It looks like I could just buy the 12V timer relay for less money and plug it in with my wall wart. My only concern is if it would waste too much power.

A timer relay won't use much power.

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


text:
can arduino on output mode sink current?
I have a arduino set below:
pinMode(1,OUTPUT);
digitalWrite(1,LOW);

Now, I am expecting 1.2mA current flow through the pin that is set as output. Is that accepted? If so, what it the max current a pin can sink?
The current comes from a pul up resistor on the line
note: I can't protect it with a diode.

Arduino pin current limitations

wouldn't INPUT allow more current?

yes it would, but Really what I'm doing in toggling between input and output LOW. The goal is to toggle the node from 0V to 3.3V.

Ok, I just found it.
from the arduno docs:
Atmega pins set aa output can source (provide positive current) or sink (provide negative current) up to 40 mA (milliamps) of current to other devices/circuits.

That's the absolute maximum rating. Recommended is 20mA

Yes it can. This blog post of mine will help to explain it.
In short:

It’s all so simple now, isn’t it? The output pin is just like a switch that either connects it to 5V or to ground.

can arduino on output mode sink current?

yes.

from the arduno docs:

the datasheet for the particular device is the best place for that answer.


text:
ModuleNotFoundError: No module named 'serial' when compiling for ESP32 in Arduino IDE
I'm new to ESP32 development and I'm trying to compile a program in the Arduino IDE to record the vibrations by an ADXL345 sensor. However, during compilation, I encounter a "ModuleNotFoundError: No module named 'serial'" error which seems to be related to serial communication.
I'm using an ESP32 Dev Module with the Arduino IDE version 1.18.19 on Ubuntu 22.04 Jammy Here's the code I'm trying to compile :
/***************************************************************************
* Example sketch for the ADXL345_WE library
*
* This sketch shows how use SPI for the basic data sketch. Please apply the
* same steps in the other sketches if you want to use SPI.
*
* Further information can be found on:
* https://wolles-elektronikkiste.de/adxl345-teil-1 (German)
* https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English)
*
***************************************************************************/

#include<ADXL345_WE.h>
#include<SPI.h>
#define CS_PIN 5   // Chip Select Pin

#define NUM_SAMPLES 3200

bool spi = true;    // flag indicating that SPI shall be used

xyzFloat samples[NUM_SAMPLES];
ADXL345_WE myAcc = ADXL345_WE(CS_PIN, spi);

const int int2Pin = 22;  // interrupt pin
volatile bool dataReady = false;

void setup(){
  Serial.begin(921600);
  Serial.println("ADXL345 Demo");
  if(!myAcc.init()){
    Serial.println("ADXL345 not connected!");
  }

  // Prepare int pin for input
  pinMode(int2Pin, INPUT);

  /* You can set the SPI clock speed. Default is 5 MHz. */
  //  myAcc.setSPIClockSpeed(4000000);

  /* Choose the data rate         Hz
      ADXL345_DATA_RATE_3200    3200
      ADXL345_DATA_RATE_1600    1600
      ADXL345_DATA_RATE_800      800
      ADXL345_DATA_RATE_400      400
      ADXL345_DATA_RATE_200      200
      ADXL345_DATA_RATE_100      100
      ADXL345_DATA_RATE_50        50
      ADXL345_DATA_RATE_25        25
      ADXL345_DATA_RATE_12_5      12.5
      ADXL345_DATA_RATE_6_25       6.25
      ADXL345_DATA_RATE_3_13       3.13
      ADXL345_DATA_RATE_1_56       1.56
      ADXL345_DATA_RATE_0_78       0.78
      ADXL345_DATA_RATE_0_39       0.39
      ADXL345_DATA_RATE_0_20       0.20
      ADXL345_DATA_RATE_0_10       0.10
  */
  myAcc.setDataRate(ADXL345_DATA_RATE_3200);

  // Safety delay
  delay(100);
  Serial.print("Data rate: ");
  Serial.print(myAcc.getDataRateAsString());

  /* In full resolution the size of the raw values depend on the
      range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit;
      uncomment to change to 10 bit for all ranges.
  */
  // myAcc.setFullRes(false);

  /* Choose the measurement range.
      ADXL345_RANGE_16G    16g
      ADXL345_RANGE_8G      8g
      ADXL345_RANGE_4G      4g
      ADXL345_RANGE_2G      2g
  */
  myAcc.setRange(ADXL345_RANGE_4G);
  Serial.print("  /  g-Range: ");
  Serial.println(myAcc.getRangeAsString());
  Serial.println();

  // Define interrupt routine and move data_ready to adxl int2
  attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING);
  myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2);
  myAcc.readAndClearInterrupts();

  // TODO add calibration routine
}

void loop() {

  int missed = 0;

  Serial.println("Beginning capture.");
  // Begin data acq
  for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    // Wait for new data
    while(!dataReady) {}
    dataReady = false;
    samples[cnt] = myAcc.getGValues();
    if (dataReady) {
      // new data received before we were ready to process it => probable miss
      missed ++;
    }
  }
  Serial.println("Capture done.");

  Serial.println("Removing DC");
  processRemoveDC();

  Serial.println("DATA_START");
  Serial.println("X\tY\tZ");
  for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    Serial.printf("%f\t%f\t%f\n", samples[cnt].x,samples[cnt].y,samples[cnt].z);
  }
  Serial.println("DATA_END");
  Serial.printf("%d Sample(s) missed\n", missed);

  printRMS();

  delay(5000);

}

/* Removes the continuous (dc) component
    This will operate inplace and edit the acquired data !
*/
void processRemoveDC() {
  float meanX, meanY, meanZ = 0;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    meanX += samples[cnt].x;
    meanY += samples[cnt].y;
    meanZ += samples[cnt].z;
  }
  meanX /= (float) NUM_SAMPLES;
  meanY /= (float) NUM_SAMPLES;
  meanZ /= (float) NUM_SAMPLES;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    samples[cnt].x -= meanX;
    samples[cnt].y -= meanY;
    samples[cnt].z -= meanZ;
  }
}
/* Computes and print the RMS per axis
*/
void printRMS() {
  float rmsX, rmsY, rmsZ = 0;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    rmsX += pow(samples[cnt].x, 2);
    rmsY += pow(samples[cnt].y, 2);
    rmsZ += pow(samples[cnt].z, 2);
  }
  rmsX = sqrt(rmsX/(float)NUM_SAMPLES);
  rmsY = sqrt(rmsY/(float)NUM_SAMPLES);
  rmsZ = sqrt(rmsZ/(float)NUM_SAMPLES);

  Serial.printf("RMS : X %f\tY %f\tZ %f\n", rmsX, rmsY, rmsZ);
}

void dataReadyISR(){
  dataReady = true;
}

I've checked that I've selected the right serial port in the Arduino IDE and that the USB drivers for the ESP32 are correctly installed on my computer. I've also tried restarting my computer and updating the ESP32 package in the Arduino IDE, but the problem persists.
How can I resolve this error and successfully compile my program for ESP32?
Thanks in advance for your help!
here is the error:
WARNING: Category '' in library ESP Insights is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library ESP RainMaker is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library WiFiProv is not valid. Setting to 'Uncategorized'
Traceback (most recent call last):
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool.py", line 31, in <module>
    import esptool
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/__init__.py", line 41, in <module>
    from esptool.cmds import (
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/cmds.py", line 14, in <module>
    from .bin_image import ELFFile, ImageSegment, LoadFirmwareImage
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/bin_image.py", line 14, in <module>
    from .loader import ESPLoader
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/loader.py", line 30, in <module>
    import serial
ModuleNotFoundError: No module named 'serial'
exit status 1
Error compiling for board ESP32 Dev Module.

Update with blink example:
/*
 * https://circuits4you.com
 * ESP32 LED Blink Example
 * Board ESP23 DEVKIT V1
 *
 * ON Board LED GPIO 2
 */

#define LED 2

void setup() {
  // Set pin mode
  pinMode(LED,OUTPUT);
}

void loop() {
  delay(500);
  digitalWrite(LED,HIGH);
  delay(500);
  digitalWrite(LED,LOW);
}

Returns:
WARNING: Category '' in library ESP Insights is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library ESP RainMaker is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library WiFiProv is not valid. Setting to 'Uncategorized'
Traceback (most recent call last):
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool.py", line 31, in <module>
    import esptool
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/__init__.py", line 41, in <module>
    from esptool.cmds import (
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/cmds.py", line 14, in <module>
    from .bin_image import ELFFile, ImageSegment, LoadFirmwareImage
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/bin_image.py", line 14, in <module>
    from .loader import ESPLoader
  File "/home/ubuntu/.arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool/loader.py", line 30, in <module>
    import serial
ModuleNotFoundError: No module named 'serial'
exit status 1
Error compiling for board ESP32 Dev Module.

ModuleNotFoundError doesn't sound like C++ error and you don't have any serial in your code (only Serial and as C++ is case sensitive, it's not the same)

Please include the full output in your question. This sounds like a problem with the ESP32 tools, which handle the upload.

copy the exact error here. I guess it is an error from the upload tool. it uses python. so it is a problem with the python installation. It has nothing to do with your sketch. did you try to upload Blink example? as a Stack Overflow user you should already know to do some basic troubleshooting.

Justdonit @chrisl ;)

You're right @Juraj I tried with the blink example and it's definitely something different that the code that creates this error. I didn't thought it could be the upload... Maybe its my IDE Version?

sudo apt install python-is-python3

Try pip install pyserial
arduino-esp32 uses esptool which is written in Python and uses pyserial. So you are probably getting this error on upload, not compiling. Maybe it is neither packaged in the esp32 tool files nor installed on your user/system python packages.

please search for duplicates before writing an answer

@Juraj if you found one, close it as a duplicate.

this one was really easy to find


text:
Data constant and always zero from the ADXL345 accelerometer with ESP32 using SPI
I am trying to get data from an ADXL345 accelerometer using an ESP32 via SPI communication. I have configured my code following the ADXL345_WE library specifications and have verified the hardware connections, but I am having trouble getting valid data from the sensor.
The problem is that even though I have correctly configured the sensor and established SPI communication, the values I get are always zero, even when I move the sensor.
...
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
DATA_END
3195 Sample(s) missed
RMS : X 0.024839    Y nan   Z 0.000000
Beginning capture.
...
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
0.000000    0.000000    0.000000
DATA_END
3195 Sample(s) missed
RMS : X 0.024839    Y nan   Z 0.000000
Beginning capture.

Aquí está mi código:
/***************************************************************************
* Example sketch for the ADXL345_WE library
*
* This sketch shows how use SPI for the basic data sketch. Please apply the
* same steps in the other sketches if you want to use SPI.
*
* Further information can be found on:
* https://wolles-elektronikkiste.de/adxl345-teil-1 (German)
* https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English)
*
***************************************************************************/

#include<ADXL345_WE.h>
#include<SPI.h>
#define CS_PIN 5   // Chip Select Pin

#define NUM_SAMPLES 3200

bool spi = true;    // flag indicating that SPI shall be used

xyzFloat samples[NUM_SAMPLES];
ADXL345_WE myAcc = ADXL345_WE(CS_PIN, spi);

const int int2Pin = 22;  // interrupt pin
volatile bool dataReady = false;

void setup(){
  Serial.begin(921600);
  Serial.println("ADXL345 Demo");
  if(!myAcc.init()){
    Serial.println("ADXL345 not connected!");
  }

  // Prepare int pin for input
  pinMode(int2Pin, INPUT);

  /* You can set the SPI clock speed. Default is 5 MHz. */
  //  myAcc.setSPIClockSpeed(4000000);

  /* Choose the data rate         Hz
      ADXL345_DATA_RATE_3200    3200
      ADXL345_DATA_RATE_1600    1600
      ADXL345_DATA_RATE_800      800
      ADXL345_DATA_RATE_400      400
      ADXL345_DATA_RATE_200      200
      ADXL345_DATA_RATE_100      100
      ADXL345_DATA_RATE_50        50
      ADXL345_DATA_RATE_25        25
      ADXL345_DATA_RATE_12_5      12.5
      ADXL345_DATA_RATE_6_25       6.25
      ADXL345_DATA_RATE_3_13       3.13
      ADXL345_DATA_RATE_1_56       1.56
      ADXL345_DATA_RATE_0_78       0.78
      ADXL345_DATA_RATE_0_39       0.39
      ADXL345_DATA_RATE_0_20       0.20
      ADXL345_DATA_RATE_0_10       0.10
  */
  myAcc.setDataRate(ADXL345_DATA_RATE_3200);

  // Safety delay
  delay(100);
  Serial.print("Data rate: ");
  Serial.print(myAcc.getDataRateAsString());

  /* In full resolution the size of the raw values depend on the
      range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit;
      uncomment to change to 10 bit for all ranges.
  */
  // myAcc.setFullRes(false);

  /* Choose the measurement range.
      ADXL345_RANGE_16G    16g
      ADXL345_RANGE_8G      8g
      ADXL345_RANGE_4G      4g
      ADXL345_RANGE_2G      2g
  */
  myAcc.setRange(ADXL345_RANGE_4G);
  Serial.print("  /  g-Range: ");
  Serial.println(myAcc.getRangeAsString());
  Serial.println();

  // Define interrupt routine and move data_ready to adxl int2
  attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING);
  myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2);
  myAcc.readAndClearInterrupts();

  // TODO add calibration routine
}

void loop() {

  int missed = 0;

  Serial.println("Beginning capture.");
  // Begin data acq
  for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    // Wait for new data
    while(!dataReady) {}
    dataReady = false;
    samples[cnt] = myAcc.getGValues();
    if (dataReady) {
      // new data received before we were ready to process it => probable miss
      missed ++;
    }
  }
  Serial.println("Capture done.");

  Serial.println("Removing DC");
  processRemoveDC();

  Serial.println("DATA_START");
  Serial.println("X\tY\tZ");
  for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    Serial.printf("%f\t%f\t%f\n", samples[cnt].x,samples[cnt].y,samples[cnt].z);
  }
  Serial.println("DATA_END");
  Serial.printf("%d Sample(s) missed\n", missed);

  printRMS();

  delay(5000);

}

/* Removes the continuous (dc) component
    This will operate inplace and edit the acquired data !
*/
void processRemoveDC() {
  float meanX, meanY, meanZ = 0;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    meanX += samples[cnt].x;
    meanY += samples[cnt].y;
    meanZ += samples[cnt].z;
  }
  meanX /= (float) NUM_SAMPLES;
  meanY /= (float) NUM_SAMPLES;
  meanZ /= (float) NUM_SAMPLES;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    samples[cnt].x -= meanX;
    samples[cnt].y -= meanY;
    samples[cnt].z -= meanZ;
  }
}
/* Computes and print the RMS per axis
*/
void printRMS() {
  float rmsX, rmsY, rmsZ = 0;
  for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
    rmsX += pow(samples[cnt].x, 2);
    rmsY += pow(samples[cnt].y, 2);
    rmsZ += pow(samples[cnt].z, 2);
  }
  rmsX = sqrt(rmsX/(float)NUM_SAMPLES);
  rmsY = sqrt(rmsY/(float)NUM_SAMPLES);
  rmsZ = sqrt(rmsZ/(float)NUM_SAMPLES);

  Serial.printf("RMS : X %f\tY %f\tZ %f\n", rmsX, rmsY, rmsZ);
}

void dataReadyISR(){
  dataReady = true;
}

Here is my wiring:

Here's my realization:

I have tried debugging the code and checking the hardware connections, but have not been able to find the problem. Is there something I am overlooking or any settings I need to adjust to get valid data from the sensor?
Any help or suggestions would be greatly appreciated. thanks!
Update with simpler example
I tried with this tutorial with less connections and code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/*Initialize an instance of Adafruit_ADXL345_Unified with a unique id*/
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void setup() {

  Serial.begin(9600);
  Serial.println("");
  Serial.println("Small example to read from ADXL345 accelerometer");

}

void loop() {

  /*Read from ADXL345 accelerometer*/
  sensors_event_t event;
  accel.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  /*Take a one second break*/
  delay(1000);

}

But now got a problem reading or accessing an invalid memory address:
A10     : 0x3ffc1e70  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x40086244  LEND    : 0x4008624f  LCOUNT  : 0x00000000

Backtrace: 0x400d1c54:0x3ffb2170 0x400d1c8e:0x3ffb2190 0x400d1cb5:0x3ffb21b0 0x400d18b1:0x3ffb21d0 0x400d18c1:0x3ffb2200 0x400d1912:0x3ffb2220 0x400d14dc:0x3ffb2240 0x400d4281:0x3ffb2290

ELF file SHA256: 5143f7db4d6401a9

Rebooting...

�
Small example to read from ADXL345 accelerometer
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400d1c57  PS      : 0x00060230  A0      : 0x800d1c91  A1      : 0x3ffb2170
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x3ffb833c  A7      : 0x00000000  A8      : 0x3ffb22b0  A9      : 0x3ffb2290
A10     : 0x3ffc1e70  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x40086244  LEND    : 0x4008624f  LCOUNT  : 0x00000000

Backtrace: 0x400d1c54:0x3ffb2170 0x400d1c8e:0x3ffb2190 0x400d1cb5:0x3ffb21b0 0x400d18b1:0x3ffb21d0 0x400d18c1:0x3ffb2200 0x400d1912:0x3ffb2220 0x400d14dc:0x3ffb2240 0x400d4281:0x3ffb2290
�

Which tutorial are you following? This one? https://www.electronicwings.com/esp32/adxl345-accelerometer-interfacing-with-esp32

No, but thanks for mentioning it @tepalia I am following this one


text:
Pump running even if relay says "off"
I have a relay that should be switched off when the analog value is too high by the Arduino code:
int digitalPin = 4; // for the relay
int analogPin = A0; // for the soil moisture sensor
int digitalVal; // digital readings
int analogVal; // analog readings

void setup()
{
    pinMode(digitalPin, OUTPUT);
    digitalWrite(digitalPin, LOW);
    Serial.begin(9600);

}

void loop()
{
    analogVal = analogRead(analogPin); // read the value returned by the soil moisture sensor
    if (analogVal < 400) { // if the soil moisture sensor returns a value < 400
        digitalWrite(digitalPin, HIGH); // The water pump waters the plant
    } else {
        digitalWrite(digitalPin, LOW); // The water pump stops watering
    }
    Serial.println(analogVal);
    delay(100);
}

But, as you can see on the video, despite going above the 400 threshold, having the relay pin switching off, it continues to pump.
Here is my architecture:

I just changed the relay to an Elegoo 4:

I am following this tutorial.

you have to connect the relay to the controlled pin

don't use the arduino as a power supply for the motor ... it could destroy the arduino

Oh, right @jsotola but isn't it what I did? (I just uploaded a photo of my attempt to implement the sketch)
Thanks for the tip for the power supply. I will look for one when I will be sure my thing is working properly :)

isn't it what I did? ... no, the wiring diagram shows otherwise

Oh, you mean that the green and the light blue wires should be the same? So the relay would be connected to the control pin ?

"I will look for one when I will be sure my thing is working properly :) " Sounds like the chicken and egg thing. Expensive if the arduino fails. Note: "A Power Supply the Arduino is NOT!" A mistook could also take out your computer.

you mean that the green and the light blue wires should be the same? ... no ... your code shows the control pin to be pin 4 ... your wiring diagram show a connection at pin 2

yes, I think that's a mistake from the tutorial @jsotola as the video accompanying it says to connect the (S) pin of the relay to pin4 of the Arduino

why are you posting inaccurate material? ... there is no reason why anyone should have to watch a video to learn what you are doing ... questions should be self contained  without need for external links

hmm, I think I've posted the inaccurate material because it is the context of the question @jsotola    My question is about the pump working continuously while the relays should stop it at some point

Do you hear the relais switch? Its PCB has an LED, does it reflect the expected state? Only if that is correct, you should think about adding the pump.

Can you post your connection diagram? A hand-drawn document is better than the wrong diagram in the question.


text:
Configuring Timers to Add One More 50kHz Square Wave
I am generating two 50kHz square waves, but I would like to generate three square waves. I have problems with generating the third square wave.
Basically, I need to configure the timer bits so that I can get the third square wave.
Here is the code I need to modify for the third square wave:
// This code demonstrates how to generate two output signals
// with variable phase shift between them using an AVR Timer

// The output shows up on Arduino pin 9, 10

// More AVR Timer Tricks at http://josh.com

void setup() {
  pinMode( 9 , OUTPUT );    // Arduino Pin  9 = OCR1A
  pinMode( 10 , OUTPUT );   // Arduino Pin 10 = OCR1B

  // Both outputs in toggle mode
  TCCR1A = _BV( COM1A0 ) |_BV( COM1B0 );

  // CTC Waveform Generation Mode
  // TOP=ICR1
  // Note clock is left off for now

  TCCR1B = _BV( WGM13) | _BV( WGM12);

  OCR1A = 0;    // First output is the base, it always toggles at 0

}

// prescaler of 1 will get us 8MHz - 488Hz
// User a higher prescaler for lower freqncies

#define PRESCALER 1
#define PRESCALER_BITS 0x01

#define CLK 16000000UL    // Default clock speed is 16MHz on Arduino Uno

// Output phase shifted wave forms on Arduino Pins 9 & 10
// freq = freqnecy in Hertz (  122 < freq <8000000 )
// shift = phase shift in degrees ( 0 <= shift < 180 )

// Do do shifts 180-360 degrees, you could invert the OCR1B by doing an extra toggle using FOC

/// Note phase shifts will be rounded down to the next neared possible value so the higher the frequency, the less phase shift resolution you get. At 8Mhz, you can only have 0 or 180 degrees because there are only 2 clock ticks per cycle.

int setWaveforms( unsigned long freq , int shift ) {

  // This assumes prescaler = 1. For lower freqnecies, use a larger prescaler.

  unsigned long clocks_per_toggle = (CLK / freq) / 2;    // /2 becuase it takes 2 toggles to make a full wave

  ICR1 = clocks_per_toggle;

  unsigned long offset_clocks = (clocks_per_toggle * shift) / 180UL; // Do mult first to save precision

  OCR1B= offset_clocks;

  // Turn on timer now if is was not already on
  // Clock source = clkio/1 (no prescaling)
  // Note: you could use a prescaller here for lower freqnencies
  TCCR1B |= _BV( CS10 );

}

// Demo by cycling through some phase shifts at 50Khz

void loop() {

  setWaveforms( 50000 , 90 );

  delay(1000);

}

What are the problems you are having? The code you posted doesn't look like it makes any attempt at a 3rd signal.

@josecanuc Exactly, there are only two signals generated. I just wanted to show what I am currently using to generate two signals. Need to modify the code to be able to generate third signal

what is the relationship between the three signals?

@jsotola They are supposed to be 90 degrees different. 1st signal - 0 degrees, 2nd - 90 degrees, 3rd - 180 degrees. Ideally, i would need a 4th which is 270 degrees, but one problem at a time.

On the Uno, you only have two PWM outputs per timer. If you need more, you will have to configure a second timer. If you need them to be synchronized, you will have to use Timer 0, but then you loose the Arduino timekeeping functions (millis() and co.) If you use Timer 2, you can preserve those functions, but you may have imperfect synchronization.


text:
Coding Arduino's samples/period and cycles/sample configurations for input signal
Am I able to code the Arduino so that I can change cycles/sample of an input waveform and a number of samples/period configurations? I would like to modify these parameters in order to be able to store a high-frequency sinusoid but taking into account Arduino's 16MHz clock.
For examples, I have a 40,000kHz sine wave. I would like to sample it at 10 samples/period and having 10 cycles/sample. As a result, I need a (40,000kHz * 10samples/period * 10 cycles/sample = 4MHz clock, which Arduino can supply). Compared to a more standard 128 samples/period and 256 cycles/sample, which would require a 1.3GHz clock.

No, an Arduino cannot do this.

@Chris Stratton  So does it mean you always have a fixed sample/period of 128 and cycles/sample of 256?

It means you can't come anywhere near your goal, so adjustability is beside the point.

The limitation is in the ADC which by default takes 104 µs to make a sample. Now you can speed up the ADC, sacrificing accuracy, but even then you can probably practically only reach a sampling time of 13 µs. Plus you would have the issue of where to put these 400,000 samples in the 2KB of RAM you have.
To sample at 400,000 times a second you would need to sample every 2.5 µs, which you can see is way shorter than 13 µs.
Plus, you not only need space to put these 400,000 samples, but it would take time to store them.
For more information see my page about the ADC which has a lot of details about sampling times, frequencies, accuracy, etc.


text:
Generating Sinusoid Signal of 40khz
I would like to generate a sinusoidal signal of 40kHz using Arduino Uno.
Maximum I could generate was 1kHz, using bit banging, fast PWM. Do you have ideas of how to boost it to 40kHz?
I used "Advanced Arduino Sound Synthesis" for inspiration. https://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/

What kind of resolution (both amplitude an time resolution) are you wanting?

Sorry, not sure what do you mean by the time resolution, but I am planning to feed the signal into a transmitter and receive it on the other end. I use speakers that work at 40kHz frequency as both transmitter and receiver.

Time resolution: how many samples per second (or samples per sinewave period) do you want?

i mean, based on Nyquist rate, I guess it should be 2*40khz at least. But otherwise, no preference

That would give you a square wave. It depends on what quality you want. Anything less than say 128 samples per period would end up in something more like a triangle wave.

Draw a single period of a sinewave on a piece of paper. Split it into sections by drawing vertical lines. Each line is one sample. How many do you need to draw (subdivide each segment each time) before the points where the lines cross the sinewave look like a sinewave.

i would try to find an opamp-based sine wave generator circuit, then use a digital pot to adjust that. or use an ESP32's DAC...

The purpose of my project now is to develop a lock-in amplifier essentially using only arduino. Thus, I'm trying to stay away from the external hardware

if you don't need to adjust the frequency, a tuned capacitor can turn a square wave into a sine wave.

I tried adding a band pass filter after generating a square wave using arduino and the output seems pretty noisy. Any advice on how to get rid of the noise?

If you don't need to adjust the frequency there are far simpler ways of generating a signal than waveform synthesis.  But before you get too worried about the generation, consider the lock-in itself: are you going to do that in the analog domain?  To do it digitally, you probably want an MCU with a better ADC.

you could use this as a peripheral to the arduino ... https://www.digikey.com/product-detail/en/cypress-semiconductor-corp/CY8CKIT-059/428-3390-ND/5184557 .... here is a tone generator app note ... http://www.cypress.com/documentation/application-notes/an69133-psoc-3-psoc-5lp-easy-waveform-generation-wavedac8-component

@ChrisStratton what MCU would you recommend for that purpose? And what are the simpler ways. Essentially, for my project I need to use as much of Arduino's own hardware as possible, but I can choose any arduino on the market.

You can't really pick a platform without a complete performance requirement.  Sure, if it has to say "Arduino" in soldermask, you could see if the specs of a Due are better in the areas you need - but you won't really know what you need without detailed examination of the requirement.

@Chris Stratton, for this project the only requirement I have is to make use of Arduino as much as possible to essentially assemble a lock-in amplifier. Thus generating a 40khz sinusoid is the first step I have to make. Why 40 kHz? Because I need to use 40kHz speakers(receiver and transmitter) that operate at that frequency

Voting to close as the asker has refused multiple requests to provide any performance specification which could be used to determine if a given method will yield satisfactory results.

Let's first do some maths.

You want 40,000 cycles per second.
Each cycle needs splitting up into samples. For example, let's use 128 samples.
Assume you want an 8-bit amplitude resolution.

Each second of signal would need 40,000 cycles * 128 samples. That's 5120000 samples per second.
If using PWM to generate the audio that's 256 clock cycles (28) per sample. That means 5120000 * 256 = 1,310,720,000.
That means a "carrier frequency" of over 1.3GHz.  There's no way an Arduino can do that.
If instead you used a simple DAC (e.g., an R-2R ladder) connected to the 8 pins of port D (that's pins 0-7 on the Uno) you don't need the 256 clock cycles per sample. That means that you have to output a new sample to PORTD 5,120,000 times per second. That's outputting at over 5MHz.
With some well crafted assembly code that might be possible.  The Arduino certainly won't be able to do anything else at all at the same time.
You would be much better off using a chip that has audio capabilities and DMA. Maybe a Teensy 3.x would be a better choice for your project.

That seems reasonable, I'll research into that. Thanks a lot

You don't need anywhere near 128 samples per cycle; in fact you only need 2. Using so many just makes the analog cleanup filter simpler.

With 2 samples you can only generate a square wave. Yes, you can then add extra circuitry to remove the higher frequency components, but as you say it's more complex. The question is about generating a sinusoid, not generating a square wave and converting it to something close-ish to a sinusoid.

If let's say you decide to take 10 samples per period instead of 180, the sinusoid is still supposed to look decent. But that gives you 1040,000256 = 102MHz clock, but Arduino only has 16MHz clock.

Any number of samples is kind of ludicrous on such a small MCU.


text:
I2C sensors not working when I connect to LCD 20X04
I am making a hydroponic nutrient monitoring system using Arduino Uno, Atlas  Scientific EC sensor, pH sensor, and RTD (temperature) sensor in I2C mode. I also want to use LCD 20x04 to display the sensor reading so that will display the EC, pH, and temperature values.
I connect all the SDA and SCL to pin A4 (SDA) and A5 (SCL), and powered all the sensors and LCD with 3.3 V. Each sensor's SDA and SCL are added with resistor 4.7 kOhm.

I tested the code first by connecting my Arduino Uno to the RTD EZO circuit and sensors, without the LCD. The Serial Monitor successfully displays the data sensor reading of RTD, as well as 'No Data' for EC and pH as I do not connect the EC and pH sensors. But when I connect all the circuits and sensors, it can not detect the pH sensor. The most frustrating part is the LCD. The LCD at first displays the EC and RTD data, but only run for 5 minutes and freeze. The LCD sometimes only shows a "0.00" value for EC and RTD even though the Serial Monitor shows the data sensor reading.
I want to know if there is something wrong with my code or maybe the problem with my own circuit.
Here is the code:
#include <Ezo_i2c.h>
#include <Wire.h>                //enable I2C.
#include <LiquidCrystal_I2C.h>

Ezo_board ec = Ezo_board(100, "EC");
Ezo_board ph = Ezo_board(99, "PH");
Ezo_board temp = Ezo_board(102, "RTD");
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);

bool reading_request_phase = true;        //selects our phase

uint32_t next_poll_time = 0;              //holds the next time we receive a response, in milliseconds
const unsigned int response_delay = 1000; //how long we wait to receive a response, in milliseconds

void setup()                     //hardware initialization.
{
  Serial.begin(9600);            //enable serial port.
  Wire.begin();                  //enable I2C port.
  Serial.println("ATLAS EZO I2C v2");
  Serial.print("Test date: ");
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1,1);
  lcd.print("ATLAS EZO I2C v2");
  lcd.setCursor(0,2);

  delay(3000);
  lcd.clear();
 }

  void loop() {                                                      //the main loop.
  lcd.setCursor(0,1);
  lcd.print("EC: ");
  lcd.setCursor(4,1);
  lcd.print(ec.get_last_received_reading());
  lcd.setCursor(10,1);
  lcd.print("ppm");
  lcd.setCursor(0,2);
  lcd.print("pH: ");
  lcd.setCursor(4,2);
  lcd.print(ph.get_last_received_reading());
  lcd.setCursor(0,3);
  lcd.print("Temp.: ");
  lcd.setCursor(7,3);
  lcd.print(temp.get_last_received_reading());
  lcd.setCursor(13,3);
  lcd.print("C");

  if (reading_request_phase)             //if were in the phase where we ask for a reading
  {
    //send a read command
    //to let the library know to parse the reading
    ec.send_read_cmd();
    ph.send_read_cmd();
    temp.send_read_cmd();

    next_poll_time = millis() + response_delay;         //set when the response will arrive
    reading_request_phase = false;                      //switch to the receiving phase
  }
  else                                                //if were in the receiving phase
  {
    if (millis() >= next_poll_time)                    //and its time to get the response
  {
    receive_reading(ec);                              //get the reading from the EC circuit
    receive_reading(ph);                              //get the reading from the PH circuit
    receive_reading(temp);                              //get the reading from the RTD circuit

    reading_request_phase = true;                     //switch back to asking for readings
  }
 }
 }

  void receive_reading(Ezo_board &Sensor) {
  Serial.println();
  Serial.print(Sensor.get_name()); //print the name of the EZO circuit
  Serial.print(": ");
  Sensor.receive_read_cmd();

  switch (Sensor.get_error())                          //switch case based on what the response code is.
     {
    case Ezo_board::SUCCESS:
    Serial.print(Sensor.get_last_received_reading());               //the command was successful, print the reading
    break;

    case Ezo_board::FAIL:
    Serial.print("Failed ");                          //means the command has failed.
    break;

    case Ezo_board::NOT_READY:
    Serial.print("Pending ");                         //the command has not yet been finished calculating.
    break;

    case Ezo_board::NO_DATA:
    Serial.print("No Data ");                         //the sensor has no data to send.
    break;
 }
}

If all your devices are i2c devices, that's not how the pull-up resistors should be wired. Please read i2c

Welcome to Stack Exchange!
I can spot a few problems with the circuit. As @hcheung said, the I2C pull-up resistors should only be wired between SDA>3.3V and SCL>3.3V (in parallel), not in series with the sensors.
Also, another warning: You are powering your sensors with 3.3V, but the outputs from the Arduino Uno are 5V! Many boards will not like this and might fry themselves, or at least not function correctly. Their signals will also be 3.3V instead of 5V, potentially causing more weird behavior.
If all your components are compatible with 5 volt power (check their datasheets/guides), I would recommend powering them all with 5 volts.
Otherwise, you will need level shifters to convert between the 5V Arduino signals and the 3.3V board signals.

Thank you for all your help.
I now realize that I have made the wrong I2C circuits. Then I modified them and now the program and the sensors work perfectly.
Here is my circuit now.


text:
Using a Microchip Fubarino with the Arduino IDE, how to acces and configure all pins
I recently got a Microchip Fubarino, contains a PIC32MX250F128D and I'm totally new to the Arduino IDE, i uploaded the blink sketch all fine and well.
Schematic: FubarinoMini_v15_sch
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
//pinMode(LED_BUILTIN, OUTPUT);

//asm ("BSF PORTA,10");
//pinMode(RA10, OUTPUT);
//TRISA10 = 0;
TRISAbits.RA10 = 0;
//PORTAbits.RA10 = 1;
//PORTAbits.RA10 = 0; // set to output
//mapPps(20, PPS_OUT_SDO2)
}

// the loop function runs over and over again forever
void loop() {
//digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
PORTAbits.RA10 = 1;
delay(500); // wait for a second
//digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
PORTAbits.RA10 = 0;
delay(500); // wait for a second
}

restults in:
 Blink:45:12: error: 'volatile union __LATAbits_t' has no member named 'RA10'
LATAbits.RA10 = 0;

changing:
void loop() {
  //digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  PORTAbits.RA10 = 1;
  delay(500);                       // wait for a second
  //digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  PORTAbits.RA10 = 0;
  delay(500);                       // wait for a second
}

doesn't work either.
I also tried this example code:
https://github.com/fubarino/fubarino.github.com/wiki/Fubarino-Mini-pps
It does work.
#define LED 1
#define SCK2 4
#define SDI2 18
#define SDO2 20

The led on the Fubarino board is not connected to pin 1, but to RA10.
Pin 18 is the MCLR on the device, reviewing the datasheet you can't even set SDI2 & SDO2 to the above defined numbers.
Normally on a PIC16F84 or so, you would do something like this.
bank1
movlw b'00000001'
movwf TRISA

movlw b'11110000'
movwf TRISB
bank0

the Arduino "code" seems a bit abstract.
I Would like to experiment with the button.
The Chipkit pps example shows you can use the Microchip keywords from the devices datasheet.
Can the Fubarino be setup like a classic PIC device in the Arduino IDE?
Configuring all the pins before going in to loop, using the Keywords from the datasheet.

BTW, it's not a Microchip Fubarino. The Fubarino is made by Fubar Labs. Jacob would be furious if you tried claiming he was Microchip ;)

@Majenko, this is when i found the schematic from the board that's all i "knew/know", the microchip box that it came said chipkit, as does the Arduino IDE. however the schematic on the page of Microsoft is the same and the file name says that, witch i downloaded from microchip. By: Brian Schmalz and Rick Anderson
what is it?
further: 02/25/2013 - Microchip version
Changed USB connector to Microchip standard
Added CE, RoSH, and chipKIT graphics to silk on back

chipKIT was originally formed as a collaboration between Microchip and Digilent. Since then both have pretty much divested their interests in it and chipKIT is now a standalone entity, consisting of a number of dedicated community engineers (me, Jacob, Brian, Rick, Guy, etc), some ex-Microchip employees, some just people that love the PIC32 chips, like myself. Anyone can make a board that works with chipKIT, but to use the chipKIT name you have to have a trademark agreement with Microchip (we're trying to get control of the name from Microchip but they are dragging their heels).

The three main board makers now are myself (the chipKIT Lenny for example), Brian (Schmalzhaus boards, like the Quick240) and Jacob & Rick (Fubar Labs, the Fubarino boards). Most of the original boards (UNO32, MAX32, etc) were made by Digilent. I'm not sure if they're still making and supporting those or not. Many of the boards have been sold via Microchip's market place (who have also provided some manufacturing facilities in the past too) although they seem to have lost interest in that now.

Ever since Microchip bought Atmel they seem to have lost interest in chipKIT and focus all their attention on Atmel based Arduinos now. Even though the PIC32 is by far a vastly superior chip and the chipKIT framework boasts a much better codebase than Arduino ;) The main problem we are facing at the moment though is that of a compiler - Microchip have traditionally provided us with an open source version of their XC32++ compiler, but since OS X went 64-bit only they have really struggled with producing a new version for us.

I'm in the process (slowly) of adapting vanilla mips-gcc to work properly with chipKIT but it's a long hard job. The compiler part is fine, it's the low-level chip support libraries that are not simple, especially for the more complex PIC32MZ chips.

i made a midi sequencer with 23LC512 sram using a PIC18F452, by far not a consumer product, but it was 100% accurate in tempo or  synced to Albeton to what ever speed up to 999 BPM, 8 steps + button and leds, the statemachine i made was brilliant. but the 74hc595 and 74hc126 are kinda slow, used a microchip picdem 2 plus board.    but now i'm back newby again ... i love that i have a microchip programmer ICD3, i like PICs.

The entries in the "bits" structures are named after the bits.
It's not
TRISAbits.RA10

but
TRISAbits.TRISA10

The same goes for
LATAbits.LATA10

The only exception is the "port" one
PORTAbits.RA10

Which is a hangover from the old PIC16 chips that didn't have a LATx register.

The led on the Fubarino board is not connected to pin 1, but to RA10.

Pin 1 is RA10. If you look in the file Board_Data.c for the Fubarino_Mini variant (packages/chipKIT/hardware/pic32/2.1.0/variants/Fubarino_Mini/Board_Data.c) you can see all the pin mappings. There's a bunch of arrays there that define how everything fits together.
The second entry in most of those arrays (pin 1, starts counting at 0) is for RA10.  As for

Pin 18 is the MCLR on the device, reviewing the datasheet you can't even set SDI2 & SDO2 to the above defined numbers.

the PPS is a whole other mess on those chips. Pin 18 is not the 18th pin on the board, but digital IO pin number 18, which is the 19th entry in those pin array tables - RA4.  Mapping RA4 is done through the file packages/chipKIT/hardware/pic32/2.1.0/cores/pic32/pps/pingroups_1xx2xx.h which contains an entry:
#define _PPS_RPA4       (2 + _PPS_SET_C)

and the file packages/chipKIT/hardware/pic32/2.1.0/cores/pic32/pps/peripherals_1xx2xx.h which has:
PPS_IN_SDI2     = (35 + _PPS_SET_C + _PPS_INPUT_BIT),

Those are then used by the mapPps() function to map RA4 to SDI2. Something which is perfectly possible.
Yes, it's convoluted and a bit of a mess, but the best we could come up with given how limited the PIC32MX2xx IO multiplexer is.

Comments are not for extended discussion; this conversation has been moved to chat.


text:
ESP8266 NODEMCU V3 web server with MAX7219 and DS3231 RTC
I am using ESP8266 NodeMCU with MAX7219 and a DS3231 teal time clock. I want to display the time and some text. The display is made of 4 FC16 modules which are made of 4 8x8 MAX7219 led matrix modules so it would be a 32x32 led matrix diplay divided in 4 rows.
I am displaying the time hh:mm on the last row and text on the first 3 rows.
With ESP8266 I connected to my wi-fi and I created a web server which says "Hello World!"
So my question is: how do I upload my code to the web server so I can change the text remotely?
I found this tutorial https://maker.pro/esp8266/tutorial/how-to-build-an-led-matrix-display-with-a-nodemcu-esp8266 that shows how to change the text on one row of display but I don't want something that fancy. I just want my code uploaded and to be able to change in the code.
#include "RTClib.h"
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server;

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 12
#define NUM_ZONES 3

int CS_PIN = D4;
int CLK_PIN = D5;
int DATA_PIN = D7;

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

uint8_t lastUpdateMin = 0;
uint8_t lastUpdateHour = 0;

// Global variable
const char  *pc[NUM_ZONES] =
{
  "TIME", //0
  "ROOM", //1
  "SUBJECT", //2
  //"GRADE",//3
};

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

  WiFi.begin("ssid", "password");

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/", []() {
    server.send(200, "text/plain", "Hello World!");
  });
  server.begin();

  P.begin();
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    //     If the RTC have lost power it will set the RTC to the date & time this sketch was compiled in the following line
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  P.begin(3);
  P.setZone(0, 0, 3); // Modules 0-3 in zone 0
  P.setZone(1, 4, 7); // Modules 4-7 in zone 1
  P.setZone(2, 8, 11); // Modules 8-11 in zone 2
  // P.setZone(3, 12, 15); // Modules 12-15 in zone 3
}

void loop(void)
{
  server.handleClient();
  DateTime now = rtc.now();
  if (lastUpdateMin != now.minute()) { // change every minute
    lastUpdateMin = now.minute();
    char buffer[] = "hh:mm";  // hours and minutes
    P.displayZoneText(0, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
  }
  if (lastUpdateHour != now.hour()) {   // change every hour
    lastUpdateHour = now.hour();
    P.displayZoneText(1, pc[1], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);  // 2nd row
    P.displayZoneText(2, pc[2], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);   // 3rd row
    //   P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 4th row
  }
  P.displayAnimate();
}

if you want to upload the sketch over WiFi, use the ArduinoOTA library. you don't need a webserver for that. see the example in the IDE Examples menu.

you want to send text to be shown over http? just take a GET param in your server.on and feed it to the P.displayZoneText function

I want things to work the other way around. From the web server I want to be able to change the text zones in my code.

In that case add a PUT or POST param in your server.on. When you want a website to type the data in, you could rely or HTML forms (I think) and/or javascript to send a post request to the server, when the submit button is clicked


text:
How can I measure maximum range of my ohm meter?
Hello everyone I am working on a project that will measure ohm value of a resistor .
Schematic / article link
https://create.arduino.cc/projecthub/iasonas-christoulakis/how-to-make-an-arduino-ohm-meter-90fda8
And
Here is the code below
int analogPin= 0;
int raw= 0;
int Vin= 5;
float Vout= 0;
float R1= 1000;
float R2= 0;
float buffer= 0;

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

 void loop()
{
raw= analogRead(analogPin);
if(raw)
{
buffer= raw * Vin;
Vout= (buffer)/1024.0;
buffer= (Vin/Vout) -1;
R2= R1 * buffer;
Serial.print("Vout: ");
Serial.println(Vout);
Serial.print("R2: ");
Serial.println(R2);
delay(1000);
}
}

There need to be a known and another unknown resistor.
The ohm value of known resistor is supposed to be 1k ohm
So my question is, what is the max ohm range will my arduino ohm meter be able to measure of the unknown resistor with 1k reference resistor and how to calculate it?
5 - 10% accuracy is enough for me
Thanks for giving me your attention :D

https://create.arduino.cc/projecthub/iasonas-christoulakis/how-to-make-an-arduino-ohm-meter-90fda8

Your question would make more sense if you gave an acceptable error percentage. You could read virtually any resistor, it just might be 100% wrong. Would 50% do? How about 10%? 1%?

@Nick Gammon almost 5% to 10%

Your resolution of the ADC (the analogRead) will be 1/1024 * 5V (since you get a reading in the range 0 to 1023), that is, you can tell the difference in increments of 5/1024 which is 0.00488V, so say roughly 0.005V.
Now, I wrote a little bit of code to work out the voltages that you would get with various values for your varying resistor:
r1 =      0, v = 5.000
r1 =    100, v = 4.545
r1 =    200, v = 4.167
r1 =    300, v = 3.846
r1 =    400, v = 3.571
r1 =    500, v = 3.333
r1 =    600, v = 3.125
r1 =    700, v = 2.941
r1 =    800, v = 2.778
r1 =    900, v = 2.632
r1 =   1000, v = 2.500
r1 =   1100, v = 2.381
r1 =   1200, v = 2.273
r1 =   1300, v = 2.174
r1 =   1400, v = 2.083
r1 =   1500, v = 2.000
r1 =   1600, v = 1.923
r1 =   1700, v = 1.852
r1 =   1800, v = 1.786
r1 =   1900, v = 1.724
r1 =   2000, v = 1.667
r1 =   3000, v = 1.250
r1 =   4000, v = 1.000
r1 =   5000, v = 0.833
r1 =   6000, v = 0.714
r1 =   7000, v = 0.625
r1 =   8000, v = 0.556
r1 =   9000, v = 0.500
r1 =  10000, v = 0.455
r1 =  20000, v = 0.238
r1 =  30000, v = 0.161
r1 =  40000, v = 0.122
r1 =  50000, v = 0.098
r1 =  60000, v = 0.082
r1 =  70000, v = 0.070
r1 =  80000, v = 0.062
r1 =  90000, v = 0.055
r1 = 100000, v = 0.050
r1 = 110000, v = 0.045
r1 = 120000, v = 0.041
r1 = 130000, v = 0.038
r1 = 140000, v = 0.035
r1 = 150000, v = 0.033
r1 = 160000, v = 0.031
r1 = 170000, v = 0.029
r1 = 180000, v = 0.028
r1 = 190000, v = 0.026
r1 = 200000, v = 0.025
r1 = 210000, v = 0.024
r1 = 220000, v = 0.023
r1 = 230000, v = 0.022
r1 = 240000, v = 0.021
r1 = 250000, v = 0.020
r1 = 260000, v = 0.019
r1 = 270000, v = 0.018
r1 = 280000, v = 0.018
r1 = 290000, v = 0.017
r1 = 300000, v = 0.017

You can see that the difference in voltage is only 0.005V (the ADC resolution) between r1 of 90k and 100k. Further down, you can't tell the difference (within 0.005V) of 270k and 300k.
I'm not sure how to express that as an error percentage, perhaps someone better at maths than me can do that. :)

So does that literally mean that I can measure max 100k resistor with 1k reference resistor? Sorry to say but ur explanation has confused me a little bit.

I'm not saying that, but if you look at the voltage for 200k (0.025V) and 250k (0.020V), then you won't be able to tell the difference between 200k and (say) 220k. So you might say, for 200k that it would be +/- 50k. That is your error amount. So you could measure a 200k resistor, but the error amount would be 50/200, that is 25%. Now for 100k, it would appear to be 10/100, or 10%. Subject to my arithmetic being right, that would seem to indicate that 100k is about your limit, if you want 10% accuracy or better.

There would be a reason why cheap multimeters want you to choose a range for resistance measurement, they probably swap in an appropriate reference resistor to give a reasonable error amount for the range you are measuring.

Ok thanks , getting it clear now

Even the very expensive ohm meters switch range, it may be transparent to you but they do. I have repaired and calibrated many over the years and they all did it.

How? I suppose one way would be to have half a dozen reference resistors, and use a MOSFET to switch the signal being measured into one rather than the other (in other words, multiplex it).

@Nick, yes I am working on a auto ohm meter with my UNO , some MOSFET and resistors of 1k 22k 47k 100k and 220 k which's maximum range should be 1m+ . All u have to do is that, get values from reference resistor then logically edit it, to switch them automatically