text:
Solar powered ESP8266. WiFi module usage optimizations
Above all, I am quite new to the ESP8266 and micro controllers development as a whole. I am now working on a project which is quite simple for now. It basically looks like this:

As you can see, I have an ESP8266 and some input peripheral. Everything works perfectly fine for the moment, I can read the inputs from the motion sensor and 4x3 keypad. And, respectively I can output on the relay and the 5mm LED. In order to make it a real IOT, I have connected it to the internet via Thinger.IO. So, I have my ESP8266 constantly connected to this platform and I can track it anytime, from anywhere.
This is great. But, my optimal goal is to power my configuration from a solar panel and make it independent of the electricity distribution network.
The average working current of the whole system is about 313mA (10000 mAh battery gets completely drained for 32 hours. Its output is 5V, 2.1A).
So, I am now in a search of the best solar panel to fit my needs. An ultimate one would have the following maximal dimensions: 30x35 cm. I am not sure there's a single panel that I can use but I am interested to hear your opinion in this.
Another aspect, that I'd like to optimize is the constant internet connectivity. Basically, I need to have my configuration connected to the internet only when keypad input was made or motion sensor detected something. During the rest of the time, I don't need to be connected to the internet and I assume WiFi module could be suspended somehow. Currently, my code uses SmartConfig and is looks like this:
#include <ESP8266WIFI.h>

void connectToWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.beginSmartConfig();

  while(!WiFi.smartConfigDone()){
    delay(500);
  }
}

void setup() {
  connectToWifi();

}

void loop() {

}

Everything works well. But, as I said, I'd like to be able to start/stop the WiFi module. I tried using the following API:
void toggleWifi(bool isWakeUpCall) {
  if(isWakeUpCall)
    WiFi.forceSleepWake();
  else
    WiFi.forceSleepBegin(30000000);

  delay(500);
}

but without much of a success. Once it gets into this portion of code, it gets completely disconnected and doesn't get connected anymore. I am now struggling with it.
I've read about the sleep modes offered by the ESP8266 but I don't think they are suitable for my case because I can not simulate external interrupt (or maybe I can?).
I am really curious to hear your opinion on this. :)

As a solar panel you can use a MEGSUN 10W 12V Mono Solar Panel or similar. They are smaller than what you specified and should be plenty for powering an ESP.

As described here the ESP8266 can be waken up using Timer Wake Up or external interrupt. The idea is simple: almost everything inside the ESP is powered down (including Wi-Fi and/or System clock or even the CPU) with only a timer running which was told when to activate before the ESP went to sleep. After the desired amount of time has passed the timer triggers GPIO 16 or D0 and if that is connected to the reset pin of the ESP is resets and starts executing code again until it goes to sleep again. For your case you can configure your motion sensor to output a LOW when motion is detected and connect is to a GPIO pin and the reset pin, so it will trigger a restart when motion is detected and in the startup sequence you look at the pin where the sensor is connected and do what you have to do. For the keyboard to work you can have the timer set to reset every 5 seconds, so you would have to hold a button for 5 seconds waiting for the ESP to wake up and accept your input or you could make a dedicated button for waking up the ESP if you want to enter the code. In that case the you don't need a timer, since as you described the ESP only has to do anything if the keyboard is activated or if the motion sensor is triggered and since they can be connected as external interrupts they will wake up the ESP if needed. I would recommend to check out this link for further details about the code and hardware.

I have already read a lot of articles regarding Deep Sleep but I am not sure I can achieve that with my current setup. The reason is simple - all of my GPIOs are currently occupied (It is not only what you can see on the diagram. I decided to leave the most important ones there). So, keypad input and motion detection are equal in my use-cases. You can either input on the keypad or you could receive a signal from the motion detection sensor. I don't think 5 seconds timer would be convenient for my case. Because I need to "teach to hold for 5 sec." my end-user which I don't think is a good idea.

@user60623 In that case you can use a regular Arduino to handle all the IO and use an ESP only when you needed to push the stuff to the cloud. Also, if you are expecting a proper answer provide everything you have not only the "important ones" since solutions are highly specific to the project schematics. And since on the diagram above I saw free pins I assumed you have headroom.

Connecting a motion sensor to the reset pin could be problematic. It would cause the ESP to reset every time the motion sensor detected motion, even if it wasn't finished restarting from the last reset. You'd really need some logic that would latch the motion sensing trigger for some time, or until the ESP released the latch. You could build a latching motion sensor trigger with a 555 timer and a few discrete components.


text:
ESP8266 WiFi doesn't reconnect
I've been reading this post while trying to optimize the usage of the WiFi module on my ESP8266.
My main goal was to be able to connect/disconnect (respectively turn on/off) the WiFi module so I can optimize electricity consumption of the chip (I am trying to solar power it).
So, the way I integrated the proposed solution is as follows as I am no where calling deepSleep:
#include <RelayModule.h>
#include <ESP8266WIFI.h>
#include <rdm6300.h>
#include <string.h>
#include <ctime>

extern "C" {
    #include "user_interface.h"  // Required for wifi_station_connect() to work
}
/*...*/
#define RFID_PIN 13
#define RELAY_PIN 10
#define FPM_SLEEP_MAX_TIME 0xFFFFFFF
#define RELAY_OPEN_DURATION 6

RelayModule relay(RELAY_PIN);
Rdm6300 rdm6300;

int relayTurnedOnAt = 0;

void WiFiOn();
void WiFiOff();

void connectToWifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
     delay(500);
  }
}

void setup() {
  connectToWifi();
  rdm6300.begin(RFID_PIN);
  /*...*/
}

void openFrontDoor() {
  WiFiOn();
  if(relay.isOff()){
    relay.on();
    relayTurnedOnAt = time(0);
  }

  /*Perform some business logic which makes a reference to Services hosted on the Internet*/
}

void lockFrontDoor() {
  relay.off();
  WiFiOff();
}

void loop() {
  // RFID TAG WAS SCANNED
  if (rdm6300.update()){
    openFrontDoor();
  }

  if (relay.isOn() && abs(time(0)-relayTurnedOnAt) > RELAY_OPEN_DURATION)
    lockFrontDoor();
}

void WiFiOn() {
    wifi_fpm_do_wakeup();
    wifi_fpm_close();

    //Serial.println("Reconnecting");
    wifi_set_opmode(STATION_MODE);
    wifi_station_connect();
}

void WiFiOff() {
    //Serial.println("diconnecting client and wifi");
    //client.disconnect();
    wifi_station_disconnect();
    wifi_set_opmode(NULL_MODE);
    wifi_set_sleep_type(MODEM_SLEEP_T);
    wifi_fpm_open();
    wifi_fpm_do_sleep(FPM_SLEEP_MAX_TIME);
}

The problem here is that once disconnected, I can not get the WiFi module connected back. I need to reset/restart the chip and then I get connected to the internet once again. I would like to be able to fully disable the module when not needed (and save power) and when I need it to submit some stuff to the internet - wake it up, do the job and then bring it back to suspended mode.

Perhaps the method wifi_station_disconnect(); drops you WIFI connection at all. Perhaps you have to perform connectToWifi(); again. But as I don't know the user_interface.h,  it is just a guess ;-)..

why do you use the SDK API. the Arduino WiFi API has all functions to turn off WiFi an turn it back https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-class.html#mode

source: Stack Exchange

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

sort: votes


text:
Variable sets to 32767 - MATLAB Arduino
I am running out of ideas of what may be causing this problem, and I would appreciate some help identifying anything I am overlooking.
Quick Problem Summary
A variable gets set to 32767 quite often and I am unsure why. I tried checking if it was a types problem, if there was somewhere in my code it could overflow, any division by 0, initialising all variables in all sections of the code, and have now tried to cast all relevant variables to int. What else could I try?
This is how this variable gets set in a C++ function:
readValue = readAverage(A0);
targetValue = 2000; // Some constant number set beforehand
myVariable = targetValue - static_cast<int>(round(readValue));

// After some operations that only check if myVariable is within a range

// There are several states in which LOG_myVariable can get set in case there is an error where data wants to get logged
LOG_myVariable = myVariable

All of the variables above are public and get initialised to 0. See in the context section to see how the readAverage function works.
This code block above gets repeated thousands of times in a loop and exits when I send an interrupt. LOG_myVariable only gets set in the method above. Sometimes it gives me normal values that I would expect, but it is returning 32767 very often. Is this some C++ syntax or function I am overlooking?
Some context:
An Arduino Due is using the MATLAB 2019 - Arduino Support Package Add-on. The variables described above are stored in memory and are dynamically overwritten during every logging function. I send them back to MATLAB via the C++ commandHandler as:
byte dataOut[2] = {
                  highByte(LOG_myVariable),
                  lowByte(LOG_myVariable)
                  };
sendResponseMsg(commandID, dataOut, 2);

In MATLAB, I convert it within a method after requesting the dataOut via sendCommand:
[dataOut] = sendCommand(arduinoObj, arduinoObj.LibraryName, commandID, dataIn);
            % Converts the two High and Low bytes from [dataOut] into a single integer.
            myVariableMATLAB = 256 * dataOut(1) + dataOut(2);

readAverage works like this:
/*
Reads the raw ADC sampled value of a pin an averagePoints amount of times.
All the values get averaged and the function returns `outputAverage`.
Note
*/
int myClass::readAverage(const uint8_t pin) {
  int i = 1, outputAverage = 0;  // Iteration value, OutputAverage
  double sum = 0, runningAverage = 0;
  // Array Initialization
  int readings[70] = { 0 };

  for (i = 0; i <= 70; i++) {
    if ((runningAverage >= 0) && (runningAverage <= 4096)) {
      // First 10% readings to setup a runningAverage value
      if (i < 70 * 0.1) {
        readings[i] = static_cast<int>(analogRead(pin));
        sum += readings[i];
        runningAverage = static_cast<int>(sum/(i+1));

      } else if (i >= 70 * 0.1) {
        // Normal Operation
        readings[i] = static_cast<int>(analogRead(pin));

        // Filtering Outliers
        // If xReading is within [LOWER_PERCENTAGE, HIGHER_PERCENTAGE] * runningAverage range.
        if ((readings[i] >= LOWER_PERCENTAGE * runningAverage)
        && (readings[i] < HIGHER_PERCENTAGE * runningAverage)) {
          sum += readings[i];
          runningAverage = static_cast<int>(sum/(i+1));
        } else {
          // Enter Error/ Out of Bounds Log Mode, how?
          // Meant to filter out
        }
      }
    } else {
      /* Enter Unknown Error Mode
      Note it defaults to a single measurement, but no signal is sent to mention this.
      */
      runningAverage = static_cast<int>(analogRead(pin));
    }
  }
  outputAverage = static_cast<int>(round(runningAverage));
  return outputAverage;
}

Any tips on improving the code/logic are always appreciated too!

Some findings:

Your for loop iterates over 71 results, but your array has only the length 70.
You may overwrite variables in the memory behind the array.
You can use else instead of else if (i >= 70 * 0.1) because it is just the negation of the if (i < 70 * 0.1). In the else case (i >= 70 * 0.1) is always true.

What is the type of myVariable? If you assign incompatible types (signage or length) an over- or underflow can happen. 32767 = 2^15 - 1 = 0b0011111111111111 (14 bits on) that looks pretty much like an underflow and a conversion of incompatible types.
EDIT:
By a second read of your question I saw another possibility of failure:
You copy the bytes of a two byte signed integer into 2 bytes and send it to matlab.
byte dataOut[2] = {
  highByte( LOG_myVariable ),
  lowByte( LOG_myVariable )
 };

Let's say you have a negative number in LOG_myVariable. In Memory this is represented with a one in the highest bit (MSBit) and the complementary bit string plus one (two's complement: See Wikipedia).
An Example:
16 bit signed int -1 is represented as 0b1111111111111111 you split it in two bytes 0b11111111 and 0b11111111. The you send it to Matlab.
Now it depends on how Matlab interprets the bytes. Are that unsigned int8 or signed int8? you combine the bytes like so:
 myVariableMATLAB = 256 * dataOut(1) + dataOut(2);

If Matlab interprets the bytes as unsigned  you get 256*(-1) + (-1) == -257 but that's not -1. And if it interprets the bytes unsigned it gets 256*255+255 == 65535 which is also not -1. I bet there is a negative number that gives you 32767.

Thanks for the help!  myVariable is an int. Will write the for loop properly, check if there might be an issue with signage (I had not looked at that before) and again revise types equivalence.  Will update if it works.

@dquintero If myVariable is an int then, I doubt that you have problems with negative values. Did you try the correct  array size of 71. It's a buffer overflow, and that's a serious error.

I've added a new idea to the answer.

Though I haven't read the question fully, 65535 is the max value of a 16 bit unsigned int, which is all bits set to one. If you cast that to a 16 bit signed integer you get -1. 32767 is the max value of a 16 bit signed int, which is all bits except the highest (sign bit) set to 1

This helped a lot, thanks!

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


text:
display pixel data on serial monitor using ov7670
i am trying to get the image data pixel by pixel from ov7670 to serial monitor and to store it into arduino memory which i can access later. i am using arduino mega and the camera is configured to 160x120 resolution. Any suggestions or code from which i can get help from?

In what way do you want to display "pixel data" on the serial monitor? And what does the serial monitor have to do with storing the data in RAM?

storing pixel data as a 2 dimensional array.

And what does that have to do with the serial monitor?

nothing. i just want to see what and how data is being sent

You are aware that at 24bpp the image will require about 7x more memory than the Arduino Mega has?  And at 8bpp it will need about 2.5x as much memory as the Mega2560 has? Where were you thinking of storing the image?

reducing the resolution to 160x120 and using 8bpp will require 19KB which is way less than memory of mega

No it isn't. The mega has 8kb. Thats much less than 19kb...


text:
arduino & drivers to control 5 brushed CIM motors independently?
i am a complete newbie in electronics but i'm a bit familiar with C.
i am building a machine that requires 5 little engines (12V 2.5in brushed CIM motors) & motor drivers (i need to adjust each motor's speed).
i've got an arduino UNO which i think is too small to control that many motors.
i would like to know if the setup i want was feasible to your opinion and which ardunio would i need to do that ?
i guess an Arduino Mega ?
also, i came accross this tutorial : https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/
it explains how to configure an arduino with a driver & two motors.
in fact i want to prepare the same kind of thing but with 5 motors that i can control independently.
which hardware would you recommend to do such a thing please ?
many thanks !
regards

Yes, with an UNO and a few of those L298 modules you should be able to control 5 motors independently, no problems.  Try the tutorial you gave the URL for and you'll see how to use more than 1 motor driver.

thanks. However i see that these drivers can control 2 engines, so i would need three of them. can i connect all three on a UNO ? will i have enough ports etc. ?
also, isnt there a better solution (like having 1 driver that can control up to 5 engines ?)

You should have just enough I/O with UNO, so long as you don't want to connect any other hardware/sensors.  Since this is unlikely, it would be better to use another board like Mega, but I'll provide solutions anyway in case you want to try them out:

Option 1:  For 5 motors controlled with L298N boards you'll need 15 output pins, 5 of which should be PWM.  Fortunately, there are 5 PWM outputs on the Arduino UNO on PORTB and PORTD.  The remaining 10 outputs need only be digital (PORTB has 1 and PORTD has 5).  You can use DDRC and PORTC commands to change function of the analog inputs labeled A0-A5, making them digital output, thereby gaining 6 more digital output pins for a total of 12 (more than the minimum 10 needed).
Option 2:  It is possible to use other PWM motor drivers that reduce number of pins required.  Examples are DRV8838 (link to supplier) and DRV8833 (link to supplier) where 2 wires are needed per motor channel.  As a bonus, these drivers are also significantly more compact than L298N.


text:
ESP8266 Arduino MQTT callback with dynamic topics
I have a program that depending on user input, it creates one or several objects that will publish data to a MQTT broker, each one with a different topic. This is already done. The ESP8266 also has subscribe itself to the same topics it publishes.
Now, the problem is that I have to create a dynamic callback in the ESP8266 to read the all the posible arriving topics to which the ESP8266 has subscribed and I am having trouble with that.
The callback function model is:
void MQTTcallback(char* topic, byte* payload, unsigned int length) {

// handle message arrived

}

The possible topics can be:
ObjectTL/TL_1
ObjectTL/TL_2
ObjectTL/TL_3
...
ObjectTL/TL_X
The number (TL_X) depends of the user input I mention at the beginning.
Thanks!

Without knowing more about the structure of your program and objects this is impossible to answer. Do you employ polymorphism for your objects? Do you have some storage where these objects are stored and are accessible? Do you have some form of list or array of the topics and their relationship to the objects?

I think using sscanf may help you
void MQTTcallback(char* topic, byte* payload, unsigned int length) {

  sscanf(data, "ObjectTL/TL_%d", dynamicTopicName);
  // handle message arrived
  your_dynamic_function(dynamicTopicName,byte* payload, unsigned int length)

}


text:
RDM6300 library not working on ESP8266
I have a RDM6300 RFID module which I am trying to connect to an ESP8266 by using rdm6300.h library.
I had it all up an running all along with other components but we had connected to the ESP8266 but we had to move from the breadboard to an actual wired setup. Everything kept on working except for the RFID reader. The way I used to do it was by making a reference to this approach (more or less):
#include <rdm6300.h>

#define RDM6300_RX_PIN 4
#define READ_LED_PIN 13

Rdm6300 rdm6300;

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

    pinMode(READ_LED_PIN, OUTPUT);
    digitalWrite(READ_LED_PIN, LOW);

    rdm6300.begin(RDM6300_RX_PIN);

    Serial.println("\nPlace RFID tag near the rdm6300...");
}

void loop()
{
    /* if non-zero tag_id, update() returns true- a new tag is near! */
    if (rdm6300.update())
        Serial.println(rdm6300.get_tag_id(), HEX);

    digitalWrite(READ_LED_PIN, rdm6300.is_tag_near());

    delay(10);
}

but now, after the re-arrangement it just stopped reading tags. What I did was to disconnect everything from the ESP and leave only the RDM6300 connected to it with the sample code. Unfortunately, it doesn't seem to detect any tags.
In order to test if the components are failing for some reason, I decided to test it by using SoftwareSerial.h library on it like this:
#include <SoftwareSerial.h>
SoftwareSerial RFID(2, 3); // RX and TX

int i;

void setup()
{
  RFID.begin(9600);    // start serial to RFID reader
  Serial.begin(9600);  // start serial to PC
}

void loop()
{
  if (RFID.available() > 0)
  {
     i = RFID.read();
     Serial.print(i, DEC);
     Serial.print(" ");
  }
}

and it worked perfectly fine. I was able to read the payload coming from the chip:

2 30 31 30 46 33 46 38 44 39 31 32 44 3

But, since I don't want to implement everything related to decoding this serial stream I decided to ask for your opinion what could be wrong here. It used to work without any problem but now it doesn't.
There is something interesting which I also noticed. When I run the first code snipped and change the ESP8266 pin used from 4 to 16(D0) and I upload it, once I move the tag close to the antenna the hardware light related to this pin starts flashing and when I bring the tag back (away from the antenna) it stops flashing.
This makes me thing that on a hardware level everything is fine but some software issues are happening.

a note to sw Serial sketch: pin 3 is hardware Serial RX

doesn't the rdm6300 library implement something like sw Serial? did you try sw Serial with pin 4 and rdm6300 with pin 2?

@Juraj this is the implementation: https://github.com/arduino12/rdm6300/blob/master/src/rdm6300.cpp

yes, it is a built-in sw Serial

@Juraj How does that help in my case?

did you try sw Serial with pin 4 and rdm6300 with pin 2?

I am using a single pin when making the connection between ESP8266 and RDM6300. It could be any digital pin.

yes but pin 2 works with SoftwareSerial. did you try it with RDM6300 library?

Yes, I did it that is the problem that it used to work now it doesn't. I have described it in my question.

in question you write about 4 and 16 with RDM6300 library.  and you write pin 2 works with SoftwareSerial. so did you try rdm6300.begin(2);?

I have tried that and GPIO2 led on board flashes when tag is near by, but rdm6300.update() never returns true. So, I can not detect the actual tag and read its ID. This is my problem.

What fixed the issue for me was to go to Boards manager on Arduino IDE and update to latest version:

Then I got the following error when compiling:

Board generic (platform esp8266, package esp8266) is unknown

In order to fix that, I followed these instructions.
And, I also removed rdm6300 library from C:\Program Files\Arduino\libraries and moved it in C:\Users\myusername\Documents\Arduino\libraries


text:
Is it possible to load both the arduino bootloader and a sketch onto an atmega328p via icsp?
i am familiar with uploading an arduino bootloader onto an atmega328p using another arduino via the arduino IDE. i have also installed software 'sketches' using that process which i believe leaves out the bootloader(meaning one wouldnt be able to upload new sketches in the future via usb). my question is: is it possible to load both the bootloader and a software program onto the chip via icsp? many thanks in advance.

The Arduino builder creates for AVR boards not only hex file for the sketch, but it creates a combined hex with bootloader and sketch too. It is for example for Blink.hex a Blink_with_bootloader.hex. If you use in IDE the "Export compiled binary" command in Tools menu, the builder puts the hex files next to ino file in your sketch folder.
If you want the command "Upload using programmer" to upload hex with the bootloader, modify in platform.txt the tools.avrdude.bootloader.pattern key to use "-Uflash:w:{build.path}/{build.project_name}_with_bootloader.hex:i"

Hi thanks very much for this. where can i find platform.txt?

it depends if it is the core bundled with IDE, then in IDE installation folder, or if it was installed with Boards Manager then packages are located in ~/.arduino15/packages/ on Linux and %userprofile%\AppData\Local\Arduino15\packages\ on Windows (AppData is a hidden folder).

yeah theres no txt file in there, just folder containing arduino cores i have installed...(i am on windows 10

something like packages/arduino/hardware/avr/1.6.21

hi i really appreciate this help by the way but am still having trouble. i tried editing the file but it had no effect (still uploading the hex file from the temp directory. i noticed that the platform.txt file was in a folder called 1.8.1 and the version of arduino i am running is 1.8.9 so i thought maybe i am editing the wrong document. so i removed the file from the folder, restarted arduino and tried uploading, expecting an error or something and it acted normally which makes me think that its not paying any attention to this file....?

the AVR core version is independent from IDE version. 1.8.1 is the latest AVR core and it is bundled with IDE 1.8.10. it is possible, you have one AVR core installation in C:\Program Files (x86)\Arduino\hardware\arduino\avr and other in Arduino15 folder

i have literally just got it working by switching over to my mac and uploading it using the terminal. (i tried it on my PC but the command kept being refused because windows cant handle spaces in a command, was drivingme nuts!) - thanks for all the help!


text:
LED GPS Speedometer Not Registoring Speed Above 0
I'm trying to make a speedometer that will change colors depending on the speed on which I am traveling.
If the speed is decreasing at any time or below 5 mph LEDs be red.
And if the speed is above 5 mph or increasing speed the LEDs will be a different color.
I am using an Adafruit 24 NeoPixel ring for LED's and a u-blox NEO-6 GPS module.
And the GPS is sometimes not registering the speed or any other GPS values and not switching colors when speed is at certain values or when it is increasing or decreasing. It tends to stay only one color no matter the speed. Also the GPS is not registering speeds above zero when I ride my bike or in a moving car.
I added a picture of the values I am getting, it seems to be connecting to satellites and getting correct GPS coordinates but as soon as I as I take it to real world test, the speed inst changing and LEDs are not changing. I also included a picture of the Arduino configuration I am using.
I am a very new to coding so any help would be very grateful.
(if anyone could help with the accelerating and decelerating code to that would be absolutely amazing!!!!)

#include "TinyGPS++.h"
#include "SoftwareSerial.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define LED_PIN  6
#define LED_COUNT 24
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800);
SoftwareSerial serial_connection(10,11);
int speedM;
TinyGPSPlus gps;

void setup() {
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  strip.begin();
  strip.show();
  strip.begin();
  Serial.begin(9600);
  serial_connection.begin(9600);
  Serial.println("Project Red Stop");
}
void loop() {
speedM = gps.speed.mph();
//int val = speedM;
 while(serial_connection.available())//While there are characters to come from the GPS
  {
    gps.encode(serial_connection.read());//This feeds the serial NMEA data into the library one char at a time
  }
  if(speedM < 5)
  //   if(speedM < 5 & val--)
  {
    Serial.println("Speed MPH:");
    Serial.println(gps.speed.mph());
    Serial.println("Satellite Count:");
    Serial.println(gps.satellites.value());
    Serial.println("Latitude:");
    Serial.println(gps.location.lat(), 6);
    Serial.println("Longitude:");
    Serial.println(gps.location.lng(), 6);
    colorWipe(strip.Color(0,100,0), 100);
   // strip.setPixelColor(0, strip.Color(0,100,0));                   // gps works faster with this:
    strip.show();
    delay(10);
  }
  else if(speedM > 5)
  //   else if(speedM > 5 & val++)
  {
    Serial.println("Speed MPH:");
    Serial.println(gps.speed.mph());
    Serial.println("Satellite Count:");
    Serial.println(gps.satellites.value());
    Serial.println("Latitude:");
    Serial.println(gps.location.lat(), 6);
    Serial.println("Longitude:");
    Serial.println(gps.location.lng(), 6);
    colorWipe(strip.Color(0,100,100), 100);
    strip.show();
    delay(10);
  }
}
void colorWipe(uint32_t color, int quick) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(0);                           //  Pause for a moment
  }
}

why do you expect the color of the LEDs to change if you cannot determine the speed?

I am just looking for help. You are right if i cant get speed i cant get color change. but i figured i just ask for help.

Separate your code into two parts: measuring speed with the GPS, and displaying LED colors according to acceleration & velocity (which you would provde as constants or terminal inputs). Get each part working, then recombine them. It's much easier to build up your application piece by piece, substituting trivial code - called 'stubs' - for the parts that don't exist yet, than it is to write the whole app and then try to debug everything at once. The stubs just provide made-up data instead of trying to get it from a complex devices like a GPS.

Why didn't you edit your first question. It is the same. You should delete one of them

Im very new to this site, i did not know i could edit previous posts, thank you for that fact ill try to remove the older post.

5 mph is slow (about 2.2 meters/second). And 2 meters accuracy is difficult to obtain (according to this stack exchange Q/A) for a normal GPS (and that is if the GPS signal isn't scrambled). Consider an alternative such as an acceleration sensor for such slow speeds and for such small speed changes.


text:
number generator show wrong segments on 7 segment display
I created a program to show a random number on a 7 segment display. It shows a random number in the serial monitor but always shows the same segments 'a c d and g'. anyone know hopw to fix this without changing the base of the coding its for and exercise so i need to have most of the code like I wrote it.
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }
};  //OFF

int buttonState = 0;
const int button = 12;
int randVal;
bool pressVal;
void num_Write(int);
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
    turnOff();
    pressVal = false;

  }
  else
  {
    if (pressVal == false)
    {
      int pin = 2;
      for (int i = 0; i < 7 ; i++)
      {
        digitalWrite(pin++, num_array[11][i]);
      }
      randVal = rand() % 10;
      pressVal = true;
    }
    Serial.println(randVal);
    if (randVal == 0)
    {
      void zero();

    }
    else if (randVal == 1)
    {
      void one();

    }
    else if (randVal == 2)
    {
      void two();

    }
    else if (randVal == 3)
    {
      void three();

    }
    else if (randVal == 4)
    {
      void four();

    }
    else if (randVal == 5)
    {
      void five();

    }
    else if (randVal == 6)
    {
      void six();

    }
    else if (randVal == 7)
    {
      void seven();

    }
    else if (randVal == 8)
    {
      void eight();

    }
    else
    {
      void nine();

    }
  }
}

void zero()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[0][j]);

  }
  delay(250);
}

void one()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[1][j]);

  }
  delay(250);
}

void two()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[2][j]);

  }
  delay(250);
}
void three()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[3][j]);
  }
  delay(250);
}
void four()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[4][j]);

  }
  delay(250);
}
void five()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[5][j]);

  }
  delay(250);
}
void six()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[6][j]);

  }
  delay(250);
}
void seven()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[7][j]);

  }
  delay(250);
}
void eight()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[8][j]);

  }
  delay(250);
}
void nine()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[9][j]);

  }
  delay(250);
}
void turnOff()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[10][j]);
  }
  delay(250);
}

Does your code really compile with all these forward declarations inside a function? Also very important: digitalWrite(pin++, num_array[11][i]); cannot work. The first dimension of num_array has only 11 elements. The element with the index 11 would be the 12th. So this is reading some data outside of the array.

yes i saw that and changed it already but the mlain problem is still the same. And i changed the code to look more like the one posted underneath here

@chrisl: ("Does your code really compile with all these forward declarations inside a function?") Yes, that's the Arduino IDE: generating a main() and function declarations.

@DataFiddler I just wondered, if it is ok to declare functions inside another function. I have seen this with other languages but not with C/C++ yet

@chrisl: Now I see your concern. A declaration inside a function is accepted without error.
But it won't work as as function call, as obviously intended.

Note, this is not an answer to your question, but I like to show some programming improvements, making your sketch  much shorter and easier to maintain.
Instead of having all functions one, two, etcetera, use a parameter to pass the number. So you get this: (I couldn't test it as I don't have an Arduino IDE at hand). Also you can use a for loop in the loop function to set the output pins.
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }
};  //OFF

int buttonState = 0;
const int button = 12;
int randVal;
bool pressVal;

void num_Write(int);
void digit(int value);

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

  for (int pin = 2; pin <= 8; pin++)
  {
    pinMode(pin, OUTPUT);
  }

  pinMode(button, INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
    turnOff();
    pressVal = false;

  }
  else
  {
    if (pressVal == false)
    {
      int pin = 2;
      for (int i = 0; i < 7 ; i++)
      {
        digitalWrite(pin++, num_array[11][i]);
      }
      randVal = rand() % 10;
      pressVal = true;
    }
    Serial.println(randVal);
    if ((randVal >= 0) && (randVal <= 9))
    {
      digit(randVal);
    }
  }
}

void digit(int value)
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[value][j]);
  }
  delay(250);
}

void turnOff()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[10][j]);
  }
  delay(250);
}

You can also remove turnOff if you treat it like digit 10 but that is not so clear (or put the implementation of digit to another function and call it from digit and turnoff.
To solve your problem, print the values of each pin to the serial monitor. If they are correct, there is a problem in your circuit. If they are incorrect, there is a problem in your sketch. In the latter case, add more print statements until you found the exact problem.
Update

Fixed void forward declaration to function call (see comment of chrisl)

If the digit function is never called, it means:

((randVal >= 0) && (randVal <= 9)) is false, however, that is not possible since it is initialized to 0 and with the rand function it gets always values between 0 to 9.
pressVal is always TRUE.

So check the value of pressVal, also add (lots of) print statements, especiallya after each if and else so you know exactly the flow of your sketch. You will see it's very easy to find the error. If you pinpoint the problem to a digitalRead that is not the expected value, THAN there is high likely a problem with your circuit (a button that is never going to be LOW or HIGH). In that case, you probably forgot a pullup/pulldown resistor.

Tnx for the feedback, will try to implement this seems alot neater than my coding. any idea how it would come that the wrong segments light up?

Not sure, I would follow the tip at the end, add more print statements to be sure that the sketch is ok, and if not, check the circuit.

So i tried finding the source of my problem and it never goes to  this part of the codevoid digit(int value) {   int pin = 2;   for (int j = 0; j < 7; j++) {     digitalWrite(pin++, num_array[value][j]);   }   delay(250); }

Did you remove the void in void digit(randVal); inside the loop function? Because that is wrong, since you don't want a forward declaration of a function there.

@chrisl I should have removed it (which I did now), probably you refer to that. And you're right, copy/paste error (having no Arduino IDE at hand). Thanks for the notification.

I updated my answer to give some more tips regarding the uncalled function.


text:
It gives some glitching on 7 segment display
It gives the right value on the monitor but it doesnt display the value on my display.
int pinNumb[7] = {2, 3, 4, 5, 6, 7, 8};
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }  //nothing
};

int pin = 2;
int button = 12;
int buttonVal;
int randVal;
bool pressVal;
void setup() {
  Serial.begin(9600);

  for (int i = 0; i < 7 ; i++)
  {
    pinMode(pinNumb[i], OUTPUT);
  }
  pressVal = false;
  pinMode(button, INPUT);
}

void loop() {
  buttonVal = digitalRead(button);
  if (buttonVal == 0)
  {
    //zero();
    turnOff();
    pressVal = false;
  }
  else
  {
    //zero();
    if (pressVal == false)
    {
      randVal = rand() % 10;
      pressVal = true;
      delay(100);
    }
    Serial.println(randVal);
    if (randVal == 0)
    {
      zero();

    }
    else if (randVal == 1)
    {
      one();

    }
    else if (randVal == 2)
    {
      two();

    }
    else if (randVal == 3)
    {
      three();

    }
    else if (randVal == 4)
    {
      four();

    }
    else if (randVal == 5)
    {
      five();

    }
    else if (randVal == 6)
    {
      six();

    }
    else if (randVal == 7)
    {
      seven();

    }
    else if (randVal == 8)
    {
      eight();

    }
    else
    {
      nine();

    }
  }
}

void zero()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[0][j]);
    pin++;
  }
}

void one()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[1][j]);
    pin++;
  }
}

void two()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[2][j]);
    pin++;
  }
}
void three()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[3][j]);
    pin++;
  }
}
void four()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[4][j]);
    pin++;
  }
}
void five()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[5][j]);
    pin++;
  }
}
void six()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[6][j]);
    pin++;
  }
}
void seven()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[7][j]);
    pin++;
  }
}
void eight()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[8][j]);
    pin++;
  }
}
void nine()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[9][j]);
    pin++;
  }
}
void turnOff()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }

}

a 7 segment display, a randopm value generated, pin 2-9 connected from arduino uno to the 7 segment display, The 7 segment display doesnt show the generated number just some random digits.

your code is overly repetitious ... you could remove 95% of the code and still retain desired functionality ... you also have some useless code ... for instance, inside the void zero() function, what is the point of having the first for loop? ... same for all the other functions

I am a complete noob to this so i just used what I learned, if you could give a bit more of a concrete explenation of what you mean that would be helpfull.

take a close look at the void zero() function ... what is the code doing? ... remember that the whole function executes in a few milliseconds .... do you really need the first for loop?

So do i just remove it, because that function made it so the display had no other digits on.

you only have one digit ... you have 7 segments

ah i mean segments;

You are continually incrementing the pin variable via pin++, but you are never resetting it to the start (2?) when a new number is to be written.  So it might work the first time but never after that.
Also, you clear the display with digitalWrite(pinNumb[i],LOW);
But you turn segments on with digitalWRite(pin,....); pin++.
Shouldn't you turn the segments on with digitalWrite(pinNumb[i] . . ?

yeah that would be easier but for the exercise i need to use an array, so that isnt possible.

my point is that you are NOT using the array when turning on the segments.

These can all be byte instead of int to save on memory:
int pinNumb[7] = {2, 3, 4, 5, 6, 7, 8};
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }  //nothing
};

int pin = 2;
int button = 12;
int buttonVal;
int randVal;

In addition, the array can be reduced to 11 bytes:
0bFD, // 0
0bC0, // 1
0bDE, // 2
etc.

Then your functions can do direct port manipulation to send bits 0-5 to the Port for D2 to D7, and bit to D8.
As written, these functions probably need some hold time so they don't just flash the LED and disappear:
void one()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[1][j]);
    pin++;
  }
}

what command should i use to hold them delay isntr really doing anything.

Longer delay()?  Like 250 (quarter second)? Experiment, see what looks good to you.

Now only the firts generated number gets shown properly all others after that are just broken segments.


text:
Somewhat Obfuscated Serial With SIM800L and Uno R3
I am successfully communicating with my SIM800L from my UNOR3 aside form some errors. But the biggest problem is with the serial monitor.
Responses from the SIM800L are somewhat obfuscated in that some characters are randomly wrong. See a snippet below:
Initializing...

OK

+C⸮T'⸮⸮b⸮j

OK

88l4110068165694746f

O⸮

+CQEG:Y⸮⸮H⸮⸮*⸮⸮C⸮
ERROR
⸮> H⸮⸮*⸮⸮
F⸮ROR
H⸮⸮
ERRO
H⸮⸮*⸮⸮

My code is also below.
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(11,10); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup()
{

  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(115200);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  updateSerial();
  mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  mySerial.println("AT+CREG?"); //Check whether it has registered in the network
  updateSerial();
  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("System on!"); //text content
  updateSerial();
  mySerial.write(26);

  delay(1000);
}

int milli = millis();
void loop()
{
  if (digitalRead(2) == HIGH) {
    digitalWrite(3, HIGH);
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("Button Pressed!"); //text content
  updateSerial();
  mySerial.write(26);
  } else {
    digitalWrite(3, LOW);
  }

  if (milli <= millis() - 500) {
    updateSerial();
    milli = millis();
  }
}

void updateSerial()
{
  //delay(300);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

The SIM800L runs off a separate power supply with a decoupling cap of 100n and the grounds are commoned.

Which SIM800L board are you using? What is the wiring and wire length between the uno and the module? Do you have level shifting in place for a possibly necessary 3.3V <-> 5V conversion?

Its a coreboard, one jumper wire and internal breadboard connections. I don't know what you mean by that unless you mean stepping down the serial voltage which did not help.

Do you have a link to the SIM800L board you're using?

I don't but it looks like this https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwjHgIL9zO_lAhXpAmMBHQhiCqEQjhx6BAgBEAI&url=https%3A%2F%2Fwww.banggood.com%2FSIM800L-GSM-GPRS-Module-Board-MicroSIM-Transfer-Card-Core-Board-Quad-band-p-1086519.html&psig=AOvVaw0LLO-qboau_2vsBH7ne9uo&ust=1574023590691357

So what voltage do you give as VCC and what level shifting circuitry are you using? This is just the bare module with a capacitor, you need to directly feed it with the necessary voltage of 3.4 to 4.2V and need at least level shifting from 5V to the target VCC.

It takes 3.8 v from my external power supply

Here is a good documentation: https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ --
Did you add a voltage divider to the RX pin?
If Arduino drive 5 Volt to the module's pin, the module might be destroyed.
The module has an automatic baud rate detection, so 115200 baud should be OK.
Do you configured your terminal with 115200 baud for the serial communication?
While sending, the Software Serial switches off all interrupts to make the micro clock more accurate. That might distort a timer interrupt for the hardware serial (but I don't really know, whether it needs one).
You changed the pins 2 and 3 for software serial (as from the example) to SoftwareSerial mySerial(11,10); Did you add the connections to the right pins. (RX?? <--> TX??)?
And last but not least. The axample uses 9600 baud for both serial interfaces. Perhaps your decision 115200 is too high.

I originally followed that, so tried changing the pins and baudrate which helped because with 9600 the chip wouldn’t respond and with the voltage divider from that tutorial I had the same issue.

@JamesConway Please check if you connected pin 11 of the arduino  to the TX pin of the module and pin 10 to the RX pin of the module. And check if you set your Serial Terminal in the Arduino ID to 115200 baud as you have configure the  hardware serial for 115200 baud too. By looking at the Serial output  I would say you have problems with the connection from the uno to the PC. So the baud thing is the most probable.


text:
ARDUINO + SIM808 POST ERROR 400 BAD REQUEST
Please, I need help with debugging communications through a SIM808 Device I'm using alongside an Arduino Uno R3 as a prototype for a tracking device. The sketch is provided below.
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define mydelay 10000
DFRobot_SIM808 sim808(&Serial);
char http_cmd[200] = "POST /api/tracker/ HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: 72\r\nHost: haulr.herokuapp.com\r\n\r\n{ \"trackerId\": \"1111\",\"weight\": ";
char mybuffer[145];
int count = 142;
long current = 0;
String longitude, latitude;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.begin(9600);

//  //******** Initialize sim808 module *************
  while(!sim808.init()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }
  delay(3000);
  Serial.println(sizeof(http_cmd));

  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
      Serial.println("Sim808 join network error");
      delay(2000);
  }

  //************ Successful DHCP ****************
  Serial.print("IP Address is ");
  Serial.println(sim808.getIPAddress());
    //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else
      Serial.println("Open the GPS power failure");
  current = millis();
}

bool mylocation(){
  bool control = LOW;
  long prevfix = millis();
  Serial.println("im here");
  while(millis() - prevfix < 3000){
    if (1 > 0){
      Serial.println("got a fix");
      latitude = String(sim808.GPSdata.lat,6);
      longitude = String(sim808.GPSdata.lon,6);
      control = HIGH;
      break;
    }
  }
  if(control){
    delay(1000);
     sim808.detachGPS();
  }
  return control;
}

void loop() {

  // put your main code here, to run repeatedly:
  if (millis() - current > mydelay){
  sim808.attachGPS();
  bool getloc = mylocation();
  if (getloc){
    float weight = 10;
    if (weight <= 0) weight = 0.00;
    latitude = (String) weight + ",\"location\": \"" + latitude + "," + longitude + "\" }";
    int cnt = count;
    for (int i = 0; i <= latitude.length(); i++){
     http_cmd[cnt++] = latitude[i];
    }
    postData();
  }
  current = millis();
 }
}
void postData(){
  delay(1000);
  if (!sim808.is_connected()){
  label:
  //*********** Establish a TCP connection ************
  if(!sim808.connect(TCP,"haulr.herokuapp.com", 80)) {
      Serial.println("Connect error");
      goto label;
  }else{
      Serial.println("Connect haulr.herokuapp.com success");
  }
 }

  //*********** Send a POST request *****************
  Serial.println("waiting to fetch...");
  sim808.send(http_cmd, sizeof(http_cmd) - 1);
  while (true) {
      int ret = sim808.recv(mybuffer, sizeof(mybuffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }
      mybuffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(mybuffer);
      break;
  }

  //************* Close TCP or UDP connections **********
  sim808.close();

  //*** Disconnect wireless connection, Close Moving Scene *******
  sim808.disconnect();
}

After uploading the sketch, I got varying responses from the SIM808. After posting the data, I checked the database for updates and got none. I have used POST MAN severally to update the database but every other update (data) sent from the device is not stored. Kindly find the snippets of the responses received below. This is the only bit left at this stage of the prototyping phase and my team needs me to resolve this very quickly.
AT
AT+CFUN=1
AT+CPIN?
182
AT+CSTT="cmnet","",""
AT+CIICR
AT+CIFSR
IP Address is 10.31.234.248
AT+CGNSPWR=1
AT+CGNSTST=1
Open the GPS power success
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } fetch over...
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT

While troubleshooting, I later observed that three of the sent posts actually received responses stated as "Bad Request"  alongside some other headers. I don't know what the issue could be. Please, kindly advise me on what steps I need to take. Thanks.

The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error .  You might posting the data in wrong format or your request format is wrong, only those cases you get 400 as status.

I have tried checking the format of the post request. I have also run it by some of my colleagues. We cannot pick out any error from it yet. Is there anything in that post request that could flag off an error? Thanks in advance for your response??

had you tried wit postman to send post request to same server with same data format?

Yes, I tried with postman. It worked quite well but I couldn't get it to work through my arduino. I eventually changed the content type to Content-Type: application/x-www-form-urlencoded. Then I sent the data in a non-json format. This worked well with the arduino and I'm sticking with this method of solving the problem and a lot of others. Thanks a lot.


text:
Decoding serial packets, please check my work!
I have a Innovate LC-2 wideband and Megasquirt ECU. The Innovate wideband has RS232 serial output I would like to use instead of the default 0-5V analog output.
So I designed and built a board using a MAX3232, MCP2515/MCP2561 CANbus, and ATMEGA328PB. I also have a MAX31856 for EGT, LIS3DH for accel, and BMP280 for barometer. I also mucked about on forums and threads until I understood enough to decode the format. What I have now works, but I would like someone more experienced to check it for errors!
The serial format is described here...
https://www.innovatemotorsports.com/support/downloads/Seriallog-2.pdf
My code looks a bit like this, it is part of a main loop reading data from other sensors as data is ready, so the loop is non-blocking. The main loop also transmits data over canbus at set intervals.
This does work, but is there anything I can do to make it more resilient?
Thank you in advance!
    if (Serial.available() > 0) {
      EGO_rx_byte=Serial.read();                                            // pull data from serial
      if ( (EGO_rx_byte & 0xA2) == 0xA2 ) {                                 // synchronization byte - bits 15-8 1x1xxx1x
         EGO_packet[0] = EGO_rx_byte;                                       // Store buffer data to Packet
         EGO_packet_index = 0 ;                                             // This is the start of the header packet, bits 15-8
      }
      else if ((EGO_packet_index == 0) && ((EGO_rx_byte & 0x80) == 0x80)) { // If index = 0 & bit 7 = 1 = 2nd syncro byte
         EGO_packet_index=1;                                                // this is second half of header packet, bits 7-0
         EGO_packet[1]=EGO_rx_byte;                                         // store buffer data to packet
      }
      else if ((EGO_packet_index == 1) && ((EGO_rx_byte & 0x42) == 0x42)) { // If index = 1 & 0x42 is set on next packet likely valid LC2 packet...
         EGO_packet_index=2;                                                // This was the third packet in six - Zero indexed
         EGO_packet[2]=EGO_rx_byte;                                         // Store buffer data to packet
      }
      else {
        EGO_packet_index++;                                                 // all else are data packets, increment the packet counter by one
        EGO_packet[EGO_packet_index]=EGO_rx_byte;                           // Store buffer data to packet in series
      }
      if (EGO_packet_index == 5) {                                          // Done recieving packets, ready to construct data... 2 words per EGO, 1 header packet
         EGO_status = (EGO_packet[2] & B00011100) >> 2;                     // status bits are in word 1 bits 12-10
         EGO_data = (EGO_packet[2] & B00000001) << 7;                       // AFR Multiplier - think this is programmed with lmprogrammer - bits 8, 6-0
         EGO_data += EGO_packet[3] & B01111111;                             // these are the 6-0 bits
         EGO_lambda = EGO_packet[4] & B00111111;                            // 13 bit lambda value, data depends on status bits
         EGO_lambda = EGO_lambda << 7;                                      // shift bits from first half of data packet
         EGO_lambda += (EGO_packet[5] & B01111111);                         // add bits from second half of packet
         switch (EGO_status) {                                              // Output data depends on Status
         case 0: Lambda = EGO_lambda; EGO_conn = 13;                        // EGO Output is valid - Lambda in 10 bit scale
         if (Lambda > 1023){Lambda = 1023;}break;                           // Megasquirt expects 0-1023 input value
         case 1:Lambda = 1023;EGO_conn = 13;break;                          // EGO Output is valid - reporting O2% in 1/10%
         case 2:EGO_conn = 10;Lambda =  500;break;                          // Free air calibration
         case 3:EGO_conn = 11;Lambda =  500;break;                          // Need Calibration
         case 4:EGO_conn = 12;Lambda =  500;break;                          // Warmup
         case 5:EGO_conn = 10;Lambda =  500;break;                          // Heater Calibration
         case 6:EGO_conn = EGO_lambda;Lambda =  500;break;                  // Error code 1-9
         case 7:EGO_conn = 0;Lambda =  500;break;                           // Reserved
         default:Lambda =  507;EGO_conn = 0;break;                          // Something else is happening, output 14.7 and error
         }
    }
}

That looks pretty robust to me as it is. You might like to make use if the length attribute of the header though to receive the right number of bytes for the payload though.

Thank you for the reply!
Oh, you mean pulling the header length from the first packet to determine the number of following packets? I have some very poorly written code that does so, but I lack the hardware to test more than one LC-2 on the serial bus at the time!


text:
Adafruit/Arduino SAMD BSP package and adding SAME51 compatibilty
I am trying to make a SAME51 variant of an arduino board, in the end I would like to have an arduino compatible board, BSP, and library for controlling canbus.
I have already gone through some things, but I believe I need a slight bit of guidance for the next step, mostly just reference files.
What I have done so far is fork the adafruit SAMD BSP and added a variant. Since the normal Bossa does not recognize my CPU ID I had to add it and recompile bossa. I also went ahead and made a UF2 style bootloader and a corresponding windows driver with matching PIDs/VIDs. At this point I had a working arduino board, but it still thinks it's a SAMD51, not a SAME51. Asking for anything to do with can leads to missing references, which makes sense since SAMD does not have CAN (but it's in DFPs?)
So finally I decided to edit boards.txt again and change the build flag from -D__SAMD51G19A to SAME51G19A. I also found SAME51 DFP online and added them to arduino/tools/CMSIS-Atmel, but this is just me guessing. I also used the DFP to build the UF2 bootloader previously. This breaks everything and if I had to guess from looking the compiler is missing the DFP and everything is very upset about that.
Earlier I had found a version of what I am after, except for a SAMC21 and not a SAME51. I thought the can peripheral was the same for each, so this should be an easy port besides maybe configuring the gclk since those are different from M0 to M4. If you compare DFPs, both are identical as far as CANBUS is concerned, at least at that level.
But, using this code and the SAMC21 BSP referenced in the readme will compile!
https://github.com/hugllc/samc21_can
Is it something to do with adafruit fork using CMSIS 5.4 and arduino using CMSIS-Atmel 1.2.0?
Thank you in advance for any and all tips!

https://arduino.stackexchange.com/questions/54484/adding-a-custom-board-to-the-arduino-ide/60660#60660

I have that part worked out, and it works fine for the SAMC21. When compiling for SAME51 all definitions are missing. I believe the issue is Arduino SAMD core has compile support for SAMC21 in /arduino15/packages/arduino/tools/cmsis-atmel/1.2.0.../samc21. By default there is no same51, so using SAME51G19 as a build flag fails.
I don't know how to add support for same51, nor am I even sure the adafruit fork uses the same compiler tools in the first place. I think that's where I'm stuck.

and if you reference the Adadruit BSP with SAMD51 support? https://github.com/adafruit/ArduinoCore-samd

That is the initial fork of the BSP I modified, not the official arduino BSP. I still have the official core installed because the Adafruit BSP references many of the arduino/tools/ files.

I think I may have made it work. I am not certain, but I think any sam.h defines in the BSP point to CMSIS-ATMEL. The default does not have same51 support, and just adding the files isn't enough. Have to edit the sam.h files to make sure the required files are included.


text:
ATMega32u4 SLEEP instruction
I was reading the ATMega34u2 datasheet and trying to figure out Sleep Mode. I know most people recommend using avr/sleep.h library. But I wanted to try out using the registers. I am fairly new to all this so sorry if this an easy question but I can't seem to really find anybody doing it like this.
When checking which registers to adjust it says this:

The SE bit must be written to logic one to make the MCU enter the sleep mode when the SLEEP instruction is executed. To avoid the MCU entering the sleep mode unless it is the programmer’s purpose, it is recommended to write the Sleep Enable (SE) bit to one just before the execution of the SLEEP instruction and to clear it immediately after waking up.

Now I understand setting the bit but what exactly is the sleep instruction? How do I call it in my arduino program?

google ATMega34u2 sleep mode assembly language

SLEEP is an assembly instruction.  You can execute assembly with GCC's Inline Assembly facility.
In short:
asm volatile("SLEEP");

will do what you want.
The avr/sleep.h file has sleep_cpu() defined as:
#define sleep_cpu()                              \
do {                                             \
  __asm__ __volatile__ ( "sleep" "\n\t" :: );    \
} while(0)

Which is essentially the same thing - just wrapped in a block to isolate it from the rest of your code somewhat.


text:
ATMEGA328P-U vs ATMEGA328-PU
On my Arduino UNO the chip part number is ATMEGA328P-U, i recently bought a ATMEGA328-PU to make a standalone Arduino. realized the part number differences after receiving the package...
I noticed that some arduino UNOs have the chip with part number of ATMEGA328P-PU! I'm totally confused!
Those chip are the same? can i use the one that i bought for an standalone Arduino?
If no what are the differences?

The datasheets say what...?

328 / 328p: https://forum.arduino.cc/index.php?topic=60001.0

Uno has ATMEGA328P-PU. ATMEGA328-PU will work in Uno. ATMEGA328P-U doesn't exist

The main difference is the bit before the -. That is, the 328 vs the 328P.  The "P" there denotes "Picopower" which allows the chip to run at very low power consumptions.
Basically the P version is a more modern version of the non-P chip.  There are probably other internal differences too but you will have to check the datasheets thoroughly for those.
Everything after the - is to do with the packaging and environmental grading of the chip.  For example PU is a -40C to +85C grade DIP chip. ANR is a -40C to +105C grade TQFP chip, etc.
If you see 328P-U then that's probably a fake chip. There's no such thing as single U suffix.

User line_code from forum.arduino.cc recently received an ATMEGA328P-U (or actually ATMEGA328P U) from Mouser (a company which you would not suspect to send out fakes or source from the gray market). He asked Mouser (who contacted the manufacturer Microchip) and got the following response:

As part of Part marking change due to the migration from Atmel to
Microchip, the package identifier has been removed from the device
marking as this can be observed visually for different packages. This
will be updated in the upcoming revisions of the device datasheet.  As
per this new marking the ATMEGA328P U are valid devices without any
process change. [...]

(Source: https://forum.arduino.cc/index.php?topic=561928.msg3890391#msg3890391)
So the P stands for pico power (the low power modern version) and if the package is a 28-pin DIP like in the photo I took then this specific ATMEGA328P U is an ATMEGA328P-PU.

Note that the Microchip response does say that the packaging is omitted from the marking. Hence we can expect ATMEGA328P Us to pop up in other packages. What the U stands for is unclear.

The U signifies ROHS compliance.  For specialized applications other options are available.  The ATmega328-MMH, for example, has a NiPdAu lead finish.

@Julian
I went through all the Product Change Notification pdfs in this mouser link https://www.mouser.in/ProductDetail/Microchip-Technology-Atmel/ATMEGA328P-PU?qs=K8BHR703ZXguOQv3sKbWcg%3D%3D
There is no mention of ATMEGA328p U. Do you have some official docs that is saying ATMEGA328P U is a legit IC Code?

There are three die types:
328
328P
328PB
all have different signature bytes which may or may not impact loading code into them. Generally tho the programming software needs to know which part type is being used, at a minimum for installing bootloader code.  Serial downloading may end up ignoring the signature bytes of a bootloaded part.
They can be had in different packaging, this is what Digikey is showing as available options:
-PU - 28 pin DIP
-AU - 32 pin TQFP
-AN - 32 pin TQFP
-MM - 28 pin leadless package, smaller than 32 pin leadless
-MN - 32 pin leadless package
-MU - 32 pin leadless package
-15AZ - 32 pin TQFP, rated for a higher temperature range
-15MZ - 32 pin leadless package rated for a higher temperature range
Any letters to the right of those seen when ordering indicate the method they are supplied - loose parts, parts in a reel, parts in a tube, etc.
Anything else is either an older part that did not follow the convention, or is a counterfeit part.
Tables 38.7 and 38.8 lists these options for the 328 and 328P for example, with H indicating a type of lead finish, and R indicating Tape & Reel availability:
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
ATmega328-AU
ATmega328-AUR
ATmega328-MMH
ATmega328-MMHR
ATmega328-MU
ATmega328-MUR
ATmega328-PU
And 328P options:
ATmega328-AU
ATmega328-AUR
ATmega328-MMH
ATmega328-MMHR
ATmega328-MU
ATmega328-MUR
ATmega328-PU
With these rated to 105C
ATmega328P-AN
ATmega328P-ANR
ATmega328P-MN
ATmega328P-MNR
ATmega328P-PN
I think you need to pull up the Automotive data sheet to see the Z numbered parts.
And the PB is a different data sheet as well.

That help a lot, but in case other people are finding this looking for ATmegaXX-XXPI, then: PI are 40-pin, PDIP

'328s are never 40-pin. There are 40-pin DIPs in the Atmega family, and some, like the '644, '1284P, have been brought into the Arduino IDE. I like the '1284P myself; 32 IO arranged as 4 8-bit ports, dual hardware serial, 128K flash, 16K SRAM (twice what the '2560 has).

Good point and my comment was more general for ATmega's, as this is the first google hit and your answer are a good reference, so i just wanted to add the answer to my own question there was about ATmega16-16pi, just in case it could help somebody else finding this looking for that.

The 328PB also won't work with the stock Arduino IDE and has a number of differences from the earlier parts.  Some of these are physical; e.g. a pin that was VCC is now a GPIO.  For support in the Ardiuno IDE (or Eclipse/Sloeber) you'll need to install MiniCore.


text:
How do I segment Arduino program when line count is so large that code maintenance is difficult?
I'm looking for the Arduino/C++ equivalent of COBOL's 'copy' statement.
I'm working on a program that is approaching 600 lines of code in the TopLevel.cpp source file.  This is hard to manage because I feel like I spend all my time scrolling up and down the source file.  The code in question does not easily lend itself to conversion to a class because it is sections of loop/main.  I've tried using xxx.h (for storage definitions) and yyy.cpp (for code sections).  Those approaches yield error messages, which I think are due to the different timings of the Arduino pre-processor and the compiler code that resolve the #include statements.
Thanks for the help.
--CVTBrakeman
p.s.
I wrote my first program in 1967; the language was GOTRAN on an IBM 1620.  For almost 50 years, I made my living designing/writing COBOL and SAS code on IBM mainframes.  Yes, Y2K was real and I survived it.

you can have many .ino files in an Arduino project. Use Add file in Sketch menu in IDE. what error messages for h/cpp?

You can use a #include directive. You can build your C++ subclasses in separate .CPP & .H/.HPP files. The Arduino IDE is just a wrapper around a C++ compiler and a bunch of scripts to load the .HEX to the Atmel chip using ICSP.

https://arduino.stackexchange.com/questions/60656/split-up-arduino-code-into-multiple-files-using-arduino-ide/60659#60659

Thanks for the help; I think the solution is to restructure the program and convert my 'include' code to separate classes. Probably should have done that in the beginning.  It looks to me as if included files are compiled separately.  Variables defined in the included code are no longer visible to the setup/main code blocks.  Thanks for your help.

This is more like a general programming question than an Arduino
question but, anyway...
You don't need to write classes to sort your code into files. You just
need to think in term of independent pieces of functionality. Each of
those pieces would be implemented in a .cpp file, with the interface
declared in a .h file.
As an example, let's say your Arduino is controlling an hyperdrive.
Managing the dilithium plasma generator is one of those functionalities
that can be separated in its own files. The .h files declares everything
that is needed for using that functionality:
plasma_generator.h:
// Read the state of the plasma.
float plasma_density();
float plasma_temperature();

// Control the plasma.
void set_plasma_target_temperature(float target_temperature);
void ignite_plasma();
void turn_off_plasma();
void add_dilithium(float amount);

Then the .cpp file contains the implementation:
plasma_generator.cpp:
#include "plasma_generator.h"

// A "static" function is a function private to this module.
static float get_gauge_reading(int gauge_number)
{
    ...
}

// Implementation of a public function, described in the .h file.
float plasma_density()
{
    float raw_reading = get_gauge_reading(42);
    ...
}

...

In your main program (or even in other modules, if needed) you
#include the .h file and use the functionality defined therein.

There are two ways of doing this:

Multiple INO files

The Arduino IDE combines multiple INO files into one single CPP file before compilation. You can split your program across multiple INO files at will. It makes it easier to manage, since you can split your program into logical chunks at will, but you don't have to think much beyond "which file shall I stick this function in?"

Create libraries

Some functionality of your program could be placed into a library or multiple libraries. This is kind of like option 1, but you have to think more about C++ syntax and suchlike that with INO files (function ordering, externs, etc). It does have the benefit that you could easily re-use code between programs, though
Personally I usually use option 2 before option 1. If a code is genericisable ("able to be made generic") then it can be made into a library - after all, I may want it later for some other program. However, if all you want to do is split your program into different chunks with each chunk a different topic or area of your program then option 1 is definitely for you.
Alternatively you might consider a different IDE, such as UECIDE which gives you such things as function bookmarks& to make navigation of your code easier.


text:
Having problems compiling this code for NRF24l01 on stm8s103f3p6
It said it has mutiple libraries were found for "nRF24L01.h"
but i check the Ardurino libraries I can only found one.
And it work fine if I compile it to Arduino uno.

//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(8,9 );  // CE, CSN

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

void setup() {
  // put your setup code here, to run once:

  while (!Serial);
    Serial.begin(9600);

  radio.begin();

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

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

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

  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));

    Serial.println(text);

  }

}

Here is the error message
Arduino: 1.8.10 (Windows 8.1), Board: "STM8S103F3 Breakout Board"

Multiple libraries were found for "nRF24L01.h"
bash.exe: warning: could not find /tmp, please create!
 Used:
C:\Users\UserName\Documents\Arduino\libraries\RF24
C:\Users\UserName\AppData\Local\Arduino15\packages\sduino\tools\sdcc\build.10738/bin/sdcc sketch\receiver.ino.cpp

nul re12 -c -Ddouble=float -DUSE_STDINT -D__PROG_TYPES_COMPAT__ -E -MC -mstm8 -DSTM8S103 -DF_CPU=16000000L
-DARDUINO=10810 -DARDUINO_STM8S_BLUE -DARDUINO_ARCH_STM8
-IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0\cores\sduino
-IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0\variants\standard
-IC:\Users\UserName\Documents\Arduino\libraries\RF24
-IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0/STM8S_StdPeriph_Driver/inc
-IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\tools\sdcc\build.10738/include
Mark re12:C:\Users\UserName\AppData\Local\Arduino15\packages\sduino\tools\sdcc\build.10738/bin/sdcc -c -Ddouble=float -DUSE_STDINT -D__PROG_TYPES_COMPAT__ -E -MC -mstm8 -DSTM8S103 -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_STM8S_BLUE -DARDUINO_ARCH_STM8 -IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0\cores\sduino -IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0\variants\standard -IC:\Users\UserName\Documents\Arduino\libraries\RF24 -IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\hardware\stm8\0.4.0/STM8S_StdPeriph_Driver/inc -IC:\Users\UserName\AppData\Local\Arduino15\packages\sduino\tools\sdcc\build.10738/include sketch\receiver.ino.cpp -o nul
cpp gefunden
In file included from C:/Users/UserName/Documents/Arduino/libraries/RF24/RF24.h:18,
                 from C:\Users\UserName\Desktop\mad\receiver\receiver.ino:4:

C:/Users/UserName/Documents/Arduino/libraries/RF24/RF24_config.h:143:30:
fatal error: avr/pgmspace.h: No such file or directory

compilation terminated.

exit status 1
Error compiling for board STM8S103F3 Breakout Board.

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

High likely this library is for Arduino only, not for your MCU

The sduino core is lacking any form of PROGMEM compatibility layer. Contact the maintainers of it.

the error is fatal error: avr/pgmspace.h: No such file or directory. ignore the 'multiple libraries' warning


text:
PWM using timer3 for servo control won't generate any output
I'm making a program for a small robot arm controlled by four servos.
Problem: I need for PWM outputs, timer1 has three so i need to use timer3 for the last one
The main program and the timer1 outputs work great, the robot arm is functional. My problem is in the initialization of the PWM's. The PWM for timer1 is set to phase-correct, 64 pre-scaling and using WGM1[0-3] to 1010 so that i can use ICR1 as the top value, leaving OCR1[0-2] for counting up so output is on OCR[0-2].
According to the ATMEGA 2560 data book I should be able to initialize an identical PWM with timer3 with just one output in just the same way, but it just won't give me any output at all on OC3A.
Any help is greatly appreciated! :)
PS this is for a class project, so no servo libraries, and no major changes to the program (the current code is already approved by my professor, also the due date is in 24 hours so i don't have the time. Yes I know that sounds like trouble, but the project is technically done, I'd just really really like to get a full range of motion on my little Plexiglas robot)
PWM.c:
// INITIALIZE PHASE CORRECT PWM ------------------------------------------------------------------------------
void initPWM()
{
    DDRB |= (1<<DDB7);      // Output pin 5 OC3A
    DDRB |= (1<<DDB5);      // Output pin 11 OC1A
    DDRB |= (1<<DDB6);      // Output pin 12 OC1B
    DDRB |= (1<<DDB7);      // Output pin 13 OC1C

    // Initialize TIMER1 for OC1A, OC1B, OC1C:
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11);     // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode
    TCCR1B |= (1<<WGM13)|(1<<CS11)|(1<<CS10);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal
    // Initialize TIMER3 for OC3A
    TCCR3A |= (1<<COM3A1)|(1<<WGM31);                            // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode
    TCCR3B |= (1<<WGM33)|(1<<CS31)|(1<<CS30);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal

    // TIMER1 Top and bottom value:
    ICR1 = 5000;
    TCNT1 = 0;
    // TIMER3 Top and bottom value:
    ICR3 = 5000;
    TCNT3 = 0;

    // Start PWM in OCR = 200 (mid value for servo)
    OCR3A = 200;
    OCR1A = 200;
    OCR1B = 200;
    OCR1C = 200;

}

I can see nothing wrong in your program except this:
DDRB |= (1<<DDB7);      // Output pin 5 OC3A

This is setting pin PB7 as an output, whereas
digital pin 5 (OC3A) is PE3.

I found that out a few hours after posting, despite having raked through my code for two days and now i feel like a bit of an idiot... Thank you very much for the help


text:
Connect a hundred SIM800L's to Arduino (or any other board)
Is there a way to connect one hundred SIM800L's to Arduino? Essentially I want to be able to communicate with any of them that I want. If Arduino isn't capable of doing this, what do you suggest, so I could connect to and control 100 SIM cards?
Thanks for your help in advance!
R.

Wow, 100 is much. Maybe with a series of multiplexer modules (only talking to one at a time). But why do you need to talk to 100 SIM800L? What are you trying to achieve?

It is likely the additional hardware needed will exceed that of most Arduino platforms.  That is, while using an Arduino Uno may work, it would be like building a race car from a go cart.

@chrisl That's for a project I am creating a PoC for. Ideally I want to be able to talk to an unlimited number of SIMs for making calls, sending texts etc. Can you please provide a link or example for using "multiplexer modules" ?

@st2000 That's fair do's. It doesn't really have to be an Arduino. I just don't know how to connect a SIM800L to a Desktop computer for example, let alone connecting hundreds of them. If money wasn't an object (within reason), what hardwares would you propose to achieve this? I'm a software engineer so coding it up is I guess the easier part, as long as it's possible to talk to the modules.

You need to think modular. Forget one central "brain" with hundreds of modems connected to it - think lots of small brains with only a few modems on each one, all communicating to a central controller over some other transmission medium (ethernet?)

@Majenko Could a SIM800L be connected to a normal desktop motherboard? Would that be through a USB-to-Serial interface? If so, are there these interfaces that provide, say 50 serial output pins so I could connect 50 SIM800L's?

@jsotola It's going to be sending lots of texts from different numbers.

@jsotola I highly doubt they will work without a SIM card active somewhere in the network. Also the networks I've been on don't support that feature. Also I want to be able to receive texts too. Maybe add a phone call feature later on too. So no, I will need to physically connect my 100 sim cards somewhere.

now it is clear what you are trying to do .... your question above is still unclear ... please edit the question to include all of the information that you put in comments, then delete the comments

You left unclear, what your exact requirements are. So the answer will be as general as your question. The SIM800L uses the Serial interface (UART). So the point is to connect to 100 different serial interfaces.
If it is ok to talk to each SIM800L sequentially (only one at a time), you can use a series of multiplexers. A multiplexer chip connects one pin to one of multiple pins (called channels here). Depending on the used chip, the channel can be selected in different ways. The standard way is with simple digital input pins, that construct a binary number. So for 8 channels you need 3 input pins (2^3). Other ways are through communication interfaces like SPI or I2C.
Normally a multiplexer has only 8 channels, though you can also find once with more, but I don't think there are multiplexers with 100 channels. So you could next the multiplexers. If you put another multiplexer on every channel of the first multiplexer, you get 8*8 = 64 channels with 9 multiplexers in total. Add some more multiplexers on the next level and you will get to over 100 channels. Then you need 2 of these multiplexer trees to multiplex both serial lines (TX and RC). Since that are a lot of multiplexers and thus a lot of inputs to choose the correct channels, you could use multiplexers with SPI or I2C interface. The first would require 1 digital output pin of the Arduino per multiplexer as slave select pin, the latter would require either a multiplexer type, that can as many different I2C addresses as multiplexers in your system, or a bit more complex programming and also 1 pin per multiplexer to change the address of the chip to configure. How to use these multiplexers with Arduino depends on the used chip. You should refer to it's datasheet.
As you now see, connecting one single Arduino to 100 serial interfaces it a complex task. Depending on your actual requirements and goals in your "PoC project", it might be a better way to follow Majenkos advice and build it more modular with multiple Arduinos/microcontrollers.

Thanks, I understood what those multiplexers do. I assume the multiplexers switching between pins would have a delay. That, and the fact I wouldn't be able to for example ask 10 SIM800L's to each do something (multithreading if you like), makes it a not so good option. Agreed Majenkos' solution sounds better.