text:
Connecting multiple topics- MQTT
I'm configuring an ESP8266 using Arduino Uno.
I have several MQTT topics I wish it to subscribe, and I do not want to repeat code 3 or 4 times ( in Python I would have created a list - and make a for loop to subscribe all )
These are my topics:
//MQTT topic
const char* deviceName = "Sonoff1";
const char* deviceTopic = "HomePi/Switches/Sonoff1";
const char* msgTopic = "HomePi/Messages";
const char* groupTopic = "HomePi/All";

This is the function registering a single topic:
void reconnect() {
        // Loop until we're reconnected
        while (!client.connected()) {
                Serial.print("Attempting MQTT connection...");
                // Attempt to connect
                if (client.connect(deviceName,user, passw)) {
                        Serial.println("connected");
                        pub_msg("Power On");
                        client.subscribe(deviceTopic);
                } else {
                        Serial.print("failed, rc=");
                        Serial.print(client.state());
                        Serial.println(" try again in 5 seconds");
                        // Wait 5 seconds before retrying
                        delay(5000);
                }
        }
}

Appriciate you kind help,
Guy

make an array and use a for loop

just for a closure:
added an array (thank to Juraj):const char* topicsArry[]={deviceTopic, msgTopic, groupTopic, "HomePi/Dvir/Clock", "HomePi/Dvir/Alerts"};
a for loop to over this that loop, and using sizeof ( which was not trivial for me ), led to :
void reconnect() {
        // Loop until we're reconnected
        while (!client.connected()) {
                Serial.print("Attempting MQTT connection...");
                // Attempt to connect
                if (client.connect(deviceName,user, passw)) {
                        Serial.println("connected");
                        pub_msg("Power On");
                        for (int i=0; i<=sizeof(topicsArry)/sizeof(char *); i++){
                          client.subscribe(topicsArry[i]);
                          char msg[50];
                          sprintf(msg, "Subscribed to %s",topicsArry[i]);
                          pub_msg(msg);
                        }
                } else {
                        Serial.print("failed, rc=");
                        Serial.print(client.state());
                        Serial.println(" try again in 5 seconds");
                        // Wait 5 seconds before retrying
                        delay(5000);
                }
        }
}

You can make life easier if you arrange your topic names hierarchically.
As an example suppose we have a multimedia controller that accepts various commmands:

mediaserver/set/volume
mediaserver/set/pause
mediaserver/set/audio/source
mediaserver/set/video/subtitles
etc...

You can then subscribe to "mediaserver/set/#"
For looping over the array of topics, you can take advantage of modern C++'s range-based for loop:

https://en.cppreference.com/w/cpp/language/range-for

Example code:
const char *topicArry[] = {
    deviceTopic, msgTopic, groupTopic,
    "HomePi/Dvir/Clock", "HomePi/Dvir/Alerts"
};
void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect(deviceName,user, passw)) {
            Serial.println("connected");
            pub_msg("Power On");
            for (const char *topic : topicsArry) {
                client.subscribe(topic);
                char msg[50];
                sprintf(msg, "Subscribed to %s",topic);
                pub_msg(msg);
            }
        } else {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}


text:
Passing a two dimensional array to a function
I'm working on an led matrix project where I'm running a series of patterns made of bitmap frames.
Here's an example: https://vimeo.com/564184465
Right now I'm using a series of method calls named per pattern to run the animation:
void CSMatrix::runPattern(PATTERNS pattern, uint8_t totalRuns)
{
  for (uint8_t i = 0; i < totalRuns; i++)
  {
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runPatternSpacedStripes();
      break;
    case PATTERN_ARROW_UP:
      runPatternArrowUp();
      break;
...
    }
  }
}

void CSMatrix::runPatternSpacedStripes()
{
  for (uint8_t i = 0; i < SPACED_STRIPES_LEN; i++)
  {
    renderFrame(SPACED_STRIPES[i]);
    FastLED.show();
    delay(100);
  }
}

void CSMatrix::runPatternArrowUp()
{
  for (uint8_t i = 0; i < ARROW_UP_LEN; i++)
  {
    renderFrame(ARROW_UP[i]);
    FastLED.show();
    delay(100);
  }
}

...

And the bitmaps used to control the matrix pixel states look like this (the functions beneath renderFrame basically say "if it's a 1, use this color, if it's a 0, use that color":
const byte SPACED_STRIPES[][8] = {
    {0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000},
    {0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100},
...
};
const int SPACED_STRIPES_LEN = sizeof(SPACED_STRIPES) / 8;

This is working fine, but having a bunch of identical methods to run each pattern is not great.
So, with this working I decided to refactor to make a common runTwoColorPattern method that could accept the pattern frames and the length to run the given pattern:
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(frames[i]);
    FastLED.show();
    delay(delayDuration);
  }
}

The problem I'm running into is figuring out how to properly pass the two dimensional array to the function.
I tried updating my switch statement by passing the pointer of SPACED_STRIPES into the runTwoColorPattern:
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runTwoColorPattern(SPACED_STRIPES, SPACED_STRIPES_LEN, 100);
      //runPatternSpacedStripes();
      break;

But when I do I get the error

argument of type "const byte (*)[8]" is incompatible with parameter of type "const byte *"C/C++(167)

I've found that I can correct this by dereferencing the first item of the multidimensional array, (which would mean I'm passing the memory address to the first pointer element of the multi-dimensional array (I think)), but when I do this the pattern runs backwards and is jittery :|
https://vimeo.com/564184624
I'm not totally sure how to correct this. I'm still fairly new to pointers so I'm sure there's something I'm misunderstanding with passing a pointer for a multi-dimensional array, but I thought what I was passing was basically an address of where to start for the pointer, so I'm not sure why I'm hitting these snags or how to fix it.
Any suggestions?

You really don't need a 2D array for this - a simple 1D one will do and just use multiple-of-8 offsets to read each frame.

Aaaaaah that's true! I was running with this format b/c it was easy to visually parse and adjust the bitmaps by hand after generating them from an online calculator, but ultimately that format isn't needed. So to restate to make sure I understand: I can make a 1d array where each element is a single number representation of the frame and those numbers can be parsed 8 bits at a time to get the rows within the frame, right?

No, you'd just have a big "blob" of 8 bit values. Exactly as you have now, but without the },{ between each frame. Then frame 0 starts at offset 0. Frame 1 at offset 8. Frame 2 at offset 16, etc. Basically &frames[i * 8]

ah, even simpler. I'll give it a try and when i have it working I'll post an answer. Thanks for the help!!

A 2D array would be passed as const byte frames[][8]. However you really don't need the complexity of a 2D array - you can do it with a 1D array.
Your array would look like:
const byte SPACED_STRIPES[] = {
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,

     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
...
};

And you reference frames within it as a multiple of 8 of the index.  Using your existing code it would look like:
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(&frames[i * 8]); // Take the address of the first value of the frame at a multiple of 8
    FastLED.show();
    delay(delayDuration);
  }
}

Awesome, this worked! I updated my pattern and the method and now the animations are running as expected. Implementing the changes also helped me understand exactly what you were going for; the structure of the multi-dimensional array helped me visually, but isn't necessary for the parsing. The other added benefit of doing it this way is that now that it's a flat array I can send through arbitrary sized blobs for different sized matricies (16x16, 32x32 ...) and just parameterize the multiplier for grabbing the pointer index. Thanks again for the help!

Re “const byte *frames[8]”: you mean const byte (*frames)[8].

@EdgarBonet I have never seen that format before in my life. I actually meant frames[][8]. Is (*frames)[8] some newer C++ syntax that didn't exist when I was taught C at uni?

AFAIK, (*frames)[8] is ANSI C, maybe even K&R C.

Well, I have only ever come across brackets like that when working with function pointers.

@EdgarBonet I have been scouring the interwebs, and I have found exactly one example using that format, with no explanation of what it is or how it works. I found one that uses (*name)[X][Y], which claims to be passing a pointer to a 2D array, and that I can completely understand. I think (*name)[X] is passing a 2D array as a pointer to a 1D array. Valid, but kind of a hack. Nowhere seems to use it, all examples either being *name[] or **name, or name[][X]

You will find a couple of examples, with explanation, if you search for “C pointer to array” on stackoverflow. It's not a hack, it's standard syntax, albeit confusing enough for most people to avoid it. name[][X] is implicitly translated by the compiler into (*name)[X], but this translation is done only within function parameter declarations. See also How do I declare a pointer to an array? and How to pass a two-dimensional array in the C FAQ.

The error message is quite explicit:

argument of type "const byte (*)[8]" is incompatible with parameter
of type "const byte *"

If you want to pass SPACED_STRIPES to the method, it is going to be
passed as const byte (*)[8], i.e. pointer to arrays of 8 byte. You
can just set the parameter type accordingly:
void CSMatrix::runTwoColorPattern(
    const byte (*frames)[8], const int length, int delayDuration)
{
    // body unchanged
}

Thanks for this answer. I ended up going with the suggestion to simplify the array, but this answer helps me understand the error I was getting. I didn't realize I could write the method signature with the parens around the pointer.

source: Stack Exchange

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

sort: votes


text:
Issues converting an uint32_t into a char*
I'm using a capacitive touch sensor that as 12 touch points and stores it's state data as a binary number.

I want to take that state, add a bit of data onto the front, and then send it up to a server via websockets. I'm using the Arduino Websockets library for my websocket client.
The library has a sendBinary method that allows you to provide a character pointer for the data.

So, I wrote a function that makes a new 32 bit unsigned integer, adds my metadata, then the touch state, and then attempts to take the address of the payload integer and cast it to a character pointer:
void sendTouchStateToServer()
{
    Serial.println("sending state to server");

    uint32_t payload = touchControllerMessageType << 12;
    Serial.println(payload);
    payload |= currentTouchState;

    Serial.print("Payload contents: ");
    Serial.println(payload);
    Serial.print("Payload contents cast as character pointer: ");
    Serial.println((char *)&payload);
    Serial.print("Payload size: ");
    Serial.println(sizeof(payload));

    client.sendBinary((char *)&payload, sizeof(payload));
}

The issue is that while the integer version of the payload looks fine, when I try to cast it into a character pointer the contents is wrong.

I've also tried creating a payloadPointer and directly set the address of the integer as the pointer address, but this also fails.

(I should take this moment to say I'm still pretty green to arduino cpp concepts like this).
What's the right way of doing this? I'm reading up on pointers and trying to understand how to properly do it, but I can't quite figure it out. Could someone explain the correct way of doing it and why? I want this to work, but more than that I want to understand the "why and how" of the proper way.
Thanks! :bows:

Are you trying to send the {metadata, payload} as a string of characters? Converting the payload by casting it doesn't do what you want it to. If so, you need build the string in a buffer (char[]), convert or copy the metadata into that buffer,  convert (not cast) the data from integer to its string representation, append that string to the buffer, and finally, pass the address of the buffer (that's the (char *) you need) to the function expecting chars. Casting an int to a (char *) doesn't change it; it tells the compiler to consider this to be a pointer to characters - which it isn't!

When sending binary data, use Serial.write(), not Serial.print(). The latter is only for ASCII encoded data

Related: How can i convert a uint32_t to a char* type.

Your code with sendBinary is probably fine, as long as on the other side you also use a function that expects to receive exactly 32 bits of binary data (in little-endian format).
Trying to print (char*)&some_32bit_int on the other hand will not do anything useful.
The short version is this:

if you want to send (or receive) binary data, use functions made for binary data - they will usually take a pointer to char (or uint8_t or something like that) and a length.
if you want to send (or receive) strings, use functions meant for strings. They'll sometimes take String, or std::string or, unfortunately perhaps, char * for C strings.

Never mix both.
Functions that expect a (C) string expect it to actually be a C string, i.e. a sequence of chars ending with a null byte (0x00). The chars are expected to be mostly ASCII printable characters. If you give them just plain raw data like the memory address of an int, you won't get what you want.
Trying to print raw data using a function that expects a C string will result in garbage (or nothing at all, or a lot more garbage than you expected!). (Details in the second part.)
If you want to format your data into a string for sending (using a string/text protocol), then use functions like sprintf to do the conversion. (Or use a library that does JSON if your receiver is a web thing - that's pretty handy.)
e.g.
char buffer[32];
sprintf(buffer, "{data:%d}", payload);

Then send buffer via a function that expects a C string.

Consider this:
uint32_t payload = 0x00323130;

The first line initializes a 32 bit int to a specific value, 0x00323130 in hex. Now let's assume that payload was stored in memory at address 0x0100. The memory after that assignment would look like this:
Addr.  Val
0x0100 0x30  // our same number 0x00323130 stored in little-endian format
0x0101 0x31
0x0102 0x32
0x0103 0x00

When you do:
client.sendBinary(&payload, 4);

Those four bytes get send over the wire (or the air) exactly as they are. Nothing more, nothing less. If that's what the receiver expects you're golden.
Now if you do:
Serial.println((char *) &payload);

Serial.println is an overloaded function. When you give it a char *, it expects a C-string, which is a series of characters terminated by a "null byte", i.e. a byte value of zero. Serial.println will then look at the first byte pointed to by the argument. If it's zero, it stops. Otherwise it outputs that char to the serial line, and moves on to the next character. Repeat until a zero byte is found.
In the specially crafted case here with that specific value of payload, Serial.println would receive address 0x0100 and:

Look at the value at 0x0100, get 0x30, check that it's not zero, and pass it on to the serial line. Serial monitor would receive 0x30 and display that. By lucky coincidence this is the ASCII character code for the digit "0".
Look at the value at 0x0101, get 0x31, check that it's not zero, and pass it on to the serial line. Serial monitor would receive 0x31 and display that. By lucky coincidence this is the ASCII character code for the digit "1".
Look at the value at 0x0102, get 0x32, ... serial monitor displays "2".
Loot at the value at 0x0103, get 0x00. That is a null byte, so it stops there, and sends a newline sequence to the serial.

So in this fabricated scenario the output on the serial monitor would be "123".
Try it with payload = 0x00616263; - serial monitor will display "cba".
In short, Serial.println will output exactly the bytes it finds in memory to the serial, until it encounters a zero byte. The serial monitor will try to display those bytes. But, unless you've crafted those values very carefully, all you'll get out of it is garbage - relatively few 8bit values map to printable characters, and even when they do they won't "look" anything like the raw data you had.
If your number happens to start with a zero byte in its binary little-endian representation, Serial.println won't print anything - like if you had given it an empty string.
If your number doesn't contain a zero byte, it will keep on reading memory past the storage allocated for payload until it finds one - possibly outputing much more "junk" than a 32bit variable could ever contain.

Excellent, thorough answer. (Voted)

Wow, this answer was fantastic! Thanks for taking the time to write this out. This makes a lot of sense. I'm going to do some c++ exploration outside of my arduino so i can do some memory inspection (I don't have the tools to do JTAG debugging). Thanks again for the answer!

The sending with client.sendBinary((char *)&payload, sizeof(payload)); is OK.
Your attempts to print binary data are wrong.
A print() of the 4 bytes of uint32_t as char array will print 4 characters which ASCII codes are in those 4 bytes and then continue print characters from memory after the variable, until a byte with 0 is read. Some of the characters can be a not printable terminal control characters.
A Serial.write((char *)&payload, sizeof(payload)); will print 4 characters which ASCII codes are in those 4 bytes.
The simplest way to visualize your binary payload is Serial.println(payload, BIN);. This will print the uint32_t value in binary.

Awesome. Thanks for the answer. It's good to know about the binary formatting :clap:

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


text:
fail to pass a value in constructor
I'm making a JSON lib dedicated for my own needs, based on ArduinoJSON v6.
I try to define StaticJsonDocument<_docSize> doc in a parametric way but I get this error and I cant find the reason for it:
/Users/guy/git/Arduino/libraries/myJSON/myJSON.cpp: In constructor 'myJSON::myJSON(char*, int, bool)':
/Users/guy/git/Arduino/libraries/myJSON/myJSON.cpp:12:28: sorry, unimplemented: use of the value of the object being constructed in a constant expression
         StaticJsonDocument<_docSize> doc;
                            ^
/Users/guy/git/Arduino/libraries/myJSON/myJSON.cpp:12:36: error: 'this' is not a constant expression
         StaticJsonDocument<_docSize> doc;
                                    ^
/Users/guy/git/Arduino/libraries/myJSON/myJSON.cpp:12:36: note: in template argument for type 'unsigned int'
/Users/guy/git/Arduino/libraries/myJSON/myJSON.cpp:12:41: error: invalid type in declaration before ';' token
         StaticJsonDocument<_docSize> doc;
                                         ^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

I paste only relevant part of the code
myJSON.h :
#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"

class myJSON
{
private:
int _docSize=100;
bool useSerial;
char _filename[30];

public:
myJSON(char *filename, int docsize, bool useserial=false);
bool file_exists();//char *file=_filename);
bool file_remove();
bool format ();

};
#endif

myJSON.cpp:
#include "Arduino.h"
#include "myJSON.h"
#include "FS.h"
#include <ArduinoJson.h>

myJSON::myJSON(char *filename, int docsize, bool useserial) {

        _docSize = docsize;
        useSerial = useserial;

        StaticJsonDocument<_docSize> doc;

        if (useSerial) {
                Serial.begin(9600);
        }
        if (!SPIFFS.begin()) {
                if (useSerial) {
                        Serial.println("Failed to mount file system");
                }
        }
        else{
                sprintf(_filename,"%s",filename);
        }
}

A class that uses <...> is called a template class.  That class uses a form of substitution at compile time to create a concrete class with those values and tokens substituted.
It is then that concrete class that is used to instantiate your object(s).
However, you are trying to use a runtime variable to convert a template class into a concrete class, and that can't be done at compile time - and there is no such thing as a runtime template in C++.
You need to re-think your implementation methodology.

thank you for explaining.  My intention is to to be able to define size of JSON buffer- is there a way doing so the way I need it ?

I would suggest create the JSON object outside your class and pass that object to the constructor. Without knowing what ArduinoJSON does with the buffer and how it's instantiated I can't comment.

OK-  that it was a good enough workaround. TNX


text:
Passing out an argument
I can't figure out why test is not passed properly to test1
#include <Arduino.h>

char *test1;
char *status_reply(char *test) {
        int ans_rel = 1;
        int ans_led = 0;
        int ans_sw = 1;
        sprintf(test,"%d%d%d",ans_rel,ans_sw,ans_led);
        Serial.println(test);
}

void setup() {
        Serial.begin(9600);
        status_reply(test1);
        Serial.println(test1);
}

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

While commenting on an answer to a previous question of yours, I suggested you read the section Arrays and Pointers of the C FAQ. Judging from from this new questions, it seems you failed to do so. Please, read it! Otherwise you will spend lots of time asking here related (and off-topic) questions.

@EdgarBonet well I did read it. I must say that the main purpose or motivation of declaring a char as char* - is quite unclear

To be clear- I understand the technicalities of such definitions, but not when or why to use each one of them. It is a whole different from Python

This is not about Arduino. It is C. You have only a pointer to char now. You must allocate memory for the c-string.
char test1[128];
If you pass pointer to sprintf, the function will write to memory where the pointer points. Something somewhere in memory will be overwritten and the following print will print the string, but later the memory will be used for something else and your c-string disappear.

thank you. There's something I'm missing : 1) In any other case if I would init char *test1="hello world" at the beginning, and print it Serial.println(test1) - I would have get proper value. 2) In code here - when I create test inside it does print it as expected, but not passing its value to test2 ?

char *test1="hello world" would be a pointer to a global allocated constant c-string and should be const char *test1="hello world". I enhanced the answer.


text:
Assign a list of char *
Explain in a simple example. How to pass a char* to a function?
#define name1 "ABCD"
#define name2 "EFGH"
#define name3 "HIJK"

char *list[3] = {};

void printList(char *l, int x) {
  for (int i = 0; i < x; i++) {
    Serial.println(l[i]);
  }

}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("start");
  list[0] = name1;
  list[1] = name2;
  list[2] = name3;

  printList(list, 3);

}

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

}

I get an error:
/home/guy/Documents/Dropbox/Arduino/sketch_jun12a/sketch_jun12a.ino: In function 'void setup()':
sketch_jun12a:24:13: error: cannot convert 'char**' to 'char*'
   24 |   printList(list, 3);
      |             ^~~~
      |             |
      |             char**
/home/guy/Documents/Dropbox/Arduino/sketch_jun12a/sketch_jun12a.ino:7:22: note:   initializing argument 1 of 'void printList(char*, int)'
    7 | void printList(char *l, int x) {
      |                ~~~~~~^
exit status 1
cannot convert 'char**' to 'char*'

You're trying to pass an array of char * to a function that is expecting a single char *.

@Majenko AFAIK anyway you pass only  pointer for the first cell of the array,  or am I wrong ?

Just change this:
void printList(char *l, int x) {

to this:
void printList(char **l, int x) {

OK, this deserves some explanation...
In C and C++, when you use (not when you define) an array
identifier, it decays to a pointer to its first element. In
this case,
char *list[3] = {};

is an array of pointers to char. When you use it here:
printList(list, 3);

it decays to a pointer to pointer to char. Thus the double * needed
in the parameter declaration.
Side note: to get really correct C++, you should replace every
instance of char by const char. This is because the characters in
question belong to string literals, and you are not allowed to modify a
string literal at run time.


text:
Watchdog Timer for atmega 128
I am using atmega 128 for a smart vehicle tracker. I am trying to use watchdog timer for this controller.But problem is that I have found the maximum watchdog reset time is 2 seconds. I need watchdog reset time 8 seconds. Now what can I do ?

Run it 4 times to get 8 seconds.

Any other way ??

Sorry. I assumed you used the watchdog to wake up the MCU after sleep. Apparently the 128 doesn't even support that. The only option would be to change your code, so wdt_reset gets called more often and make sure there are no delays/waits/timeouts longer than 2 seconds. 2 seconds is quite a long time for a processor. What's your code doing that it requires more than 2 seconds?

There is no way you can make the Watchdog timer longer on Atmega 128. It is max 1.8 sec if you set all 3 bits of Timer Prescaler.
For Atmega 328 the max watchdog time is 8 sec and longer time can be achieved using  watchdog interrupt and count up (or down) until you want a reset and then force the reset by setting the shortest watchdog timer.
Atmega 128 doesn't support watchdog interrupt, so the trick with interrupt can't be used.


text:
Adding RTC Library for Arduino Project in Visual Studio
I am working in an Arduino project in visual studio. I need to get and set time to a RTC clock. That's why I am adding a ds3231 header file in my project from GitHub. When I want to build "it's showing me linking error.
cccSeqVu.ltrans0.o*: (.text.startup+0x1ea): undefined reference to DS3231_init(unsigned char)

My code is given below.
   #include <Wire.h>
   #include "ds3231.h"

    void setup(){
        Wire.begin();
        DS3231_init(0x4);
    }

    void loop(){
    }

Can anyone please help me to find out what I have missed.

add the whole library, not just the header file

How to add the whole library in visual studio?

I don't know. I don't use platformio


text:
ATtiny85 - report error "Device reports version as: 2.2"
I've bought ATtiny, from see link.
Trying to upload a basic Blink sketch I get this error: Device reports version as: 2.2.
1) Board manager was updated using http://digistump.com/package_digistump_index.json
2) Board selected as Digispark (Default -16.5MHz )
3) Programmer set to Micronocleus
Tried using some guides on-line, but some were old, some were for windows, while I'm using Ubuntu machine.
Appreciate any help,
Guy

It sounds like you have a newer board than the version of Micronucleus in the Arduino package.
As I discovered here you basically need to upgrade micronucleus in your Ardino installation, which you can download from here

Download the zip file from Github and extract it.  Then in a terminal (if you're not already in one) go to the directory you extracted.
Build the executable by typing "make"
Copy the compiled executable to ~/.arduino15/packages/digistump/tools/micronucleus/<version>/

where <version> is the currently installed version number (e.g., 2.0a4).  There should already be a micronucleus executable in there that you would replace with your newly compiled one.

a `\2.04a' directory was inside that path you noted ( was added after adding digistumb's board manager

@Guy.D Where abouts in the path?

micronucleus after built was move to noted directory. But directory already contains an instance of micronucleus, inside a directory 2.0a4. Should I delete it ? ( didn't help ). Seemed that didn't matter

Replace the existing one with your newly compiled one

guy@desktop:~/.arduino15/packages/digistump/tools/micronucleus$ ls -l total 60 drwxrwxr-x 2 guy guy  4096 May  8 16:06 2.0a4 -rwxr-xr-x 1 guy guy 55616 May  8 17:40 micronucleus

after deleting I get this error msg: "
`java.io.IOException: Cannot run program "REMOVE/launcher": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:485)
at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:11)
at cc.arduino.packages.Uploader.executeUploadCommand(Uploader.java:129)
at
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 11 more
An error occurred while uploading the sketch'

Did you replace the existing one with the new one, or put the new one up a directory? I have modified my answer

I have deleted entire 2.04 lib, and pasted 1 executable file that was created by make

Make the directory again and move the file into it.

that solved it !!!! thank you !!!


text:
Detect if MCU is ESP8266 or ESP32
I'm coding a library which handles sleep procedures.
Since I'm using both ESP826 and ESP32, which uses different sleep commands ( and WiFi ), I'm looking for a way to detect the MCU, while NOT using a boolean flag that indicates so.
Guy

#if defined(ESP8266), #if defined(ESP32)

how could you use a boolean flag? the code for esp32 would not compile on esp8266 and vice versa

@Juraj the part that code differs, I need the flag for.

you have in the question "while NOT using a boolean flag that indicates so." so you exclude a not existing option

I take this to mean that you do not want to have to ask the user of the code to configure a boolean flag.
The ESP8266 Arduino package provides -DARDUINO_ARCH_ESP8266 -DESP8266
command-line options these while calling g++.  These effectively #define feature test macros as though they were at the beginning of the source code.
For ESP32 it does likewise with -DARDUINO_ARCH_ESP32 -DESP32
You could perform tests in your code such as:
#if defined (ARDUINO_ARCH_ESP8266)
// do one thing
#elif defined(ESP32)
// do another
#else
#error Architecture unrecognized by this code.
#endif

There are likely also macros like these that are predefined by the xtensa g++ compiler.


text:
Fail to convert time_T from past to tm struct
Continuing a Question asked few days ago, answered by Edgar, a new question has rised:
My goal was using a past time_t value, and convert it into a struct tm variable in order to  use it, part as a Char to print a readable text and some for logic queries.
At start NTP is configured as:
void myIOT32::startNTP(const int gmtOffset_sec = 2 * 3600, const int daylightOffset_sec = 3600, const char *ntpServer = "pool.ntp.org")
{
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

and every-time I need to get epoch and or struct tm of current time I call this function
void myIOT32::getTime()
{
  int a = 0;
  while (a < 3)
  {
    if (getLocalTime(&timeinfo))
    {
      delay(100);
      time(&epoch_time);
    }
    a++;
  }

BUT, when using the following function I get not GMT (+3) reference as needed :
struct tm *myIOT32::convEpoch(time_t in_time)
{
  struct tm *convTime = gmtime(&in_time);
  //char time_char[40];
  //sprintf(time_char, "%04d-%02d-%02d %02d:%02d:%02d", convTime->tm_year + 1900, convTime->tm_mon + 1, convTime->tm_mday,
          convTime->tm_hour, convTime->tm_min, convTime->tm_sec);
  return convTime;
}

Meaning I get to correct epoch time, but strcut tm is 3 hrs earlier ( and no, I do not want to hard-code +3... )

the Arduino and the NTP server don't know the time zone you are in. so create a constant and put it at the beginning of your sketch (yes, hardcode). why do you use the C time library? the TimeLib is much simpler to use

@Juraj - even tough it was config at the beginning when start NTP was executed ?

@Juraj  and the reason I do not want to hard code +3, is daylight saving...

in Europe it looks like we have only a few changes to/from DST before us. the date can be calculated. https://github.com/jandrassy/Regulator/blob/104421279aef672362bcff0baf7447410bc2b590/Regulator/Modbus.ino#L94

@Juraj Yes... that was my fallback. By the way, you asked about the reason not using TimeLib... since in example called "simpleTime" for ESP32 used dates that way ( and not as in ESP8266), so I guessed it is a compatibility issue.

replacing gmtime(&timeinfo) with localtime(&timeinfo) in myIOT32::convEpoch passes definition of time-zone as needed.
for more information in this cpluspls site


text:
ArduinoJSON v6 - Passing buffer as function parameter
I'm new to ArduinoJSON - so perhaps it is a newbie's question.... but I wish to pass a StaticJsonDocument into a function as a parameter ( later on it should be implemented in a library ).
exmaple below shows test_1 what I wish to obtain, but by duplicating StaticJsonDocument, which I don't want to do.
How can test_1 should be written (as I tried in test_2)?
#include <ArduinoJson.h>

StaticJsonDocument<200> doc;

void createJSON() {
        doc["sensor"] = "gps";
        doc["time"] = 1351824120;

        JsonArray data = doc.createNestedArray("data");
        data.add(48.756080);
        data.add(2.302038);

        // Generate the minified JSON and send it to the Serial port.
        serializeJson(doc, Serial);
        Serial.println("JSON is created:");

        // Generate the prettified JSON and send it to the Serial port.
        serializeJsonPretty(doc, Serial);

}

bool test_1(StaticJsonDocument<100> _doc){
        serializeJson(_doc, Serial);
        return true;
}

bool test2(const JsonObject& _doc){
        Serial.println("HI");
        serializeJson(_doc, Serial);
}

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

        createJSON();
        test_1(doc);

}

void loop() {
        // not used in this example
}

bool test_1(StaticJsonDocument<DOC_SIZE>& _doc) { use a define or const for the size. it must be the same

@Juraj - why not posting it as an answer ? it works OK

it is not about Arduino, but OK. I even found a better solution. (I know it is working, I tested it)

The StaticJsonDocument is a template class. The template value in <> is here only the size of the internal buffer, but every size used generates a different class. (memory usage!)
To have the parameter of the function take an StaticJsonDocument version instance, it must be the same version or a common base class. In this case the base class is JsonDocument.
If you don't use the reference symbol & the parameter is copied. In this case StaticJsonDocument<200> _doc or JsonDocument _doc would create a copy and that copy would be modified in the function. The object used as parameter value would be unchanged - empty.
So use
void test2(const JsonDocument& _doc) {
  Serial.println("HI");
  serializeJson(_doc, Serial);
}

Hey @Juraj, thanks for this answer. I'm trying to do exactly the same thing as @Guy .D, except when implementing your solution I'm getting a compiler error:
no known conversion for argument 2 from ArduinoJson6101_000::StaticJsonDocument<168u>' to 'const JsonObject& {aka const ArduinoJson6101_000::ObjectRef&}  Any advice would be great and I can post a code snippet if required.

yes I'm using ArduinoJSON V6.

sorry, the code snippet was from Guy's code, not from my test. corrected


text:
Arduino MEGA2560 wake up using DS3231 RTC
I am trying to set the Arduino MEGA 2560 R3 into sleep mode and wake it up with an RTC DS3231 via interrupt. I was following this tutorial:
Tutorial
One of the libraries included is the "LowPower" library, you can find it here on GitHub. It produces the following error while compiling:
C:\XX\Arduino\libraries\Low-Power-master\LowPower.cpp: In member function 'void LowPowerClass::idle(period_t, adc_t, timer5_t, timer4_t, timer3_t, timer2_t, timer1_t, timer0_t, spi_t, usart3_t, usart2_t, usart1_t, usart0_t, twi_t)':

C:\XX\Arduino\libraries\Low-Power-master\LowPower.cpp:562:49: error: 'power_usart3_disable' was not declared in this scope

  if (usart3 == USART3_OFF) power_usart3_disable();

                                                 ^

C:\XX\Arduino\libraries\Low-Power-master\LowPower.cpp:597:48: error: 'power_usart3_enable' was not declared in this scope

  if (usart3 == USART3_OFF) power_usart3_enable();

                                                ^

exit status 1
Error while compiling for Arduino/Genuino Mega or Mega 2560.

I dont understand why there should be any functions in the library, which are not declared...This would mean noone could use it?! I am not an expert in C++ so maybe one of you could tell me what the issue could be. I am glad for any help.

after further web research, it looks like this is a bug which hasnt been fixed yet.
it was discussed previously here and here.
My solution was to go into the "LowPower.cpp" scroll down to the lines, where the functions are not declared and I just out-commented them. Compiling works now.


text:
Error "avr-g++: error: CreateProcess: No such file or directory" When Compiling Script
Whenever I try to compile a script, the Arduino IDE throws the error avr-g++: error: CreateProcess: No such file or directory. I've already tried reinstalling the IDE, changing the board version in the board manager to 1.6.21, and deleting the Arduino15 folder under AppData/Local/Arduino15.
This problem appeared suddenly - one compilation worked, and two minutes later, nothing would compile - and occurs across all scripts that I've tried.
I'm working from Windows 10 and compiling for an Arduino Uno.

Antivirus playing merry hell with your installation?

Just checked my activity log and that's exactly what's going on. Thank you!

Turns out that McAfee's Host Intrusion Prevention had decided to start blocking avr-g++.exe. Not sure why it did so all of a sudden, but it's an easy fix once you know where to look. Anyone finding this in the future should be sure to check their antivirus logs to see if the compiler's executable is being blocked.

I seem to be having this issue as well, but it's not clear to me what I should do about it. Do I disable McAfee and then reinstall? Do I set the executable as an exception? I've never modified anything in McAfee so I need more information for this easy fix. Much obliged!

Setting the executable sounds reasonable. This part is really more to do with McAfee. I would expect McAfee's documentation is sufficient to answer this, but if not https://superuser.com/ is probably the place to ask that sort of thing.


text:
SG90 servo motor not working
I tried to test a servo motor for a project using this simple circuit but the motor won't move. I've used this before with the same setup and code and it worked, but now suddenly nothing works, even tried a different servo motor.
I have tried changing arduinos, changing signal pins , changing servos but nothing works. I had got them to work only a few days back but now suddenly i cant and i dont know where im going wrong.
here is my circuit :- image of circuit
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup()
{
myservo.attach(9);
}
void loop()
{
for (pos = 0; pos <= 180; pos += 1)
{
myservo.write(pos);
 delay(15);
}
for (pos = 180; pos >= 0; pos -= 1)
{
 myservo.write(pos);
delay(15);
}
}

you are like the guy that thinks of replacing an engine in an automobile before he thinks to check if there is any gas in the tank ...... have you checked the voltages on the power supply?

There's nothing wrong with your code. Check your wiring:

Servo brown  -> Gnd
Servo red    -> +5v (not +3v)
Servo Orange -> pin 9
Connections at the servo-connector and at the Arduino are electrically sound
Try swapping the 3 jumper wires (the only parts you didn't say you'd swapped)


text:
ESP8266 NODEMCU V3, HOW TO USE AND CONTROL V3 OUTPUT POWER
this is my very first post in here so I apologise if I am not giving you all the information that I should.
I am creating this topic to ask you help regarding how to control and use the v3 output of my Nodemcu.
I have a script which is working fine to power on and off a led by using one of the GPIO and the ground. However, my project requires to power on a small motor for about 2 seconds and then stop it. If I connect this motor to one of the GPIO and the ground I can control it but it runs very slow. If I connect the motor to the 3V output it goes fine but I can't turn it on or off. The motor requires 3V to run properly. How can I turn it on and off by powering it from that 3V output?
What am I missing?
I have a 4n25 chip which I saw in a video that has been used for a similar project however the vide is in Portuguese and I am not able to follow it properly.
Can please someone advice?
Thank you for your time,
Ade

I would suggest to control the motor using FET rather than directly attaching it ESP pin. As these pins cannot supply enough current and you can damage your ESP by doing this. So use FET for motor and control the FET using gpio's of ESP, that will turn ON and OFF the motor.

Guys, thank you very much for replying so fast.
Which one would you suggest?
IRFZ44 Power MOSFET TO-220
or
20pcs/lot 2n7000 To92 Small Signal Mosfet 200 Mamps, 60 Volts N-channel To-92

irLz44n is the the logic-level version of the ever-popular irF44n, and one i use with ESPs a lot. be careful ordering them from a cut-rate webfront or auction house though; i've gotten ones that clearly were out of spec from places like that.

You cannot control the "V3" output. It's a 3.3V power supply output. Think of it like a battery. It's always on and always giving power.
Instead, you need to add a "switch" to control that power that the ESP8266 can itself control, such as a MOSFET or a motor driver (H-Bridge).


text:
Getting two trinkets to talk to each other via the serial pins
I'm trying to make a quick proof of concept of two trinket M0s talking to each other via their RX and TX pins and I'm not able to get it working.
I uploaded sender and receiver sketches to two trinkets:
//sender.ino
char state[10] = "hello";

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

void loop()
{
    Serial.write(state, 5);
    delay(1000);
}

//receiver.ino
char state[10];

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

void loop()
{
    Serial.println("reading bytes");
    Serial.readBytes(state, 10);
    Serial.println(state);
    delay(1000);
}

After the uploads I wired the two trinkets together, jumping the RX of the first to the TX of the other and TX of the first to the RX of the other. I also connected their grounds to have a common ground.

I plugged the sender into a battery and the receiver into my computer. The problem I'm running into is that when I look at the serial monitor for the receiver instead of getting the expected "hello" I'm getting broken strings of "TestingOpen":

I double checked the pinout diagram and guide for the Trinket M0 to make sure I was using the correct RX/TX pins (pin 3 for RX, 4 for TX) and it all seems fine but obviously something is still going wrong.
Anyone know what I'm missing or misunderstanding?

1) you should use if (Serial.available()) before starting to read with readBytes. now you print random memory
2) readBytes is blocking. it waits for the next character until a timeout. default timeout is 1 second. after "hello" was received it waits a second. you could use readBytesUntil and some 'separator' character for example '\n' (new line)
3) readBytes returns the count of bytes read. you should use it to terminate the buffer
void loop()
{
  if (Serial.available()) {
    Serial.println("reading bytes");
    size_t l = Serial.readBytesUntil('\n', state, 10);
    state[l] = 0;
    Serial.println(state);
  }
}


text:
Having an issue accessing values from a pointer
Context
This may be more of a C++ question than an arduino specific question, but it's dealing with arduino c++ so I thought I'd start here.
I'm building a class to abstract some simple melody playing that I want for a project. I got everything working in a procedural way, so I started moving everything out to a header and cpp file (still new-ish territory for me).
The general concept is that I want to call a public method on my class to allow my code to play a specific melody. I defined an enum for each melody available and in my playMelody() method I'm using a couple of pointers and a switch statement to get the specific frequencies and durations I need to play the specific melody. These frequency and duration values are stored in private arrays in the class.
Here's the header:
// MelodyPlayer.h

enum MELODY
{
    SHAVE_AND_A_HAIRCUT = 0,
    IDLE,
    READY,
    PROCESSING,
    COMPLETE,
};

class MelodyPlayer
{
    uint8_t speakerPin;

    int melody_shaveAndAHairCut[9];
    int durations_shaveAndAHairCut[9];
    int *activeMelody;
    int *activeDurations;

    void _playMelody();

public:
    MelodyPlayer(uint8_t speakerPin);
    void playMelody(MELODY name);
};

MelodyPlayer::MelodyPlayer(uint8_t pin)
{
    speakerPin = pin;

    int melody_shaveAndAHairCut[] = {
        NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4, 0};

    int durations_shaveAndAHairCut[] = {
        4, 8, 8, 4, 4, 4, 4, 4, 4};
}

void MelodyPlayer::playMelody(MELODY name)
{
    switch (name)
    {
    case SHAVE_AND_A_HAIRCUT:
        Serial.println("Shave and a hair cut");
        activeMelody = melody_shaveAndAHairCut;
        activeDurations = durations_shaveAndAHairCut;
        break;
    }

    _playMelody();
}

And here's the implementation:
// MelodyPlayer.cpp

void MelodyPlayer::_playMelody()
{
    Serial.println("Playing Melody");
    // * pulled from the toneMelody arduino example
    for (int thisNote = 0; thisNote < 8; thisNote++)
    {

        int activeDuration = activeDurations[thisNote];
        int noteDuration = 1000 / activeDurations[thisNote];
        int noteFrequency = activeMelody[thisNote];

        Serial.println(thisNote);
        Serial.println(activeDuration);
        Serial.println(noteDuration);
        Serial.println(noteFrequency);

        tone(speakerPin, noteFrequency, noteDuration);

        int pauseBetweenNotes = noteDuration * 1.30;
        delay(pauseBetweenNotes);

        noTone(speakerPin);
    }
}

And I call it in my .ino file like this:
MelodyPlayer player = MelodyPlayer(SPEAKER);
player.playMelody(SHAVE_AND_A_HAIR_CUT);

The problem
I'll upload the sketch and everything fires. The problem I'm running into is that when I get to the private _playMelody() method the values I get for activeDuration, noteDuration and noteFrequency are all ultra wrong:

I imagine I'm doing something wrong with the setting and getting of the values via the pointer variable I set in the switch statement, but I'm not sure where I'm going wrong.
You can see/pull down the actual code from the abstracting-to-class branch of my repo if you want to dig in.
I've done a similar dynamic-selection-via-pointer in a proof of concept before, but it was procedurally written, not classed. I can't seem to figure out where the difference is :|
Any ideas?

Your melody and duration arrays that contain the actual data are local to the constructor. Further to that, they aren't used, so the compiler will optimize them away.

As Majenko mentioned in the comment, you created new local arrays in the constructor, but never put anything in the member arrays of the classes. They have the same name, but are not the same variable. Responsible for creating the new variable is the keyword int. However, you cannot simply assign array values by just omitting the int. Therer are multiple possibilities:

You can fill the array for each index: durations_shaveAndAHairCut[0] = 1;
You can copy your local array to the member variable with memcpy: memcpy((void*)this->durations_shaveAndAHairCut, (void*)durations_shaveAndAHairCut, 9*sizeof(int));
You can declare the arrays static in the class declaration and initialize it outside of the constructor in MelodyPlayer.cpp:
int MelodyPlayer::durations_shaveAndAHairCut[] = {
    4, 8, 8, 4, 4, 4, 4, 4, 4};

I prefer the last option.

Awesome! Thanks for the help! I went with the last option. It definitely feels like the most simple and straight forward solution.


text:
platformio native unit test Arduino.h not found
I'm writing code for a microcontroller project using PlatformIO.
I have a couple of classes that I want to write unit tests for. I've not unit tested with pio before so I'm starting with one of the easier classes. I wrote out the start of my test:
#include "PixelRange.h"
#include <unity.h>

void test_forward_incrementation(void)
{
  PixelRange range = PixelRange(1, 5, 10);
  uint8_t currentIndex = range.getCurrentIndex();

  TEST_ASSERT_EQUAL(5, currentIndex);
}

int main(int argc, char **argv)
{
  UNITY_BEGIN();
  RUN_TEST(test_forward_incrementation);
  UNITY_END();
  return 0;
}

For my class:
#pragma once
#include <Arduino.h>

class PixelRange
{
public:
  PixelRange() {}
  PixelRange(int rows, int startingIndex, int endingIndex);

  void setReverseIteration(bool reverse);
  uint8_t getNextIndex();
  uint8_t getCurrentIndex();

  int getRowCount();
  int getStart();
  int getEnd();

private:
  bool _iterateInReverse = false;
  uint8_t _iteratorIndex = 0;
  int _rowCount;
  int _start;
  int _end;

  uint8_t forwardIteration();
  uint8_t reverseIteration();
};

And my platform.ini looks like this:
[env:adafruit_trinket_m0]
platform = atmelsam
board = adafruit_trinket_m0
framework = arduino
lib_deps = fastled/FastLED@^3.4.0

[env:native]
platform = native
test_ignore = test_embedded

I wanted to start by running the test in the native environment, but when I run it I get errors saying that I'm missing the Arduino.h file. Even odder, one of the errors is coming from a file that's not even under test.

I'm referring to the calculator example as far as setup and I don't see anywhere in the desktop test where Arduino.h is mocked.
Anyone have an idea of why this would be failing? Here's the full project in case that helps.

I suppose native means on the computer, not on the arduino, and the computer doesn't have a Arduino.h header. Why do you even need it? The uintX_t are defined in  header so if it's the only dependency, it should be all to just include it..


text:
Unable to find headers from installed platformio library
I wrote a library that I intend to use in several project and I published it via platform.io's library management system.
https://platformio.org/lib/show/12820/FastLED-SectionManager
This is the first time I've published via platform.io (first time I've published any c++ library). I read over platform.io's docs on creating a library and structured my library accordingly with my headers in the include directory and the implementation files in the src directory:

And created the following library.json file:
{
  "name": "FastLED-SectionManager",
  "version": "1.0.2",
  "description": "A led strip index manager that allows for logical groupings of strip sections.",
  "repository": {
    "type": "git",
    "url": "git@github.com:chris-schmitz/FastLED-Section-Manager.git"
  },
  "authors": [
    {
      "name": "Christopher Schmitz",
      "email": "schmitz.chris@gmail.com",
      "url": "https://light-inspiration.com/"
    }
  ],
  "homepage": "https://github.com/chris-schmitz/FastLED-Section-Manager",
  "license": "MIT",
  "dependencies": {
    "fastled/FastLED": "^3.4.0"
  },
  "frameworks": "*",
  "platforms": "*"
}

The problem that I'm running into is that when I install the library in a different project via platform.io and try to include a header, the header can't be found:

I double checked in the pio directory for the project and I can definitely see the header and implementation files:

So I'm not sure why platform.io can't find the headers.
I can't quite tell what I'm doing wrong. any ideas?

your library has a typo in main.cpp ... want to flip the direction on every other row with the third boolean argument ....
sectionManager.addRangeToSection(0, 0, 3, true); .... the boolean is 4th argument

I woke up this morning and looked back at the documentation.
A part I mis-read was this:

We recommend to use src folder for your C/C++ source files and include folder for your headers. You can also have nested sub-folders in src or include.

I had my headers stored in the lib folder :facepalm:
I tried to search around in the platformio docs for the explanation of the lib vs include vs src folders (I knew I saw it at one point) but couldn't find it.
I then remembered that I read the purpose of each directory in the Readme files in the project structure itself generated when you create a new platformio project:

The gist being:

src: your compiled files, i.e. your cpp files

It's worth noting that you could just shove all of the files in here and it would work

lib: libraries private to your project/library itself
include: declaration and macro definition files, i.e. your header files

This explains how the header files in the lib directory worked in the SectionManager project itself but didn't work when using the SectionManager as an installed library; the lib directory is only "visible" local to a project, so when I tried to include the header files from another project they couldn't be found.
So in my SectionManager project I moved the headers to the include directory, bumped the version number, and published:

Then I switched to my main project that I'm pulling the SectionManager library into, adjusted the dependency version to include the minor bump, updated, and now it works!

Makes sense, I'm just still getting used to c++ and platform.io.


text:
esp32 crashes when trying to dereference a pointer value
I have a websocket listener that is giving me a std::string of my message payload (I want the bytes) and I wrote a function that pulls each of the bytes out and puts them into 32 bit integer variables, adds that integer to an array of 32 bit integers, and passes back the pointer address:
uint32_t *get32BitInt(WebsocketsMessage message)
{
  std::string raw = message.rawData();
  uint32_t chunks[message.length() / 4];
  int chunkIndex = 0;
  for (int i = 0; i < message.length(); i += 4)
  {
    uint32_t chunk = 0;
    for (int j = 0; j < 4; j++)
    {
      chunk <<= 8;
      chunk |= raw.at(i + j);
    }
    chunks[chunkIndex] = chunk;
    chunkIndex++;
  }
  return chunks;
}

And I know that parsing and array building works because if I add a loop before I exit the overall function call it prints them out just fine.

And in the function that calls the parser I can print out the address of the pointer that was passed back.
But, as soon as I try to dereference anything my microcontroller crashes:

I know that I'm pretty green to pointers and I'm probably misunderstanding something, but I keep looking at docs and examples of passing arrays as pointers and it seems right.
Also, something worth noting is that it doesn't seem to be an issue with the actual number printing, because if I store the first number of the array into a variable and then try to print a line after the assignment the controller crashes after the assignment but before the next serial print:

uint32_t chunks[message.length() / 4]; - I don't think, that you can do that. Array sizes have to be compile time constants. Or you need to use dynamic memory allocation. which can be bad (though on an ESP32 not as bad as on boards like the Uno).

@chrisl, gcc allows that

Just a guess: But don't you use a local array? Which ich created on the Stack (Frame) of the function? And then you use the pointer to that array, when the function has completed und the stack is reduced i.e. its stack has been free'd?

Ah sorry, I first wrote the comment and then saw the answer. ;-). Party fail!

@PeterPaulKiefer no worries, I appreciate the extra eye and comment :)

Ah, one of my friends pointed out the issue. It's a scope snag:

chunks is allocated on the stack in get32BitInt By returning a pointer to chunks, you are pointing to memory that is deallocated. Think of it as pointing to a member variable of a class that has already been destroyed
when you try to dereference deallocated memory, bad things can happen. usually in debug the compiler makes sure you fail hard
the easiest way to test this is to allocate chunks outside of that function and pass it in as a reference

So yeah, I was allocating memory within the scope of a function and then blowing that memory contents away when that functions scope ended.
I refactored my code to move the array outside of the scope of the parsing function and passed the pointer in to the parsing function to get populated:
void get32BitInt(WebsocketsMessage message, uint32_t *chunks)
{
  Serial.println("--------------------------------");
  Serial.println("raw parse:");

  std::string raw = message.rawData();

  // uint32_t chunks[message.length() / 4];
  int chunkIndex = 0;

  for (int i = 0; i < message.length(); i += 4)
  {
    uint32_t chunk = 0;
    for (int j = 0; j < 4; j++)
    {
      chunk <<= 8;
      chunk |= raw.at(i + j);
    }
    chunks[chunkIndex] = chunk;
    chunkIndex++;
  }

  Serial.println("parsed chunks:");
  for (int i = 0; i < 11; i++)
  {
    Serial.print(chunks[i], HEX);
    Serial.print(" == ");
    Serial.println(chunks[i], BIN);
  }

  Serial.println("--------------------------------");
}

void addWebsocketListener()
{

  client.onMessage([&](WebsocketsMessage message) {

    uint32_t gameFrame[message.length() / 4]; // *try moving gameFrame out of scope
    get32BitInt(message, gameFrame);

    Serial.print("game frame address: ");
    Serial.println((int)&gameFrame);

    Serial.println("storing first 32 bit integer in a variable");
    uint32_t firstNumber = *gameFrame;

    Serial.print("game frame first value: ");
    Serial.println(firstNumber, HEX);

    Serial.println("printing frame:");
    for (int i = 0; i < 11; i++)
    {
      Serial.println(gameFrame[i], HEX);
    }
  });
}

And now my controller isn't crashing :D

And now I understand scope when dealing with pointers a bit better :)

you could also just make it static or global to avoid having to pass it around.

definitely. I'm kind of feeling my way around procedurally at the moment because I don't know 100% what the final shape of everything is going to be, but my plan is to refactor this into a class once I do and when I do my plan is to make this a private property. But yeah for now I'll def move this out to a global to simplify the code, that's a good idea. Thanks for the suggestion :)


text:
Running a HC-SR501 PIR Sensor constantly using battery
I am not sure if this is the correct forum since I tend to use the ESP8266 standalone and not together with the arduino nano.
However, here is what I am planning.
I have a HC-SR501 PIR sensor, which I want to use to constantly track movements of animals outdoor. I dont want to go into further details, but 10 impulses per minute are expected (max. is 30/min) except for the night maybe.
I am planning to count the impulses for one hour, than send the sum to a webserver using wifi and reset the counter.
For powering I want a battery/akku solution (non-negotiable). Since the input of the PIR sensor is 4.8-20V I will directly connect it to the battery (provided the Voltage is high enough like with a 9V battery) and the ESP8266, which is used as WIFI station will be connected via an AMS1117 generating 3.3V.
WIFI Router which is connected to the internet is available and several sensor systems will be used to check several areas. Basic knowledge of using AT cmds or programming with Arduino IDE is given.
Questions:

Can the ESP8266 module count impulses during one of the sleep modes?
Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)
What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

Optimum lifetime for the beginning would be 1 month for the first prototype. Afterwards a SolarModule + Akku solution will be implemented, but the first prototype has to be finished simple and fast yet satisfying :)
kind regards

This are multiple questions in one. But I will do my best to tackle them one by one.

Can the ESP8266 module count impulses during one of the sleep modes?

The ESP8266 has different power modes. Short answer: As long as the CPU is running, yes.
Long answer: The ESP8266 has quite a few power modes. They are easily put:

No-sleep (as high as 170 mA while communicating)
Modem-sleep (15 mA Wifi is off, everything else is running)
Light-sleep (0.9 mA CPU is put to sleep and system clock stopped, can be waken up by a external interrupted)
Deep-sleep (20 uA Everything is off, basically it's powered down, but can wake itself on set intervals or reset it to wake it. everything in RAM is lost, except RTC RAM)

So if your sensor gives a pulse, you can use that as a interrupt and go to light-sleep. If you need to pull it, all you can do is modem-sleep.
ESP8266 power modes

Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)

Modem-sleep is your friend. Only connect to the router if there is data to send.
You can set up an AVR and use it in ultra low power mode and only turn on the esp if there is data to send. But explaining how to set that up goes way too far out of this scope.

What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

I can't choose a battery for you, there are just too many of them. But what I can do is tell you about how batteries work.
Take for example a 9 volt battery (not my first choice, you will see in a bit).
We take an energizer 522. It's a Alkaline battery and has 600 mAh. That means it can deliver 600 mA in one hour. But there is a catch. the more you draw from a Alkaline battery, the less capacity it will have.
It is 9 volts right? yes and no. you see. the voltage potential will drop (quite dramatically) over its lifetime.
A liniar voltage regulator (AMS1117) will take the needed mA of the output on the input and drop off the extra power as heat. So the battery will always have the same load (Yes, the esp8266 is a dynamic load, but lets keep it simple)
so lets say it's in modem-sleep (15mA). Lets divide 600 by 15, that is 40 hours of runtime. For simplicity I don't count the sensor itself.
9 volt block datasheet
The AMS1117 needs 1.5 volts more then its output voltage for ensuring a stable output. So that is 4.8 volts or higher. But no higher than 12 volts.
AMS1117 datasheet
Choose a battery that has enough mAh and isn't more then 12 volts and not lower than 5 when depleted. If using outside, check if its operating temp range is wide enough.
So basically try to lower your energy footprint as far as it can possibly go and then based on the new average power usage, find a battery that is big enough for the task.
Better yet, get a solar cell and a rechargeable battery. It has a full list of other problems, but this answer is a bit too long already and that topic is out of the current scope.

Thank you for this elaborate answer. I was diving deep into the battery topic and I agree with your last statement using solar power. This is a good tutorial [link]https://www.youtube.com/watch?v=SPpgMl_TeIc. The only thing I will add is the AMS1117 to get back to 3.3V after boosting to 5V (not nice but 4.8V is min for AMS). Regarding the sleep mode, what about sending the ESP to soft-sleep letting it being waken up every time I receive an impuls, incrementing that to the counter and saving the new value by overwriting the old one in a non-volatile memory space and going back to sleep?

@Slev1n Yes, you could go into deep sleep and store it in RTC ram (NV-RAM). That will conserve it. But you will reset the chip, when you wake it. so you need a system that keeps track of what it is suppose to do. Or it will always do the same. It will better work to make a program that will send a package to the router then go back into deep sleep. The downside is that the ESP takes time to wake from deep-sleep. Light-sleep is much better for this workload. Again, this comment is getting too long, here is some info on how to implement it (https://www.youtube.com/watch?v=6SdyImetbp8)

Thank you for the link. For now I will try the solar panel approach as a prototyp but I learned a lot. Later I will switch to a complete low power Module from TI http://www.ti.com/tool/TIDA-00489 i just found.


text:
Arduino + Solenoid Lock
I was trying to use a solenoid lock alongside the arduino, using a 12V 2A DC adapter, TIP120, and a diode.
The circuit looks something like this. However, the lock isn't going in automatically (it requires a push).
I've tested the circuit using a multimeter, and the output given by the transistor, is indeed 12V, however, when connected to the lock, the potential difference is around 8V. I don't know if that's normal, but the lock isn't going in on it's own.
Can anyone help me with this issue?

Welcome to Arduino:SE. You might find this helpful: How to ask a good question for Arduino Stack Exchange

lock isn't going in ... what does this mean? .... lock or unlock?

@jsotola by this I mean that it is not unlocking. When I provide it direct 12V dc, it is going unlocking perfectly.

It sounds like your 12 volt adaptor is not powerful enough to operate the lock solenoid. If you power up the solenoid only and directly using the adaptor it should work. If it doesn't, you'll need a more powerful adaptor. If it does work, then the problem is somewhere in your driver circuit or Arduino sketch.

Well, the lock works (goes in) when I power it directly. I don't know what am I doing wrong. :/

The next step is to connect the lock to the TIP120 driver circuit. Apply 12V to the base of the transistor through a 1k ohm resistor. The solenoid should work.

Well...I still have to push the lock in that configuration.. :/ Don't tell me the lock is faulty...

I think the power adaptor and lock are OK. The TIP120 driver circuit is not allowing enough current to flow through the solenoid. The next step would be to verify the driver circuit has been built correctly. Are any of the components getting hot? With everything connected, try using a jumper wire between the TIP120 emitter and collector. The solenoid should activate.

Well, no part was getting heated, however, a jumper wire between the collector and the emitter worked. Any leads?

For some reason, the TIP120 circuit is not able to operate the lock solenoid, so your question is more of a "general electronics" question, not an Arduino question. For the price of $1 CDN, you can get a relay that will definitely do the job: https://www.aliexpress.com/item/One-1-Channel-Isolated-5V-Relay-Module-Coupling-For-Arduino-PIC-AVR-DSP-ARM/32669140447.html. There is a chance that your power adaptor is "just powerful enough" to engage the relay, yet when combined with the transistor's voltage drop it is not. You could check this with a power adaptor that can deliver more current.

Yes use a well protected relay, check the voltage ratings so you don't fry your Arduino.

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


text:
Dim a led using a NPN transistor
I know there are a lot of questions about this topic, but I've tried everything and any possible guide online without success.
I want dim (increase and decrease the brightness) some leds (3.5 Watt each). To do that I'm using an Arduino Nano, a 10k potentiometer and an NPN transistor (TIP41).
I was able to drive the potentiometer as a switch: on/off. Now I want to control its brightness using the potentiometer. I don't get what I'm expecting because the led is always on except when the potentiometer is turned all the way on the right (where is connected Vcc).
This is the schematic:

This is my Arduino code:
int pinPotentiometer = 0;
int pinTransistor = 3;

void setup() {
  Serial.begin(9600);
  pinMode(pinTransistor, OUTPUT);
  pinMode(pinPotentiometer, INPUT);
}

void loop() {
  int potValue = analogRead(pinPotentiometer);
  int outValue = map(potValue, 0, 1023, 0 ,255);
  Serial.println(outValue);
  digitalWrite(pinTransistor, outValue);
  delay(100);
}

The potentiometer is working fine because I read from the serial values between 0 and 255.
Am I using the wrong transistor? Or maybe I'm using it in the wrong way?
NOTE: to test my circuit I'm using a small 5mm led and not the 3.5 Watt one so I don't have any external power source.
Many thanks!

Use analogWrite() instead of digitalWrite(). And make sure you're using a PWM-capable pin.

Try using analogWrite().
Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite(), the pin will generate a steady square wave of the specified duty cycle until the next call to analogWrite() (or a call to digitalRead() or digitalWrite()) on the same pin. The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz.
Source: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/

Considering using a protected MOSFET, it will run much cooler then the transistor.  Reason the transistor has a 0.7V collector emitter voltage drop, the MOFET will be less then 0.01 depending on choice. You are missing a resistor from the base to the Nano.  Use something in the 50 to 120 Ohm for the MOSFET to keep it ultra stable. Be sure to use a seperate power supply with the high wattage LEDs. Also connect the power supply grounds.

@Gil - The OP stated they were using a TIP41 transistor. Perhaps your comment would be useful if you added it to the question.

your transistor base should be connected to the PWM side of the Arduino and not the collector. put a 1kOhm resistor between that base and arduino too. collector to load, load to positive of battery or power source. emitter to ground.

You also need a resistor on the collector side, if the load is a LED. For 3W Led you need a fat resistor (some Watts)

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


text:
How would you add Arduino WiFi Module using I2C or serial interface?
I am new to Arduino prototyping. I bought an Arduino Automatic Smart Plant Watering Kit 2.0 thinking it was a shield to use with my Arduino Uno WIFI Rev 2.  However, it turns out to be a specially designed Arduino board with all of the components integrated together.
While the system works as designed, my goal is to stream the data to IBM Watson Studio, or some other third-party SaaS.
I welcome feedback to understand how it might be possible to integrate the ESP8266 WIFI module using either the I2C or Serial interface. Here is the sample code: https://www.elecrow.com/download/watering_kit.zip I used a Raspberry Pi to get access to the data and use it in a web/mobile application but I'd like to eliminate this element, if possible.

esp8266 arduino core doesn't have a working I2C slave library. and 32u4 has Serial1

I appreciate the prompt feedback. so, maybe the better solution than connecting to a Raspberry Pi is to set up this Arduino board to communicate with another Arduino like the Wifi Rev2 or Arduino YÚN Rev 2?
https://www.arduino.cc/en/Tutorial/MasterWriter

why? you can attach esp8266 to Serial1 of this board (the "Serial interface" connector). (How did get the idea about Yun? Forget Yun.)

okay, it's forgotten! I am grateful for the feedback.

You would connect the ESP8266 to the serial port.  The normal way of working with an ESP98266 is to issue AT command (like an old Hayes modem) through a serial connection. Since you have one of those available on your board it is a simple matter to just wire it directly to it.
Just follow any of the myriad of ESP8266 + Arduino tutorials, substituting the pins in the examples for your serial pins, and use the Serial1 object instead of the SoftwareSerial class that you have to use on an Uno that lacks extra serial ports.


text:
Basic communication with nrf24l01 between nodemcu and arduino nano
I spent the last two days to find a way to set up a basic communication between a nodemcu amica and an arduino nano with a nrf24l01 module; all of this without success..
Here the code uploaded on my nodemcu:
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(D4, D8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

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

  radio.begin();

  //set the address
  radio.openWritingPipe(address);

  //Set module as transmitter
  radio.stopListening();

  Serial.println("inizio ad trasmettere");
  Serial.println(radio.isChipConnected());
}
void loop()
{
  Serial.println("qui");
  const char text[] = "Hello World";
  bool ret = radio.write(&text, sizeof(text));
  Serial.print("Write ret: ");
  Serial.println(ret);
  delay(1000);
}

and here the code on the arduino side
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(5, 6);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

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

  radio.begin();

  //set the address
  radio.openReadingPipe(0, address);

  //Set module as receiver
  radio.startListening();

  Serial.println("inizio ad ascoltare");
  Serial.println(radio.isChipConnected());
}

void loop()
{
  //Read the data if available in buffer
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }
}

Following my wiring config of
nodemcu
and
arduino nano
Can anyone see something that I don't see?
I'm really frustrated
My nrf24l01 module is this https://www.amazon.it/gp/product/B06WD17WLS, not the module in the fritzing scheme.

how does it fail? does the esp8266 boot? the D8 wiring can make problems

Simply I don't see a successful communication, both Nano and nodemcu appear to transmit and receive normally, but no frame arrive at the receiver


text:
Send data from arduino to server using GSM, TCP
My actual connection is like:
Arduino -> GPRS(http)-> my server(php script)-> firebase <-android plotting app
But it only allows to send some data once every 2 - 3 seconds (depending of ping to my server).
I need to send some data (18 bytes) but every 0.5 - 1 seconds
It is possible to send directly over tcp to firebase?
And also i thinked about this schema:
Arduino(client) -> GPRS(tcp) -> my server(tcp socket) -> my database <- android plotter
but I don't know how to go about it, what server software i need to redirect recieved tcp packages to mysql.

you use AT commands on the unknown GSM module?

allows to send some data once every 2 - 3 seconds .... this indicates that there may be a bug in the PHP script

https://en.wikipedia.org/wiki/HTTP_persistent_connection

@jsotola Or it takes a couple of seconds to establish a new connection.

this is m590e module, and i use simple AT commands. It uses http GET connection and script read data from url parameters. I close connection every GET request. 'void loop() {
value++;
String dpa  = "/test.php?arduino_data="+(String)value;
strncpy(resource, dpa.c_str(), sizeof(resource)); //string to char
http.get(resource); //starting get request
Serial.println(err);
http.stop();} //closing connection' using tinyGSM library, how to make from it persistent connection, removing "http.stop()" not working :C


text:
Arduino MKR Zero problem with new UART comunication
I'm currently using an Arduino MKR Zero board and I need to add a new communication because the Serial1 on pins 13 and 14 is already used by another device.
I've followed this tutorial from Arduino official website to create a new serial communication, but using the given code I have no communication on pins 0 and 1.
The code compiles, but it doesn't work when uploaded to the MKR Zero board.
I've noted that IrqHandler() is not highlighted in my Arduino IDE (it remains black).
So, should I install some library?
Thank you.

Did you manage to resolve the issue? I also struggle to get an additional serial interface to work.

When a library does not highlight, it might be that the library is not coded to be highlighted (see here).
If you installed the library yourself, you may have put it in the wrong path.


text:
Arduino weather station BMP280 and BM1750
im experiencing troubles with combining a arduino sketch with BMP280 and BM1750. At this moment i have 2 sketches which need to be combined.

#include Wire.h>
#include BH1750.h>

// ADDR line LOW/open:  I2C address 0x23 (0x46 including R/W bit) [default]
// ADDR line HIGH:      I2C address 0x5C (0xB8 including R/W bit)
BH1750 sensor(LOW);

void setup()
{
  Serial.begin(115200);
  Serial.println(F("BH1750 continues measurement basic example"));

  // Initialize I2C bus
  Wire.begin();

  // Initialize sensor in continues mode, medium 1 lx resolution
  sensor.begin(ModeContinuous, ResolutionMid);

  // Start conversion
  sensor.startConversion();
}

void loop()
{
  uint16_t lux;

  // Wait for completion (blocking busy-wait delay)
  if (sensor.isConversionCompleted()) {
    // Read light
    lux = sensor.read();

    // Print light
    Serial.print(F("Light: "));
    Serial.print(lux);
    Serial.println(F(" LUX"));
  }
}

and the BMP280

#include  Wire.h>
#include SPI.h>
#include Adafruit_Sensor.h>
#include Adafruit_BMP280.h>
#include ESP8266WiFi.h>
#include BH1750.h>

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

Adafruit_BMP280 bme; // I2C
BH1750 lightMeter;

/**************************
 *   S E T U P
 **************************/
void setup() {
  Serial.begin(9600);
  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  Wire.begin(D2,D1);
  // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);

  lightMeter.begin();
  Serial.println(F("BMP280 test"));
  if (!bme.begin()) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  }

}

  /**************************
 *  L O O P
 **************************/
void loop() {

  uint16_t lux;

  // Wait for completion (blocking busy-wait delay)
  if (sensor.isConversionCompleted()) {
    // Read light
    lux = sensor.read();

    // Print light
    Serial.print(F("Light: "));
    Serial.print(lux);
    Serial.println(F(" LUX"));
  }
    Serial.print("T=");
    Serial.print(bme.readTemperature());
    Serial.print(" *C");

    Serial.print(" P=");
    Serial.print(bme.readPressure()/100);
    Serial.print(" hPa");

    Serial.print(" A= ");
    Serial.print(bme.readAltitude(1013.25)); // this should be adjusted to your local forcase
    Serial.println(" m");
    //every 20 sec
    delay(2000);
}

The BMP part is working fine.

i do have a combined script now, but it seems only the lux part is giving results. the BMP values are 0

Then you'd need to edit the question to show us your current program.


text:
nodemcu pins + sensors reading values
what are the SDA & SCL pins in NodeMCU? (Pins 20 & 21 in Arduino MEGA2560) I already implemented a simple project to read 2 accelerometers values from Arduino and send them through wifi to firebase database. I used Arduino Mega before for the same project and the sensors gave me readings between approximately -300 to 300. Now when I moved to NodeMCU the sensors became very sensitive and are getting values up to 65500+. And with a very small angle change the axis reading drop down to 20 or less.
I used pins D1 and D2 for SCL and SDA. Are the pins correct? And What about the reading values how to fix that?

The ESP8266 doesn't have a hardware Two Wire Interface. I²C is done in software, so you can use any 2 pins, as long as you specify them in your code using Wire.begin(SDA, SCL).
My guess would be that there's another problem. 65500+ sounds like an integer overflow, for example. ((uint16_t) -1 == 65535)


text:
cannot open source file "WProgram.h" in VSCode
So I started typing out this question, but in the process of taking screenshots and looking up sources for the question I figured out the answer :P
That said, this problem has been a snag for me for a while and I've asked multiple people about it with no solution. Because it seemed kind of daunting for me and I haven't seen many well explained reasons I figured I'd finish out the post here to help anyone that is running into this or will run into it in the future.

The snag
I'm using vscode for my editor and I've had this snag for a while but it's finally driving me nuts enough to ask for help.
When in include certain libraries I get error squiggles under the include.

In this case the squiggle is popping up because of the error:

cannot open source file "WProgram.h" (dependency of "Adafruit_MPR121.h")C/C++(1696)

At first I though the snag was because my include path needed my arduino libraries directory so I added that for the project, but I still get the snag.

I did a computer wide search for the WProgram.h file but was not able to find it.

The thing is, all of my sketches still compile and upload fine so for the most part I'm just able to ignore it ... but the squiggle!!!!!!.
Any ideas of how I can resolve this?

I landed here in the same position as you, and after researching the comments mentioning -DARDUINO=10813 and some more googling I found: https://github.com/microsoft/vscode-arduino/issues/1148
This led me to adding one more line to defines in my c_cpp_properties.json
and this also removed the squiggly!
{
    "configurations": [
        {

            ...

            "defines": [
                "USBCON",
                "ARDUINO=10813"
            ],

            ...

        }
    ],

}```

Just because this doesn't answer why this works: Arduino versions <1.0 used WProgram.h, but Arduino >=1.0 use Arduino.h. As @Chris Schmitz explained, many libs use a check to determine which to load for backwards compatibility. Because the VSCode extension should be up to date, we can use the (current) latest version of 1.8.13, or 10813 as it's defined in the code. Adding this to VSCode lets packages checking versions see we're running modern versions.

The answer
Like I said in the question, I found the answer after doing some searching while typing up the question itself and I want to explain it for future squiggle-haters :)
WProgram.h vs Arduino.h
I did a bunch of searching to try to track down what's going on and I eventually found this helpful (and depending on the veracity of the source, kind of sad) bit of history:

There is history of the arduino project not everyone was aware of or supposed to know. I only this much: this all started with some graduate student(s) that created the wiring platform and IDE, called wiring board and wiring "programming language". This project is still active with active users like the arduino project. Then the arduino folks decide to create the arduino project based on wiring project so they took the wiring IDE (which took from the original Processing IDE), including all the libraries etc. and created the first Arduino board (slightly different than wiring board, cheaper!) called it arduino. Arduino project has not very positively acknowledged the wiring project as the source of their project and wiring folks didn't take it very well.
Now, that WProgram.h, is a definition file created by and for the wiring project and board. That's why it has a W on it. It has been in Arduino IDE since its beginning and was replaced by Arduino.h only recently when Arduino 1.0 was released. Now all Arduino 1.0+ IDE will use Arduino.h and not WProgram.h so if you have that plus some other old stuff, you will have to make changes to work with Arduino 1.0+ IDE.

The temp fix
With that in mind I dove into the source file for the Adafruit_MPR121.h library and found where it includes the WProgram.h header file and commented it out.

It's also worth pointing out that the pre-compiler conditional here supports the renaming of the file in newer versions of Arduino.

I labeled this section of the answer as "The temp fix" because it involves modifying a 3rd party dependency which is normally not a great idea. Yeah it fixes it now, but as soon as I need to update this library that edit is going to get blown away and I'd need to manually do it again. In this case the update is pretty minimal so maybe that's no big deal, but if the fix was more involved, like a heavy edit, that would be a real big pain in the butt and could cause other unforeseen consequences (and I played half-life as a kid so I know that's not good).
The better fix
Normally I would say the better fix for this would be to clone the source repository, make the fix there, and do a pull request so the dependency itself gets updated at the source (if someone approves and merges the PR).
But this is a bit different, the conditional in there is actually fine as it adds backwards compatibility. It's there so that the library can support both pre-1.0 and post-1.0 arduino IDE versions. If we did a PR to cut out the WProgram.h reference we'd add in breaking code for anyone on the older versions.
So, the better solution is to appease my local compiler.
We know that the Arduino.h header for all intents and purposes is the same as the WProgram.h, so a almost-full-proof solution would be to fake out the WProgram.h file on my computer to appease the compiler.

An important part to note here is that to make sure I faked it out correctly I went to the arduino repository, scrolled back through the tags, found the last tag before they switched to 1.0+, and found the WProgram.h file. Once there I grabbed the same pre-compiler check and definition for the WProgram header so I could be sure I did the correct define for the WProgram name.

This feels like a bit of overkill because it protects me from other headers being included with the same string defined, but if that happened it would be because I have the WProgram file anyway, but I figured if I was going to fake it out I'd do it right.
This could backfire if I include a library that only includes WProgram.h and not the Arduino.h in that arduino version check conditional, but this would 100% be the case for a correction and pull request for that library.
Summary
So now I know that the Arduino.h file is the reason I'm able to compile everything correctly even with the red squiggle, I have a faked out WProgram.h so that my compiler can find something when looking for the file and, most importantly, I no longer need to look at those red squiggles under the includes :)

Next step, figure out the same thing for Sam.h :P

The simplest fix: create WProgram.h and place in it #include <Arduino.h>.

Ah, that's a good point, though I feel like I'd run into the same modifying-code-that-could-be-overwritten issue if I put it in Arduino.h and then an update to the arduino IDE modifies that file.

platformio doesn't define Arduino version? you can add -DARDUINO=150 somewhere in projects properties?

If you want to be compatible with the Arduino ecosystem, the proper fix would be to use the same preprocessor macros as the Arduino IDE itself. For instance, Arduino 1.8.13 compiles every file with the command-line option -DARDUINO=10813.

Oh interesting, I didn't know about preprocessor macros! I did some searches through the arduino docs just now but can't find where it's talked about. Could someone point me to the right spot in the docs? If I figure out how to add that in on the vscode side I'll update my answer.

https://arduino.github.io/arduino-cli/platform-specification/#global-predefined-properties

Ah awesome, thanks for the point :clap:

If you used the free version of IntelliJ Idea you could have just right-clicked on the warning (red squiggle) and told the IDE that it's ok. IntelliJ would remember that and not bother you about it again. (IntelliJ supports most common programming languages, including C and C++, python, and javascript, as well as Java).

I recently figured out, it's way too simple.
Just tap F1 and look for this then select the configuration for "Arduino".

(Pardon my Grammer)

Simple and effective!

My VS code has no configuration for Arduino. It only has win32. How do I get the configuration for Arduino?


text:
Voltage issue on an esp32 wvroom 32D development board
I have an esp32 wroom 32 dev board. I'm running into power issues and I'm not sure what's going on.
When I try to upload sketches the uploads fail if I have any jumpers running to the 5v or 3.3v pins which is weird.
Also, when I have nothing plugged into the board other than the usb cable and try to measure voltage across the ground and power pins I get 1.5v from the 5v pin and 0 from the 3.3 pin

This is a brand new out-of-the-static-bag board and I'm having the same issue with another board of the same type.
I feel like there's something I'm missing. Any ideas?

Please verify your black wire is connected to GND and not to D3.

@VE7JRO yeah, the angle is odd in the picture, but the ground is definitely connected to the ground pin and not d3. I hooked it all back up just now to double check, still the same readings.

Is it possible to measure the voltage with the ESP32 un-plugged from the prototyping breadboard? One last suggestion, try a different volt meter if you have access to one.

Try measuring the voltage against a different ground pin? I had a similar problem and discovered the pin next to the 5v input pin wasn't actually ground. Not sure why this would affect sketch uploading though..


text:
Does LabVIEW Linx affect the communication speed with Arduino?
I am using LabVIEW to connect to Arduino Mega. I control a logic gate to switch the current On/Off and at the same time there is an I2C connection with a sensor. It came to my attention that the sensor time resolution is very low and I cannot get enough data points from the sensor (I know that the sensor is capable of much better resolutions). My question, is this a problem inherent to LabVIEW and Linx module or my program in LabVIEW? Should I turn to coding with Arduino programming language or C?
note! My reason for using LabVIEW is that I need to sync timing of data aqcuisition with another device which is connected through another VISA port.

As far as I know, VIs are kind of compiled into c/c++ under the hood. It might help us if we could see your LabVIEW program and know which sensor it is. How do you connect to the arduino? I2c as well?

For specific timing requirements, my recommendation is to write your own Arduino code.
The Linx module deploys its own ino program to the Arduino and uses serial IO to send it commands and receive data from it. Open NI I/O Trace to observe that traffic.

Thanks for the answer, I exactly did that.
Linx communicate every command to the arduino and wait for the answer, the loop frequency with linx drops as the linx blocks increases in the loop. it droped to 10Hz for me. I am now using the arduino code and send the data back to labview using serial communication. Its much faster (Up to 300Hz loop frequency).


text:
Problems when attaching a second ultrasound sensor (HC SR04)
I am working on an obstacle avoiding robot. It uses an ultrasound sensor to avoid obstacles, but currently has trouble avoiding objects that are diagonal to it. Thus, i want to add a second ultrasound sensor, and alternate their readings. I am testing the code, which should look right and then leftn and return the distances. The code worked for just one ultrasound.  and it is a follows:
#include <NewPing.h>
#include <Servo.h>

#define trig_pin1 A1 //analog input 1
#define echo_pin1 A2 //analog input 2
#define trig_pin2 A3 //analog input 1
#define echo_pin2 A4 //analog input 2
int distance1 = 100;
int distance2 = 100;

#define maximum_distance 200 //sensor function
Servo servo1; //our servo name
Servo servo2;
NewPing sonar1(trig_pin1, echo_pin1, maximum_distance);
NewPing sonar2(trig_pin2, echo_pin2, maximum_distance);
void setup() {
  // put your setup code here, to run once:
  servo1.attach(11); //our servo pin
  servo1.write(90);
  servo2.attach(6); //our servo pin
  servo2.write(90);

  distance1 = readPing1();
  distance2 = readPing2();
  delay(100);
  distance1 = readPing1();
  distance2 = readPing2();
  delay(100);
  distance1 = readPing1();
  distance2 = readPing2();
  delay(100);
  distance1 = readPing1();
  distance2 = readPing2();
  delay(100);
}

void loop() {
    int distanceRight = 0;
  int distanceLeft = 0;

        distanceRight = lookRight();
    delay(300);
    distanceLeft = lookLeft();
    delay(300);
  }
}

int readPing1(){
  delay(10);
  int cm = sonar1.ping_cm();
  if (cm==0){
    cm=250;
  }
  return cm;
}

int lookRight(){
  servo1.write(50);
  delay(500);
  int distance1 = readPing1();
  delay(100);
  servo1.write(115);
  return distance1;
}

int readPing2(){
  delay(10);
  int cm = sonar2.ping_cm();
  if (cm==0){
    cm=250;
  }
  return cm;
  }
int lookLeft(){
  servo2.write(170);
  delay(500);
  int distance2 = readPing2();
  delay(100);
  servo2.write(115);
  return distance2;
  delay(100);
}

I get the following error:
'readPing1' was not declared in this scope

and I get the same error for the readPing2 function. Why could this be?

tip: you can simplify your code by using if (cm==0) cm=250;

It turns out I had an extra "}" after the void loop function. The code worked as expected after removing it


text:
MD_Parola display issue when constructing test
I'm using ESP8266 and 4 dot Matrix Tiles, to display clock ( updates using NTP and WiFi ).
Everything is working well, but only when I'm constructing text using a const char* type.
But, since I wish to construct text as sprintf(temp, "12:00"); or char temp[20]="12:00\n; creates gibberish text.
MD_Parola dotMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void updateTime()
{
  char clk[10];
  char dat[10];
  char temp[10];
  sprintf(temp, "12:00"); // <---- this ways failes
  const char *t = "12:00"; // <---- this way succeeds
  dotMatrix.displayText(t, PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
}

link to library
Appreciate explanation how to construct text not as const char*

You haven't written, how you supply temp to the dotMatrix.displayText() function. Are you just writing temp where now t is written? Have you tried providing a pointer to temp? I'm not sure here about the implicit handling of arrays as pointers, but you might try something like &temp or &temp[0] to get the pointer as parameter of the display function. That's what I would try in this case

@chrisl - t replaces temp as you asked. &temp fails compilation and &temp[0] yields same result as temp

Mhh, the library documentation states, that the library doesn't use an internal buffer, but points to the buffer, that you provide a pointer to. I haven't looked into the library closer, but the problem might be, that the temp buffer goes out of scope after the function exits, which means, that the library uses then a pointer to an invalid location. Please try moving the declaration of the temp buffer to the global scope.

@chrisl - I've read also what you;ve stated but I didn't understand that it should be external. it is correct! please  post as an aunswer

The library documentation states:

The library does not allocate any memory for the text message

That suggests, that the buffer has to be valid beyond the execution of the displayText() function. But as you declare it inside of your updateTime() function, it the buffer gets out of scope, when exiting that function. The memory space can then be reused by the rest of the program. At that point the library will still have the pointer to the old location, though that pointer can now be considered invalid. Thus you are just reading, what the compiler decided to place in that memory location.
To solve that, you need to keep the buffer variable in scope. You can do this by moving the declaration to the global scope.