text:
How do I use a servo in an interrupt?
I am working on a small circuit now where I increment the rotation of a servo motor and at the same time blink a LED.
I have used all methods I know to do it but still it does not work or it blinks and then the servo start working but never both at the same time.
This is what i am basically working with:
  for(position=0;position<=90;position=position+5){
    digitalWrite(led_pin,HIGH);
    delay(200);
    digitalWrite(led_pin,LOW);
    delay(200);
    servoBar.write(position);
    delay(15);
  }

But it blinks once and then it stops and the servo start working right after that.
I know I must not use delays in interrupts. I am using a function that I can but just to show you what I am working with.

The problem is that the delay routine is blocking. It stops operation and blocks other things from happening. Have a look at the Blink without delay example in the example tab. (also linked below)
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
What you need to do is to not block. Call the time checker often and check if the time you want delayed has run out. The perform the action needed to be done at that time.
This is a more sophisticated way to deal with timed events. Also look at this
Demonstration code for several things at the same time.
https://forum.arduino.cc/index.php?topic=223286.0
Have fun learning. :)

If you want the timing mechanics of the interrupt, you'd want to create very slim loop() routine that only checks if your custom "move the servo" flag is set. If it is, remove the flag and move the servo, and use the interrupt only to set the flag.

A good way to manage timing without delay is to use:
if(millis()-lastCheck > delayPeriod){
lastCheck=millis();
doStuffHereOrChangeServo();
}

This code is naturally overflow-safe and is actually how delay() works. The difference is that delay() uses a while() loop that breaks when this condition is met, so it prevents any code after the delay from running UNTIL delay completes. That's why you are getting odd pauses in your code.
As a side note, it's actually a fun project to build a simple task scheduler that uses a list of function pointers and a variation on this method to do completely generic scheduling. If you want to try that route, you'd keep a struct holding the function pointer and a signed integer larger than your maximum intended delay size. Then, every time the scheduler is called, you subtract the difference between millis() and the stored value of millis() from each of those integers in the struct. Once that goes negative or zero, the task can run!


text:
Arduino pin 13 as PWM output, not possible?
I have noted on more than one occasion the comments in sketches "reserving pin 13 for future PWM backlight dimming of the LCD" while using Uno and Nano boards.
Am I missing something ?  I always considered it NOT possible as PWM output is only available on pins 3,5,6,9,10 and 11 on most boards.

Have you checked schematics and processor datasheets?  That pin may be backed with PWM hardware, but not be supported by Arduino software for the reason stated.  Remember that an Arduino is a product of a little self-contained ecosystem with certain design goals in mind.

you can program any pin to output a PWM signal

yes, but analogwrite() only works with those pins backed by hardware PWM circuitry on-chip

Arduino pin 13 is SCK/BP5 on the ATmega8 MPU, there's no hardware PWM capability on that pin, so any PWM would be software driven.

source: Stack Exchange

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

sort: votes


text:
NRF51822 ± Arduino Uno / ATmegaXXX?
Hello I want to make a simple home automation project and I'd like to use an arduino uno for prototyping and later a atmega for deployment. I need some sort of a mesh communication method. I was thinking about the NRF51822 chip but I can't find any arduino libraries for it.

NRF51822 has a MCU. you don't need to add ATmega

you want to use Bluetooth for home automation?

Oh, weird it's advertised as a BLE module. And yeah

You can use the NRF51822 as module with AT firmware attached to Arduino. Then you need only the AT commands reference and some examples how to send AT commands and parse the response.
Or you can use the 32-bit ARM cortex-m0 micro-controller inside NRF51822 with Arduino nrf5 package. It requires a programmer/debugger hardware for sketch upload.

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


text:
32u4 using internal clock on custom PCB - loading sketch
I have a custom PCB with a 32u4 running fine with an 8MHz external oscillator.  I burned the bootloader and loaded my sketch with an UNO using Arduino as ISP.
I have no USB on my PCB nor do I need precise timing, so I wanted to see if I could simplify things by removing the external oscillator and caps.
Reading the 32u4 datasheet it states "The device is shipped with Low Power Crystal Oscillator (8.0 - 16MHz) enabled and with the fuse CKDIV8 programmed".
With that, can I simply hook my PCB (assuming a factory fresh 32u4) via ISP to the UNO as before and in IDE just use Sketch > Upload Using Programmer?    Basically not burning any bootloader at all.
Also, in IDE I have been choosing the Sparkfun ProMicro 3.3v, 8MHz board.  Can I still use that selection?

Yes you can reprogram your 32U4 chips via the ISP, they do not have to be fresh chip. If you set your Fuses to -U lfuse:w:0xE2:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m using AVRDUDE you will have an 8mhz internal RC oscillator set and you do not have to have the external crystal.
You can play with these settings at http://www.engbedded.com/fusecalc/.
I recommend learning the command line AVRDUDE commands this way you have more control over what you are doing to your chip.
I use this all the time, and if you need to do more than one quickly I typically make a batch file that does the Fuse Burn and hex at the same time.
this is for a attiny167 but you get the idea:
.\avrdude\avrdude -C".\avrdude\avrdude.conf" -v -pattiny167 -cstk500v2 -PCOM3 -Ulfuse:w:0xE2:m -Uhfuse:w:0xDF:m -Uefuse:w:0xFF:m  -Uflash:w:1060X01-001.hex:i

I understand that I can set the fuses using AVRDUDE.  My question is: since the datasheet says the 32u4 comes from the factory with the internal oscillator fuse already set, do I need to do anything additional (i.e. set other fuses) before being able to upload my code with SPI?

I have always programmed my fuses then loaded the bootloader hex. then you can use the USB like any pro micro.

@da40flyer also, the single fuse setting of the High, Low, and Extended fuses are all the fuses you have to set, It configures the entire chip with things that need to be done at power on. After that the only thing you need is your program code or your bootloader on the chip.

have you ever tried setting the fuses with Avrdude on a factory fresh chip?  I could not get the chip to be recognized by avrdude.  I ended up having to put an external clock on the XTAL1 pin in order for avrdude to recognize it... and then I could set the fuses.  Thoughts on this?

I believe I discovered why....  I purchased the 32u4 chips.  While you can set the fuses for the internal clock to be used, it does require an external clock in order to program the first time.  I need to use the 32u4rc which is set from the factory to use the internal clock and can be programmed directly.

actually it doesn't require an external clock you have to tell AVRdude to use a very slow clock like 1024 because without any setting the chip defaults to the 32khz RC clock.

I just received some 32u4RC chips and confirmed:
If you are building a custom PC and want to use the 32u4 chip and use the chip's internal clock for your project, simply purchase the 32u4RC version of the chip.  Your sketch can be loaded onto the chip via SPI without the need to set any fuses with avrdude.


text:
Arduino IDE Board Selection for 32u4 on custom PCB
I am using a 32u4 on a custom PCB: 3.3v, 8MHz.
Are there any operational differences between using the Sparkfun ProMicro selection versus the Adafruit ItsyBitsy selection in IDE, since they are both for the 32u4?

Are they both 3.3V, 8 MHz? Or are they 5V, 16 MHz?  Are you trying to select one to bootload your part with?

Yes, both 3.3v, 8MHz.  I have already bootloaded my PCB using the ProMicro selection and it works fine.  I am simply wondering if there is any difference in how the 32u4 would operate if I were to use the ItsyBitsy selection in IDE instead.

There should not be any difference, However you would need to load the ItsyBitsy bootloader instead of the ProMicro Bootloader. Personally, I use the Pro Micro Bootloader on my 32u4 Boards.
The only difference would be in the size of each bootloader, one may be smaller and give you more actual codespace. Other than that there should be no performance difference because your code runs independently of the bootloader.


text:
Arduino Swissflow Meter
We've hooked up a Swissflow sf800 flow meter to our Arudino Uno. The system works, our interrupt callback is triggered and as water flows through the metre, it counts up. The issue is, that the pulse rate is supposed to be 5600/L and we get exactly double that, so we get 5600 per 500ml.
The code is:
if(millis() - lastTime >= 1000)
{
  noInterrupts();
  totalCount = pulseCount;
  lastTime = millis();
  interrupts();

  if (totalCount >= 5600)
  {
    // Here we have 500ml of water, not the expected litre....?
  }
}

void InterruptCallback()
{
  ++pulseCount;
}

For sake of brevity, I've left out variable declarations and globals etc but the code is working as "expected". Is the pulse count not correctly counted in the interrupt callback? We're both fairly new to this, but it seems to be the way people have implemented it in other examples. If it helps, the interrupt is set to trigger on RISING.
Link to the flow meter and spec:
http://www.swissflow.com/sf800.html
http://www.hemomatik.se/PDF/Datasheet_SF-800-3-8_2012_h.pdf
Interrupt code:
attachInterrupt(digitalPinToInterrupt(2), InterruptCallback, RISING);

The interrupt is being triggered and the count increases.

Without seeing the specs of your flow meter it's hard to answer.

And the initialization of the interrupt.


text:
Send file post request from the ESP32
Is it impossible to send a file post request from the ESP32 using the SPIFFS file system? ESP32 freezes while sending.
Code example:
File file = SPIFFS.open("/Images/test.bmp", FILE_READ);

String start_request = ""; String end_request = "";
start_request = start_request +
                "\n--AaB03x\n" +
                "Content-Disposition: form-data; name=\"userfile\"; filename=\"CAM.bmp\"\n" +
                "Content-Transfer-Encoding: binary\n\n";
end_request = end_request + "\n--AaB03x--\n";
uint16_t full_length;
full_length = start_request.length() + file.size() + end_request.length();

WiFiClient client;
if (!client.connect("server_name", 80)) {
  Serial.println("Connected FILED!");
  return;
}

Serial.println("Connected ok!");
client.println("POST /Home/Index HTTP/1.1");
client.println("Host: example.com");
client.println("User-Agent: ESP32");
client.println("Content-Type: multipart/form-data; boundary=AaB03x");
client.print("Content-Length: "); client.println(full_length);
client.print(start_request);

while (file.available()){
  client.write(file.read());
}

Serial.println(">>><<<");
client.println(end_request);

HTTP requires an empty line after the headers. add an empty line with client.println() before client.print(start_request);

One can send a POST request with data fields appended with binary data as shown in the code below. The presented code was made to make a POST request to a Dataverse repository, however, can be easily adapted to any other POST request. Finally, the code below is optimized for Tensilica's Xtensa LX6/7 microprocessors, vis-a-vis ESP32.
The full code can be found here:
https://github.com/aeonSolutions/openScienceResearch-Smart-DAQ-Device-able-to-Upload-Live-Experimental-Sensor-Data-to-a-Data-Repo
// *********************************************************
//            Upload Dataset to Harvard's Dataverse
// *********************************************************
void UploadToDataverse() {
  //Check WiFi connection status
  if(WiFi.status() != WL_CONNECTED){
    mserial.printStrln("WiFi Disconnected");
    if (connect2WIFInetowrk()){
      UploadToDataverse();
    }
  }
  // Start sending dataset file
  File datasetFile = FFat.open("/"+EXPERIMENTAL_DATA_FILENAME, FILE_READ);
  if (!datasetFile){
    mserial.printStrln("Dataset file not found");
    return;
  }

  String boundary = "7MA4YWxkTrZu0gW";
  String contentType = "text/csv";
  // DATASET_REPOSITORY_URL = "/api/files/:persistentId/replace?persistentId=" +PERSISTENT_ID;
  DATASET_REPOSITORY_URL =  "/api/datasets/:persistentId/add?persistentId="+PERSISTENT_ID;

  String datasetFileName = datasetFile.name();
  String datasetFileSize = String(datasetFile.size());
  mserial.printStrln("Dataset File Details:");
  mserial.printStrln("Filename:" + datasetFileName);
  mserial.printStrln("size (bytes): "+ datasetFileSize);
  mserial.printStrln("");

  WiFiClientSecure client;

  int str_len = SERVER_URL.length() + 1; // Length (with one extra character for the null terminator)
  char SERVER_URL_char [str_len];    // Prepare the character array (the buffer)
  SERVER_URL.toCharArray(SERVER_URL_char, str_len);    // Copy it over

  client.stop();
  client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);
  if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
      mserial.printStrln("Cloud server URL connection FAILED!");
      mserial.printStrln(SERVER_URL_char);
      int server_status = client.connected();
      mserial.printStrln("Server status code: " + String(server_status));
      return;
  }
  mserial.printStrln("Connected to the dataverse of Harvard University");
  mserial.printStrln("");
  // We now create a URI for the request
  mserial.printStr("Requesting URL: ");
    mserial.printStrln(DATASET_REPOSITORY_URL);

  // Make a HTTP request and add HTTP headers
  // post header
  String postHeader = "POST " + DATASET_REPOSITORY_URL + " HTTP/1.1\r\n";
  postHeader += "Host: " + SERVER_URL + ":" + String(SERVER_PORT) + "\r\n";
  postHeader += "X-Dataverse-key: " + API_TOKEN + "\r\n";
  postHeader += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n";
  postHeader += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
  postHeader += "Accept-Encoding: gzip,deflate\r\n";
  postHeader += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
  postHeader += "User-Agent: AeonLabs LDAD Smart DAQ device\r\n";
  postHeader += "Keep-Alive: 300\r\n";
  postHeader += "Connection: keep-alive\r\n";
  postHeader += "Accept-Language: en-us\r\n";

  // jsonData header
  String jsonData = "{\"description\":\"LIVE Experimental data upload from LDAD Smart 12bit DAQ \",\"categories\":[\"Data\"], \"restrict\":\"false\", \"tabIngest\":\"false\"}";
  String jsonDataHeader = "--" + boundary + "\r\n";
  jsonDataHeader += "Content-Disposition: form-data; name=\"jsonData\"\r\n\r\n";
  jsonDataHeader += jsonData+"\r\n";

  // dataset header
  String datasetHead = "--" + boundary + "\r\n";
  datasetHead += "Content-Disposition: form-data; name=\"file\"; filename=\"" + datasetFileName + "\"\r\n";
  datasetHead += "Content-Type: " + contentType + "\r\n\r\n";

  // request tail
  String tail = "\r\n--" + boundary + "--\r\n\r\n";

  // content length
  int contentLength = jsonDataHeader.length() + datasetHead.length() + datasetFile.size() + tail.length();
  postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";

  // send post header
  int postHeader_len=postHeader.length() + 1;
  char charBuf0[postHeader_len];
  postHeader.toCharArray(charBuf0, postHeader_len);
  client.print(charBuf0);
  mserial.printStr(charBuf0);

  // send key header
  char charBufKey[jsonDataHeader.length() + 1];
  jsonDataHeader.toCharArray(charBufKey, jsonDataHeader.length() + 1);
  client.print(charBufKey);
  mserial.printStr(charBufKey);

  // send request buffer
  char charBuf1[datasetHead.length() + 1];
  datasetHead.toCharArray(charBuf1, datasetHead.length() + 1);
  client.print(charBuf1);
  mserial.printStr(charBuf1);

  // create buffer
  const int bufSize = 2048;
  byte clientBuf[bufSize];
  int clientCount = 0;

  while (datasetFile.available()) {
    clientBuf[clientCount] = datasetFile.read();
    clientCount++;
    if (clientCount > (bufSize - 1)) {
        client.write((const uint8_t *)clientBuf, bufSize);
        clientCount = 0;
    }
  }

  datasetFile.close();

  if (clientCount > 0) {
      client.write((const uint8_t *)clientBuf, clientCount);
      mserial.printStrln("[binary data]");
  }

  // send tail
  char charBuf3[tail.length() + 1];
    tail.toCharArray(charBuf3, tail.length() + 1);
    client.print(charBuf3);
  mserial.printStr(charBuf3);

  // Read all the lines of the reply from server and print them to mserial
    mserial.printStrln("");
    mserial.printStrln("Response Headers:");
  String responseHeaders = "";

  while (client.connected()) {
    // mserial.printStrln("while client connected");
    responseHeaders = client.readStringUntil('\n');
    mserial.printStrln(responseHeaders);
    if (responseHeaders == "\r") {
      mserial.printStrln("======   end of headers ======");
      break;
    }
  }

  String responseContent = client.readStringUntil('\n');
  mserial.printStrln("Harvard University's Dataverse reply was:");
  mserial.printStrln("==========");
  mserial.printStrln(responseContent);
  mserial.printStrln("==========");
  mserial.printStrln("closing connection");
  client.stop();
  }


text:
Faster way to parse a HTTP response in Arduino
I send a GET http request to a server and get following data back.
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 16 Nov 2018 16:30:05 GMT
Connection: close

35
{
  "uuid" : "13b29524-7e12-48fb-bbf9-4396aefff45d"
}
0

with the following code I get the header info and the body.
void parseResponse() {
  boolean headerEnd = false;
  byte lineCount = 0;
  String line;
  char endOfLine[] = "\r\n";
  while (1) {
    if (client.available()) {
      char inChar = client.read();
      if (!headerEnd && line.endsWith(endOfLine)) {
        // Just save the first then headers
        if (lineCount == 10) {
          headerEnd = true;
        } else {
          headers[lineCount] = line;
          line = "";
          lineCount++;
        }
      }

      if (line.endsWith("close")) {
        line = "";
        headerEnd = true;
      }

      if (headerEnd && line.endsWith("}")) {
        line.toCharArray(response, sizeof(response));
        client.stop();
        break;
      }

      line += inChar;
    }
  }
}

this thakes 60 - 70ms to parse. Is there a faster way to parse? I think that's slow, for so little text, in the world of AVRs.

That doesn't look like C...

The Arduino language is not C, but C++ with some non-standard extensions, such as boolean and byte for bool and unsigned char respectively. Please retag your question.

char lastChar = ""; should be char lastChar = '';. "" is a string, not a char.

But the lastChar variable is never used for anything, why do you keep assigning it?

@Barmer . Right, I have removed it.

there are nice functions inherited from Stream class
int parseResponse(char uuid[], int size) {
  if (!client.find("HTTP/1.1")) // skip HTTP/1.1
    return -1;
  int st = client.parseInt(); // parse status code
  int l = -1;
  if (st == 200 && client.find("\"uuid\" : \"")) {
    int l = client.readBytesUntil('"', uuid, size);
    uuid[l] = 0; // terminate the C string
  }
  return l;
}

Thanks for the note "client.readBytesUntil". I did not find that under Arduino Client.
https://www.arduino.cc/en/Reference/ClientConstructor but there, https://www.arduino.cc/en/Reference/StreamReadBytesUntil. :S. It's now 20ms faster!


text:
Arduino Leonardo keyboard.print keeps printing equal sign
I am currently working on a DIY controller for Train Sim World. I am relatively new to the Arduino and the C programming language. My code is structured to look for button presses or PS2 joystick inputs and print a specific character for each button. I have also included a kill switch on pin 3. However when I run the code and open Notepad to see the results, the Arduino keeps printing the = character even if pin 3 is not pulled low. After I pull pin 3 low and press a button, there is a delay of about two seconds during which the = character keeps being printed over and over again, and after these 2 seconds elapse the Arduino prints the character attributed to the button several times before returning to printing = over and over again.
What can I do to fix this?
#include <Keyboard.h>

void setup() {
    pinMode(0, INPUT_PULLUP);
    pinMode(1, INPUT_PULLUP);
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);
    pinMode(6, INPUT_PULLUP);
    pinMode(7, INPUT_PULLUP);
    pinMode(8, INPUT_PULLUP);
    pinMode(9, INPUT_PULLUP);
    pinMode(10, INPUT_PULLUP);
    pinMode(11, INPUT_PULLUP);
    pinMode(12, INPUT_PULLUP);
    pinMode(13, INPUT_PULLUP);
}
bool pantograph = 0;
void loop() {
    while (digitalRead(3) == LOW) {
        Keyboard.write("M");
        if (digitalRead(1) == LOW) {
            Keyboard.write("W");
        } else if (digitalRead(2) == LOW) {
            Keyboard.write("S");
        } else if (digitalRead(0) == LOW) {
            Keyboard.write("Q");
        } else if (digitalRead(5) == LOW) {
            Keyboard.write("Y");
        } else if (digitalRead(6) == LOW) {
            Keyboard.write("T");
        } else if (digitalRead(7) == LOW) {
            Keyboard.write("G");
        } else if (digitalRead(8) == LOW) {
            Keyboard.write("K");
        } else if (digitalRead(9) == LOW) {
            Keyboard.write("Z");
        } else if (digitalRead(10) == LOW) {
            if (pantograph == 0) {
                Keyboard.write("P");
            } else {
                Keyboard.write("O");
            }
        } else if (digitalRead(11) == LOW) {
            Keyboard.write(9);
        } else if (digitalRead(12) == LOW) {
            Keyboard.write("N");
        } else if (digitalRead(13) == LOW) {
            Keyboard.write(32);
        } else if (analogRead(A0) > 700) {
            Keyboard.write(93);
        } else if (analogRead(A0) < 200) {
            Keyboard.write(91);
        } else if (analogRead(A1) > 700) {
            Keyboard.print(39);
        } else if (analogRead(A1) < 200) {
            Keyboard.print(59);
        } else if (analogRead(A2) > 700) {
            Keyboard.print("A");
        } else if (analogRead(A2) < 200) {
            Keyboard.print("D");
        }
    }
    delay(1000);
}

I'm not sure if it'd cause it but I think you should have a Keyboard.begin() at the end of the setup function.

@PeterJ unfortunately it didn't work. Same thing happens as I've described before. However by moving the delay inside while the program slows down to printing once every second, as expected, and the buttons' associated characters only print once, but the program still prints the "=" over and over again

did you read my answer?

The method write with one parameter takes char not string. Use write('W'), not write("W");


text:
Teensy freezing when reading ir sensor
I have a teensy that controls a motor and reads from a ir sensor, GP2Y0E02b. The issue i run into is that at random times the teensy seems to freeze, the main code stops printing but the interrupt routine continue to work. It seems to be that when reading the ir sensor it causes the teensy to freeze. The code below is what I'm using to read the ir values.
#include <i2c_t3.h>
//#include <WSWire.h>
#include <Arduino.h>
uint16_t ReadFirstSensor();
uint16_t ReadSecondSensor();

#define ADDRESS       0x80 >> 1  // Arduino uses 7 bit addressing so we shift
address right one bit
#define DISTANCE_REG  0x5E
#define SHIFT         0x35

class GP2Y0E02B {
public:
    int MaxDistance;
   int MinDistance = 27;
float distance = 0;
byte high, low = 0;
float shift = 0;
bool badSensor = false;

GP2Y0E02B(){
  //Serial.println("Sensors Initialized");
};

float GetRawDistance()
{
    //if (!badSensor){
      float FirstDistance = ReadFirstSensor();
      return FirstDistance;
    //}
    //else
    //  return 22000;
}

void StartSensors()
{
    //Serial.println("StartSensors Called");
    Wire.begin(400000);
    delay(50);
    //Serial.println("Wire.begin() has been called");
    Wire.beginTransmission(ADDRESS);
    //Serial.println ("beginTrans done");
    Wire.write(SHIFT);
    //Serial.println ("Shiftwrite done");
    int stat = Wire.endTransmission();
    //Serial.print("endTrans done stat: ");Serial.println(stat);

    int i = 0;
    while (Wire.available() == 0)
    {
        //Serial.println ("Im trying SPI");
        i++;
        delay(5);
        if (i>30) break;
    }
    if (i<30)
    {
        shift = Wire.read();
        Wire.requestFrom(ADDRESS, 1);
        MaxDistance = GetRawDistance();
        badSensor = false;
    }
    else
    {
        //Serial.println ("couldnt initialize the sensors");
        badSensor = true;
    }
 }

 uint16_t ReadFirstSensor()
 {
    static int LastDist = 0;
    //Serial.println ("Read First sensor called");
    Wire.beginTransmission(ADDRESS);
    Wire.write(DISTANCE_REG);
    //Serial.println ("DoneWireWrite");
    int SPIhealth = Wire.endTransmission();
    //Serial.print ("DoneWireEndTransmit: ");Serial.println (SPIhealth);
    if (SPIhealth == 0) Wire.requestFrom(ADDRESS, 2);
    else return LastDist;
    //Serial.println ("DoneWireREquest");

    int EmergBreak = 0;
    while(Wire.available() < 2)
    {
        //Serial.println ("Trying to get sensor reading");
        EmergBreak++;
        delay(1);
        if (EmergBreak > 20) return LastDist;
    }
    if (EmergBreak > 20);//Serial.println ("Couldnt Read Sensor");
    //else Serial.println ("Done Reading Sensor");

    high = Wire.read();
    low = Wire.read();

    uint16_t rawDistance;
    rawDistance = (high * 16 + low)/16/(float)pow(2,shift); // Calculate the range in CM
    //Serial.print("rawDistance: ");Serial.println(rawDistance);
    rawDistance = (uint16_t) low ;
    rawDistance += (uint16_t)high << 8;
    LastDist = rawDistance;

    return rawDistance;
  }

};

I2C code would typically get "stuck" if the peripheral fails to respond and you don't have a reasonable timeout configured.  You should probably figure out how to configure a timeout for the I2C operation.  And maybe see if you can debug the conditions under which it occurs.

ill try that out

I don't know where to start. The StartSensors function calls Wire.available without a Wire.requestfrom and it will never get to the section with Wire.requestFrom and the variable shift will stay 0. That unused section does a Wire.read first which might return -1 and puts that into the float shift, and after that the Wire.requestFrom is called but the requested data is never read. The function ReadFirstSensor has a while statement without meaning and a calculation for rawDistance has bytes, integers, and float. The I2C bus is not a SPI bus, but there are variables with SPI in their name.


text:
How to transmit Float sensor values via NRF24L01 module?
I'm trying to figure out a way to transmit four sensor values: Voltage, Current, Power and consumption but I'm unable to do that.
Yet, my syntax is correct... what am I missing?
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <RF24.h>

#define ACS712 A0

int lastData = 0;
int dataSum = 0;
int Count = 0;

float Voltage;
float Current;
float Power;
float kWh;
float Consumption;
String Data;

float vpc = 4.882813; // approx. voltage per count

RF24 radio(9, 10); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

void setup() {
  Serial.begin(115200);
  pinMode(13, OUTPUT);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

void loop() {

  radio.stopListening();

  if (millis() > lastData + 1) {
    dataSum += sq(analogRead(ACS712) - 512);
    Count++;

    lastData = millis();
  }
  // If statement to make calculations.
  if (Count == 1000) {

    // To get the RMS of the data.
    float mean = dataSum / Count;
    float value = sqrt(mean);

    // To get the Voltage (in volts) consumed.
    float Voltage = value * vpc;

    // To get the Current (in amps) consumed.
    float Current = Voltage / 66;

    // To get the Power (in watts) consumed.
    float Power = Current * 240;

    float kWh = Power / 1000;
    float Consumption = kWh;

    dataSum = 0;
    Count = 0;

    Data += F("\nVoltage: ");
    Data += String(Voltage, 3);
    Data += F("\nCurrent: ");
    Data += String(Current, 3);
    Data += F("\nPower: ");
    Data += String(Power, 3);
    Data += F("\nConsumption: ");
    Data += String(Consumption, 3);
    //Serial.println(Data);

    radio.write(&Data, sizeof(Data));
    if (radio.write(&Data, sizeof(Data)) && true) {
      Serial.println("Sent!");
    } else {
      Serial.println("Failed!");
    };
    delay(10);
  }
}

I'm unable to do that is meaningless ..... clear description of observed results is meaningful

Hint: What is the payload max size? And what would be transmitted for radio.write(&Data, sizeof(Data)), the String object or its value?

Have you tried sending command values instead of string values? For example, send 0x01 for Voltage, 0x02 for Current etc. That way you don't send Strings (which in embedded programming you really shouldn't be using!!) and will reduce the data transferred.

Why not just send the voltage, and do all those calculations on the receiver, as there are just basic division/multiplication with set constants. Also, first try a more basic program to get the radio working. Were you able to run one of the example sketches, and get the radios working?

Simple float transmission:
For TX use
float payload = 0.12345;
radio.write(&payload, sizeof(payload));

For RX use
float payload = 0;
radio.read(&payload, sizeof(payload));

here he wants to transmit the complete string, not a single float value your answer will be applicable if it is a single float but here the question deals with how he can transmit a complete string.


text:
Maze solving robot turning failure due to sensor distance to the corner increasing during the turn
At my school we have a project where we have to make a robot that can solve a 3D-maze using an arduino controlled robot that uses ultrasonic sensors to determine how to turn. The robot may not be pre-programmed and must work on all simple mazes with 90d turns.
I have figured out most of the code I think, however my problem is that when the robot needs to turn. Since how much and which direction the robot should turn is determined by distance sensors, the distance to the corners increase, making it longer than what is required to turn. This makes the robot want to turn back into the corner and then it gets stuck in a loop of turning in and out of the corner (see image attached).
Note: we don't want to program a 90d turn as it could mess up later and we believe it better to try make how long the robot should turn be determined by the value of the different sensors.
The robot is made up of three ultrasonic sensors, front, right, and left. The robot has tracks which lets it turn on the spot. The arduino is an arduino mega, so it is fast at updating and measuring values (unless the time needed for measuring the distance is long).
Files:

Pictures describing the turning problem:

Images of the robot:

If any other information is needed that is left out, I will try to obtain it (such as images, dimensions, exact component names, etc.)
The entire code:
enum robState {
  robInit,
  robInitForward,
  robInitRotL,
  robInitRotR,
  robStop,
  //robWaitCrystals,
  robInitBack,
  robReset,
  robFindWay
};

struct LFR {
  int L;
  int F;
  int R;
};

struct robMotor {
  byte pwm;
  byte dir_1;
  byte dir_2;
};

robState robStatus;
//const int robTurnSpeed = 255;
robMotor motorL = {2, 4, 3};
robMotor motorR = {5, 6, 7};

int dirInt = 1;
LFR echoPin = {12, 11, 13};
LFR trigPin = {24, 26, 22};
LFR distance;
const int robStartStopPin;

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

  //init pinModes
  initPins();

  Serial.begin(9600);
  robStatus = robInit;
}

void loop() {
  int disWall = 12;
  // put your main code here, to run repeatedly:
  distance.L = distanceUpdater(trigPin.L, echoPin.L);
  distance.F = distanceUpdater(trigPin.F, echoPin.F);
  distance.R = distanceUpdater(trigPin.R, echoPin.R);
  Serial.print("/n distance.L= ");
  Serial.println(distance.L);
  Serial.print("/n distance.F= ");
  Serial.println(distance.F);
  Serial.print("/n distance.R= ");
  Serial.println(distance.R);
  //delayMicroseconds(50);

  switch (robStatus) {

    case robInit:
      //init motors and shit
      motor(0, 0);
      motor(1, 0);
      //wait for start/stop
      //while (digitalRead(robStartStopPin) == LOW);
      Serial.print("/n robInit");
      robStatus = robFindWay;
      break;

    case robInitForward:
      motor(0, 1);
      motor(1, 1);
      Serial.print("/n robInitForward");
      robStatus = robFindWay;
      break;

    case robFindWay:

      Serial.print("/n robFindWay");
      if (distance.R > disWall) {
        //if open to right, turn right.
        robStatus = robInitRotR;
      }
      else if ((distance.R < disWall) && (distance.F > disWall)) {
        //go forward if you can't go right
        robStatus = robInitForward;
      }

      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L > disWall)) {
        //if nothing else works, turn left.
        robStatus = robInitRotL;
      }
      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L < disWall)) {
        //found the end, must turn. turns left.
        robStatus = robInitRotL;
      }
      else {
        Serial.print("shit somethings wrong with path finding");
      }
      break;

    case robInitRotL:
      Serial.print("robInitRotL");
      //forward direction of motorR
      motor(1, 1);
      //reverse direction of motorL
      motor(0, -1);
      //send the correct motor speed*/
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robInitRotR:
      Serial.print("robInitRotR");
      //reverse direction of motorR
      motor(1, -1);
      //forward direction of motorL
      motor(0, 1);
      //send right motor speed
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robStop:
      motor(0, 0);
      motor(1, 0);
      //while (digitalRead(robStartStopPin) == LOW);
      robStatus = robInit;
      break;

    case robInitBack:
      //reverse both motors
      motor(0, -1);
      motor(1, -1);
      break;
  }

}

void initPins() {
  //init motors
  pinMode(motorL.pwm, OUTPUT);
  pinMode(motorL.dir_1, OUTPUT);
  pinMode(motorL.dir_2, OUTPUT);

  pinMode(motorR.pwm, OUTPUT);
  pinMode(motorR.dir_1, OUTPUT);
  pinMode(motorR.dir_2, OUTPUT);
  //init sensors
  pinMode(trigPin.L, OUTPUT);
  pinMode(trigPin.F, OUTPUT);
  pinMode(trigPin.R, OUTPUT);

  pinMode(echoPin.L, INPUT);
  pinMode(echoPin.F, INPUT);
  pinMode(echoPin.R, INPUT);
  //init button
  pinMode(robStartStopPin, INPUT);
  //init power sources
  /*pinMode(VCCPin1, OUTPUT);
  digitalWrite(VCCPin1, HIGH);
  pinMode(GNDPin1, OUTPUT);
  digitalWrite(GNDPin1, LOW);*/
}

void motor(int side, int action) {
  //side 0=L 1=R
  //action -1=reverse 0=still 1=forward
  int normalSpeed = 255;
  if ((side == 0) && (action == -1)) {
    //reverse left
    digitalWrite(motorL.dir_1, LOW);
    digitalWrite(motorL.dir_2, HIGH);
    analogWrite(motorL.pwm, normalSpeed);
  }
  else if ((side == 0) && (action == 0)) {
    //still left
    digitalWrite(motorL.dir_1, HIGH);
    digitalWrite(motorL.dir_2, LOW);
    analogWrite(motorL.pwm, 0);
  }
  else if ((side == 0) && (action == 1)) {
    //forward left
    digitalWrite(motorL.dir_1, HIGH);
    digitalWrite(motorL.dir_2, LOW);
    analogWrite(motorL.pwm, normalSpeed);
  }
  else if ((side == 1) && (action == -1)) {
    //reverse right
    digitalWrite(motorR.dir_1, LOW);
    digitalWrite(motorR.dir_2, HIGH);
    analogWrite(motorR.pwm, normalSpeed);
  }
  else if ((side == 1) && (action == 0)) {
    //still right
    digitalWrite(motorR.dir_1, HIGH);
    digitalWrite(motorR.dir_2, LOW);
    analogWrite(motorR.pwm, 0);
  }
  else if ((side == 1) && (action == 1)) {
    //forward right
    digitalWrite(motorR.dir_1, HIGH);
    digitalWrite(motorR.dir_2, LOW);
    analogWrite(motorR.pwm, normalSpeed);
  }
  else {
    Serial.print("monkaS wrong motor inputs");
  }
}

int distanceUpdater(int trigPin, int echoPin) {
  long duration;
  int distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration * 0.034 / 2);
  return distance;
}

The pathfinding and turning:
switch (robStatus) {

    case robInit:
      //init motors and shit
      motor(0, 0);
      motor(1, 0);
      //wait for start/stop
      //while (digitalRead(robStartStopPin) == LOW);
      Serial.print("/n robInit");
      robStatus = robFindWay;
      break;

    case robInitForward:
      motor(0, 1);
      motor(1, 1);
      Serial.print("/n robInitForward");
      robStatus = robFindWay;
      break;

    case robFindWay:

      Serial.print("/n robFindWay");
      if (distance.R > disWall) {
        //if open to right, turn right.
        robStatus = robInitRotR;
      }
      else if ((distance.R < disWall) && (distance.F > disWall)) {
        //go forward if you can't go right
        robStatus = robInitForward;
      }

      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L > disWall)) {
        //if nothing else works, turn left.
        robStatus = robInitRotL;
      }
      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L < disWall)) {
        //found the end, must turn. turns left.
        robStatus = robInitRotL;
      }
      else {
        Serial.print("shit somethings wrong with path finding");
      }
      break;

    case robInitRotL:
      Serial.print("robInitRotL");
      //forward direction of motorR
      motor(1, 1);
      //reverse direction of motorL
      motor(0, -1);
      //send the correct motor speed*/
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robInitRotR:
      Serial.print("robInitRotR");
      //reverse direction of motorR
      motor(1, -1);
      //forward direction of motorL
      motor(0, 1);
      //send right motor speed
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robStop:
      motor(0, 0);
      motor(1, 0);
      //while (digitalRead(robStartStopPin) == LOW);
      robStatus = robInit;
      break;

    case robInitBack:
      //reverse both motors
      motor(0, -1);
      motor(1, -1);
      break;
  }

Your main loop (loop()) is powering through the whole code continuously. It wouldn't be a bad idea to put some "breaks" between each sensor scan cycle. For example:
long timerCounter = 0;

void setup()
{
    // Do your setup here

    timerCounter = millis();
}

void loop()
{
    // Only do some code every 1 second (1000ms)
    if (millis() - timerCounter >= 1000)
    {
        ScanSensor1();
        ScanSensor2();
        ScanSensor3();

        robState state = DetermineStateFromSensorReadings();

        DoActionForState(state);
    }
}

What this does is break the cycle down to 1Hz (change as you wish). When you are using ultrasonics (as per your images), it's always a good idea to reduce the intervals between each reading, as it allows residual noise to quieten down. Imagine the beeping sound from the sonar on a submarine.
You've got the right idea by using a state machine in your code. Each cycle can determine which state it should be in after reading the sensor data. Good job on that!
Just some additional information about ultrasonics regarding your project:

Sonar has an emission angle of 30 degrees (not a straight line!). Imagine a code pointing out with an angle of 30 degrees. This means anything inside this range could be picked up by the sensor. Looking at your turning problem image 2, I'd expect a lot of erroneous data from that sensor pointing towards the corner.
Multiple sensors working at the same frequency (40kHz?) may interfere with each other.

The problem you are seeing is mainly caused by the fact that you are checking the walls around you as you are turning. I would suggest you use either the forward facing sensor or the opposite sensor to that in turning problem image 2 to significantly reduce erroneous data.
If your budget (and time) allows, you may benefit from using a cheap Lidar (like this one for example) to more accurately determine your surrounding. Lidar doesn't have an emission angle, which means that it's measurement point is in a straight line from the source.

Autonomous robots are a lot of fun (and hard!)  Right now your robot is doing exactly what you told it to do - follow the wall.  One way or another you are going to have to 'program in a 90-deg turn'.  The hard way to do this is to model the corner, in terms of the expected distance profile vs time, and constantly adjust the robot's offset target to smoothly navigate the turn.  The easy way would be to let the robot recognize that a turn is required, execute the turn, and then reassess the situation.  FMI, see the 'robots' category at  https://www.fpaynter.com/

You need two states. Making a turn and not making a turn.
Once you start making a turn, ignore the side sensors, and continue turning until the front sensor distance has reached its peak.


text:
Debug-logging without using Serial.print and without WiFi
In order to transmit text from the Arduino board to the HC-05 Bluetooth module, I have use Serial.print. However, I don't see a way to debug the code without using Serial.print to test the other features of the software. Is there another way to transmit text from the Arduino to the computer, and from the Arduino to the HC-05, simultaneously (and without WiFi)?

Yes. Plenty. You could add WiFi to it. You could use an external UART adaptor and SoftwareSerial. You could add Ethernet to it. There's many ways.

WiFi isn't available in this case. I'll edit the question.

The simplest is probably to just use SoftwareSerial and an external USB to UART adaptor. Or just move the HC-05 to other pins and use SoftwareSerial with it (as long as you're no faster than around 9600 baud).

Yes, what version of Arduino are you using?

For Arduino Mega, you can use Serial.println for writing debug data and Serial1.println for communication with HC-05. (See Example: MultiSerial Example)
For other Arduino boards, you can use Serial.println for writing debug data and SoftwareSerial library for communication with HC-05. (See Example: SofwareSerial)

I'm using an Arduino Uno.

Ok, connect RXD pin and TXD pin of HC-05 to pin 10 and 11 of Arduino Uno and follow SoftwareSerial example. https://www.arduino.cc/en/Tutorial/SoftwareSerialExample


text:
Why is this failing after 3 iterations?
I simply cannot figure this out, why is this failing after 3 iterations? Other than that, what better way is there to do this? Thanks!
#define rotary_encoder_topic  "/rotary/encoder"
#define remote_button_topic  "/remote/button"
#define remote_2x_toggle_topic  "/remote/2xtoggle"
#define rotary_button_topic  "/rotary/button";
char* devices[] = { "ledrpi", "lamprpi", "mediaroom" };
int currentDevice = 0;

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

void incrementCurrentDevice() {
  currentDevice++;
  if (currentDevice >= sizeof(devices)) {
    currentDevice = 0;
  }
 Serial.println(concatenateChars("Switched device to: ", devices[currentDevice]));
}

char* concatenateChars(const char* one, const char* two) {
  char result[150] = "";
  strcat(result, one);
  strcat(result, two);
  return result;
}

void loop() {
  Serial.println(concatenateChars(devices[currentDevice], remote_2x_toggle_topic));
  incrementCurrentDevice();
  delay(1000);
}

what does failing mean?

As Jaromanda X pointed out in the comments, sizeof(array[0]) (size of first element) will not return the size of the literal strings, but the size of a char pointer.

It doesn't work (whatever that means for you), because sizeof(devices) doesn't return the number of entries in the array, but the size of the array in bytes, e.g. something like (following is wrong: 24 (1 byte per character plus 1 byte with the concluding null character for each string) ) 6 (The size of a char pointer is 2 bytes on most microcontrollers; I'm not sure, if this is the same for Node MCU). So after 3 iterations (which can use the string literals in the array) currentDevice doesn't go back to zero, but counts further. With the access to the array with exceeding index you are accessing memory, that doesn't belong to the array anymore (e.g. random data).
There is no native function, that gives you the length of an array. But it can be calculated with sizeof(array)/sizeof(array[0]), which is the size of the array in bytes divided by the size of one element in bytes. In your case you would have an array size of 6 and an element size of 2, resulting in a calculated element count of 3, which is correct.
Another simple solution, which is easier to understand for beginners, but not as flexible, is to set a constant or define, that contains the size of your array. You can then use it in your code, whenever you need the size, including, when you define the array.

actually wouldn't sizeof(devices) return 3 x sizeof(char *) so, the length of each string is irrelevant. therefore sizeof(array)/sizeof(array[0]) will give 3 in this case, guaranteed

of course, I meant sizeof(devices)/sizeof(devices[0])

@JaromandaX Mhh, I haven't thought of this. But I think, you are right. The size of a pointer is 2 bytes, as I remember. So it will count to 6. Is this the same for a Node MCU? And yes, the division should work either way.

knowing size of the pointer doesn't actually matter :D

It doesn't matter for this case, but I was interested


text:
Seeed CAN Shield - Not receiving extended CAN-Message
I want to receive an extended CAN-Message. I send a extended CAN-Message, but nothing happens. Maybe somebody have an idea what the problem is..
It works with a standard CAN-Message.
Thanks in advance.
// demo: CAN-BUS Shield, send data
// loovee@seeed.cc

#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

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

    while (CAN_OK != CAN.begin(CAN_250KBPS))              // init can bus : baudrate = 250k
    {

        CAN.init_Mask(0,1,0);
        CAN.init_Filt(0,1,0);

        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");
}

unsigned char len = 0;
unsigned char buf[30];

void loop()
{
    CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
    unsigned long canId = CAN.getCanId();
    Serial.println("-----------------------------");
    Serial.print("Get Data from ID: 0x");
    Serial.println(canId, HEX);
    Serial.println("Data content:");
    for(int i = 0; i<len; i++) // print the data
    {
        Serial.print(buf[i]);
        Serial.print("\t");
    }
    Serial.println("-----------------------------");
}

What happens if you remove the filter and the mask?

It change nothing.

Maybe this discussion can help you: https://github.com/Seeed-Studio/CAN_BUS_Shield/issues/39

Unfortunately, I found this discussion, but nothing changed.

How do you send the message? With the same Can-shield on a different Arduino? If yes, can you post code of the sender? I assume you don't have any other device to verify, if the extended frame is actually sent to the bus?

I read a CAN communication from an other device. So I don't have the code of the decide. I only know, that the Baudrate is 250k and it is using extended CAN messages. I want to read with the Arduino Uno the CAN communication.


text:
RN4678 Bluetooth doesn't respond
I am facing very basic level issue with RN4678. I purchased a module from https://www.mikroe.com/rn4678-click
I want to simply communicate with it through serial port.  To do that I connected it to PC by usb to TTL. Whatever I send, I don't get any response from module.  Then parallely I paired it with mobile phone and on successful connection, from  Android app terminal I tried the same and nothing happened.  If I send something from PC, I get it on mobile but reverse doesn't work.    And the main issue is Module doesn't respond at all.   I tried 3modules as well.
Help would be appreciated.

Have you made sure that your USB to TTL is implementing flow control on the UART. An option is to delete the CTS/RST in RN configuration and try two wire UART to eliminate CTS/RTS option


text:
Arduino scrolling text program freeze after some time
I use a 16x2 character lcd to display some text. What I want is first line will stay, but the second line should scroll text.
I wrote a program which works fine but the problem is after some time arduino does not respond. I suspect there might be a bug or memory leak in the code.
The relevant code is like this.
void scrollTextFromRight(int line, char text[])
{
    const char space[16] = "                ";
    char screen[16];
    char * longText;

    longText = malloc(sizeof(char) * (sizeof(text) + 17));

    memset(longText, '\0', sizeof(char) * (sizeof(text) + 17));
    memset(screen, '\0', sizeof(screen));

    for (int i = 0; i < 16; ++i)
    {
        longText[i] = space[i];
    }

    for (int j = 0; j < sizeof(text) + 17; ++j)
    {
        longText[16+j] = text[j];
    }

    for (int i = 0; i < sizeof(text) + 17; ++i)
    {

        lcd.setCursor(0, line);
        strncpy(screen, longText + i, 17 );
        lcd.print(screen);
        delay(350);
    }
}

I call this function from main program like this:
scrollTextFromRight(1, "Scrolling text");

you don't free the memory taken by malloc(). don't malloc() on Uno. even if you would free the memory the small heap gets fragmented fast. you can do the same with a buffer on stack

You malloc but don't free. Of course it's going to leak. Also sizeof(text) doesn't work like that. Instead you can do strlen to get the number of characters in a null-terminated char array.
You can do this without the longText buffer by doing partial copies into screen.
const char space[16] = "                ";
char screen[16];

for (int i = 0; i < sizeof(text) + 17; ++i)
{
    lcd.setCursor(0, line);
    strncpy(screen, space, i); // copy i spaces
    strncpy(screen+i, text, min(17-i, strlen(text))); // copy the rest of the string up to the end whichever is shorter.
    screen[17] = '\0'; // force null termination
    lcd.print(screen);
    delay(350);
}


text:
Image Processing
I have a project I am working on where I need to check the pressure on a gauge using a camera. I am familiar with a little openCV programming using a laptop webcam. However, for this application, I need to use a camera and a micro-controller. The camera needs to take a picture of the pressure gauge and check if it is between certain values. If it is so, the micro-controller sends a true or a false to a PLC. The first thought I had was to use an Arduino because the software is easily available as well as easy to use. However, an Arduino may not have the image processing capability is what I read online. Can someone please suggest a micro-controller suitable for this application. Also, is it possible to send signals to a PLC from the micro-controller?

Not really the right place to post this question - Stackoverflow or RaspberryPi or Arduino sites SO sites would be more appropriate.

What is the distance to the pressure gauge? You could be able to detect the thresholds another way?

If you want to use and Arduino (even if faster chip with more RAM would be better), there is an option: the small camera module Ov7670 is available in two versions. One just take pictures get them and send them immediatly which is a big challenge in terme of time and will certainly not give you enought time to analyse but the "FIFO" version of the Ov7670 has a buffer in which the module store the image.
So you can ask it to "take a photo" and then you have time to get the data.
Of course, it's impossible to retrieve the full picture and you'll have to check it pixel per pixel or maybe line per line.

However, an Arduino may not have the image processing capability is what I read online.

Correct. An 8-bit Arduino cannot store a big enough image and process it.

Can someone please suggest a micro-controller suitable for this application.

One of the 32-bit offerings from Arduino or any of the many third-party board makers (Teensy, chipKIT, STM32, etc) may be up to the job.
Your main concern will be memory (RAM). The more memory you have the bigger the image you can store and process.
The actual processing will probably be simple enough if the colours of the different things are obvious enough - for instance if the pointer is red and the background (in the target area) is black, then if there is red within the target area the pointer is there.

Also, is it possible to send signals to a PLC from the micro-controller?

Probably. That all depends on how the PLC communicates.

I recommend using a Raspberry Pi or perhaps Arduino Yun for this project. They are both Linux computers and will have much more processing power to do image processing.
I'm sure there's a way to send signals into a PLC, but I don't know how PLCs communicate, and you haven't provided any user manuals or data sheets for one, so I can't explain any details at this time.


text:
NRFlite Question
I'm trying to use NRFlite library to facilitate a simple wireless remote incorporating a 3x4 keypad and nRF24L01 modules.  I have it all working well except for one programming puzzle.
All of the example NRFLite receiver sketches that I can find online show the entire main program loop within a while statement:
while (_radio.hasData())
Such as:
void loop() {

while (_radio.hasData())

{

    _radio.readData(&_radioData); // Note how '&' must be placed in front of the variable name.

    String msg = "Radio ";

    msg += _radioData.FromRadioId;

    msg += ", ";

    msg += _radioData.OnTimeMillis;

    msg += " ms, ";

    msg += _radioData.FailedTxCount;

    msg += " Failed TX";

    Serial.println(msg); }}

But my sketch is obviously much more complicated than these examples.  I would like to pass the data received to a variable to use outside of this "while" loop to do a bunch of other stuff not related to the wireless remote.  However, whenever I try to do that, the conditional argument of this "while" function
"(_radio.hasData())"
seems to test as TRUE, and the old data just received is treated again as new data with each pass through the program loop.
How can I pass the data packet outside of the "while (_radio.hasData())" function and get it to subsequently ignore that last data packet received?
Looking at the cpp file, it seems as if perhaps just calling the function "_radio.readData(&_radioData)" is intended to do just that by reseting a "data received flag", which makes sense as a way to accomplish just what I need.  But it doesn't seem to work that way.  Here is that "_radio.readData(&_readData)" function from the .cpp file:
void NRFLite::readData(void *data) {

// Determine length of data in the RX FIFO buffer and read it.

uint8_t dataLength;

spiTransfer(READ_OPERATION, R_RX_PL_WID, &dataLength, 1);

spiTransfer(READ_OPERATION, R_RX_PAYLOAD, data, dataLength);

// Clear data received flag.

uint8_t statusReg = readRegister(STATUS_NRF);

if (statusReg & _BV(RX_DR))

{

    writeRegister(STATUS_NRF, statusReg | _BV(RX_DR));
}
}

I would sure appreciate any suggestions, because otherwise, the NRFlite library seems very efficient for my simple need.

Seems like you need to add your code at the end of the while, not after it. PS If you also need to add some code that isn't packet-data dependent, you might want to change the while to an if

Gerben, thanks for the suggestions.  I previously tried replacing the "while" with an "if" condition, but the result is the same.  My sketch does kind of 'work' if it is all within the 'while' condition, but that isn't really workable because it would mean that the sketch would be dead until the first packet of data is received, and there are lots of other things the sketch does that don't depend on the wireless remote.

Could you add the sender side sketch or at least add how often packages are sent.

Put the stuff that depend on the incoming packets inside the while, and the rest outside of the while.


text:
Parsing Data and Comparing two string in arduino
I am working on my final assignment. The problem is I want to make a prototype tool, with 2 string compare. If I send data "OK DISC DISCLOSED: 341513DB689AOK RSSI: -056 OK NAME: CarBT1 OK DISCE" will be parsed and bring up data "CarBT1 OK DISCE" if the data is correct then the LED will turn on, but my program isn't working? does anyone know the problem?
String dataIn;
String dt[10];
int i;
boolean parsing=false;
const int pinLED = 8;
String readString;

void setup (){
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
  Serial.print("Sketch:   ");   Serial.println(__FILE__);
  Serial.print("Uploaded: ");   Serial.println(__DATE__);
  Serial.println(" ");
  while(!Serial){
    ;
  }
}

void loop (){
  if(Serial.available()>0) {
  char inChar = (char)Serial.read();
  dataIn += inChar;
  if (inChar == '\n'){
  parsing = true;
  }
}
if(parsing){
  parsingData();
  parsing=false;
  dataIn="";
}
while(Serial.available()){
  delay(3);
  char c =  Serial.read();
  readString += c;
}
readString.trim();
  if(readString.length()>0){
    if(readString == "CarBT1 OK+DISCE"){
      digitalWrite(pinLED, HIGH);
      Serial.println("Switching On");
   }
  if(readString == "off"){
      digitalWrite(pinLED, LOW);
      Serial.println("Switching Off");
   }
readString = "";
 }
}

void parsingData(){
int j=0;
Serial.print("data masuk : ");
Serial.print(dataIn);
Serial.print("\n");
dt[j]="";
for(i=1;i<dataIn.length();i++){
  if ((dataIn[i] == ':') || (dataIn[i] == ':')){
  j++;
  dt[j]="";
}
  else{
  dt[j] = dt[j] + dataIn[i];
  }
 }
}
Serial.print("data 1 : ");
Serial.print(dt[0]);
Serial.print("\n");
Serial.print("data 2 : ");
Serial.print(dt[1]);
Serial.print("\n");
Serial.print("data 3 : ");
Serial.print(dt[2]);
Serial.print("\n\n");
Serial.print("data 4 : ");
Serial.print(dt[3]);
Serial.print("\n\n");
}

i think you need to add more info than (does not work). perhaps try remove (\r) char with string.replace("\r",""). and its better to use (readUntil) function than your method.

Part of your assignment is to learn debugging skills. Ask yourself what DOES work and where does it start to go wrong? Build from there.

Thank you for your response. Actually I tried to parse the data entered through serial on Arduino, and it worked. The problem is when the data that has been parsed I compare it to the string. I take an example, if I enter a message past the Arduino serial in the form of ABC: DEF I will be parsed into two data. data1 = ABC, data2 = DEF. When one of my data compares for example if (data1 == "ABC") {digitalWrite (pinLed, HIGH)}. LED does not turn on

while(Serial.available()){   delay(3);   char c =  Serial.read();   readString += c; } readString.trim();   if(readString.length()>0){     if(readString == "CarBT1 OK+DISCE"){       digitalWrite(pinLED, HIGH);       Serial.println("Switching On");    }   if(readString == "off"){       digitalWrite(pinLED, LOW);       Serial.println("Switching Off");    } readString = "";  } and this is the problem code, I took it from the code above

your code is inconsistently indented ..... that makes it difficult to follow the program flow ..... please try to correct the indentation of your code

I think that the biggest problem that you are encountering is that reading a line from serial is not as straightforward as you would like. I don't have a quick and easy solution for you, but there is much on this issue that you can look at.
You have two serial read while loops. The first exits as soon as there are no characters to read (even though some may be on the way). When "\n" is read, you set parsing but it does not mean that \n is removed from dataIn.
The second serial read while loop is using a delay(3) after detecting that a character is available, but that character could have arrived after the first read and be the only character in the buffer, for example.
I suspect that the reason that your String comparison does not work is simply because the Strings are not equal.
Your String looks like something read from an HM-10/11 or something similar. I have had some success reading those transmissions by doing the following:
Make sure the serial buffer is empty. When a character is available, read it into your building String, but continue looking for characters that are available for a set amount of time (maybe a couple of seconds). Continue looking for characters until the time has elapsed and not as soon as there are no characters available (because more may be coming). Alternatively, keep building the string until you recognize the "DISCE" marking the end of that transmission.
A problem, however, is that, in my experience, if it is a very long line (that can occur when there are many devices out there), you will never get that "DISCE". I assumed that this was a firmware issue.
Hope it helps.


text:
OTA mDNS issues with ESP8266 and PlatformIO?
The common useage of the OTA library for this MCU is to have it connect to a network, and to then use a computer on that network to upload firmware across that network. Due to either issues with PlatformIO (my IDE of choice right now) or my router (administrated by my ISP) blocking discovery (mDNS does NOT work here either way, and getting the IP is very hard as a result*), I would like to use the SoftAP class to make an access point that I can connect to directly when uploading firmware.
However, I have attempted this, and it does work IF I specify an IP address. This is a bit more convenient, but it fails if I try using mDNS again (via upload_port = myesp8266.local). (As an aside, this means that OTA over SoftAP does work, at least to this degree. I'm sure some will find this useful.)
Has anyone else confirmed either of these issues? I understand that they may be unrelated (since problem one is (Network || PIO) and the second is (PIO || SoftAP) as the cause), but any information as to why this might fail in both cases would be useful.
So, for the first case, can someone who uses that IDE and has an ESP8266 board test if mDNS works with the IDE?
For the second, assuming that mDNS does work with the IDE in the first case (and it's thus the MCU's fault), can anyone determine why the SoftAP class either halts or fails to work with mDNS?
This will really help my abilities to easily get firmware onto the board, and also tell me if I need to get a new router that allows mDNS (if it's not PlatformIO in the first case).
*Since the ISP administrates the router, I am unable to log in and view the IP addresses currently connected. My only option is printing it via UART, which renders this pointless, or attaching a OLED or LCD screen to every single device I build, or get a new router, which is its own issue right now. I've now run the web server test again, and not only does OTA not work with mDNS, but apparently I can't access it at all unless I know its actual IP address.

1: I'm surprised the router can block mDNS, that's not how mDNS works - 2. PlatformIO works with mDNS 100% in my (Windows 10) experience ... what operating system are you using? Can you ping myesp8266.local - are you sure you have the correct host name for your ESP? 3. I've never attempted OTA using SoftAP

can anyone determine why the SoftAP class either halts or fails to work with mDNS - would've thought mDNS is redundant with SoftAP - since SoftAP means the ESP has a known fixed address, 192.168.4.1 (by default)

that's not how mDNS works - I guess a router could block mDNS if it wanted to, seems like an unlikley scenario though

I had to perform that experiment again, and apparently I remembered wrong -- the web server is also not accessible. I can't even access the esp8266.local address even if I can access its IP directly. That's apparently for any networking feature if it's attached to my home network.

So you can't access the esp by ip address either?

No, I cannot. Chromium simply says that it can't find the address. PlatformIO complains of the same issue, saying that esp8266.local cannot be found.


text:
How to read analog pins from a second Arduino
I've run out of analog pins on Arduino Uno and don't have time to order new parts. I've heard you can connect two Arduinos and I have access to another UNO. If I did that, could I read the analog pins of the second Uno on the first one?
I'm planning to control 7 servos with separate potentiometers.

Why not buy an I2C or SPI ADC like the MCP3208? Needs the digital SPI on your Arduino Uno but gives you more 8 analog inputs. You can also buy two MCP3208, put them on the same SPI bus to give you 16 new analog inputs. Inter-Arduino communication is more complicated and costs more money. For I2C you have MCP3428.

Please tell us what you have connected to the analog pins. Perhaps we can find a way to change that. Do you need 7 potentiometers? It is for example possible to use a single analog input for 7 potentionmeters without extra hardware. That requires 14 digital pins to be able to power each potentiometer seperately.

I have connected several potentiometers and servos. I need to control the servo angle in real time, it's a lazer puzzle with mirrors redirecting the beam from one to another with real time inputs from potentiometers. There are 7 servos, each with their separate controls.

Yes that is possible, you can even use as many Arduino's as you want and send the information to one 'master' Arduino to process the data.
What you need is a way to communicate between them. Depending on distance, speed and reliability, you can chose for Serial, I2C, SPI or more 'exotic' solutions like CAN(bus), RS485 or even wireless methods (with nRF modules).
Some have a simple protocol, for others you might have to make it yourself.
Also think of the processing, you want to do the processing on the main device, or to process as much as possible on the 'slave' Arduinos and send it to the main device.
(Btw, I talk about Master/Slaves), these are not official terms, but meant as example. For example, with CAN, you can send message from any Arduino to any other. With Serial, you can send from 1 Arduino to 1 other.
If you have 2 Arduino's, probably Serial is the easiest.

Serial is best. Other protocols like I2C are bit complex to send and receive, requires understanding of I2C protocols, etc


text:
Arduino Bluetooth to Control Joystick Issue
I am trying to control a robot, where I have one HC05 module as a master connected to an Arduino Uno with an attached joystick. This Arduino sends data signals that will run blocks of code on the slave Arduino, which will have four servo motors connected to it, but for testing purposes, only two are connected. This Arduino also has an HC05 Bluetooth module connected to it, but it is configured as a slave. I have tried everything to get the Bluetooth functionality to work, but it does not work! If you are interested in the background of this, this is for my Rapid Assembly and Design project for school, which I have a report on soon. We are creating a robot that can operate on land and traverse the sea, so we are making it waterproof as well.
P.S. both modules are HC05 modules.
Master Code:
#include <SoftwareSerial.h>
int yPin = A0;
int xPin = A1;
int buttonPin = 2;
int xPosition = 0;
int yPosition = 0;
int buttonState = 0;
const int RX_PIN = 10;
const int TX_PIN = 9;
SoftwareSerial BL(RX_PIN, TX_PIN);
const int BLUETOOTH_BAUD_RATE = 9600;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  BL.begin(39600);
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  xPosition = analogRead(xPin);
  yPosition = analogRead(yPin);
  buttonState = digitalRead(buttonPin);
  /*if (buttonState == 1) {
    if (xPosition >= 450 & xPosition <= 550) {
      if (yPosition >=450 & yPosition <= 550) {
        Serial.write("a1 ");
        bluetooth.write("a1");
      }
      if (yPosition > 550) {
        Serial.write("a2 ");
        bluetooth.write("a2");
      }
      if (yPosition < 450) {
        Serial.write("a3 ");
        bluetooth.write("a3");
      }
    }
    if (yPosition >= 450 & yPosition <= 550) {
      if (yPosition >= 450 & yPosition <= 550) {
        Serial.write("b1 ");
        bluetooth.write("b1");
      }
      if (xPosition > 550) {
        Serial.write("b2 ");
        bluetooth.write("b2");
      }
      if (xPosition < 450) {
        Serial.write("b3 ");
        bluetooth.write("b3");
      }
    }
  }
  delay(100);
} */
  if (buttonState == 1) {
    if (xPosition >= 450 & xPosition <= 550) {
      if (yPosition >= 450 & yPosition <= 550) {
        BL.write("a1");
        BL.print("a1");
        Serial.print("a1");
        Serial.write("a1");
      }
      if (yPosition > 550) {
        BL.write("a2");
        BL.print("a2");
        Serial.print("a2");
        Serial.write("a2");
      }
      if (yPosition < 450) {
        BL.write("a3");
        BL.print("a3");
        Serial.print("a3");
        Serial.write("a3");
      }
    }
    if (yPosition >= 450 & yPosition <= 550) {
      if (xPosition >= 450 & xPosition <= 550) {
        BL.write("b1");
        BL.print("b1");
        Serial.print("b1");
        Serial.write("b1");
      }
      if (xPosition < 450) {
        BL.write("b2");
        BL.print("b2");
        Serial.print("b2");
        Serial.write("b2");
      }
      if (xPosition > 550) {
        BL.write("b3");
        BL.print("b3");
        Serial.print("b3");
        Serial.write("b3");
      }
    }
  }
}

Slave Code:
// Global Area
#include <Servo.h>
#include <SoftwareSerial.h>
int xPin = A1; // X connects to analog pin
int yPin = A0; // Y connects to analog pin
int buttonPin = 2; // Digital input pin for joystick state
int xPosition = 0; // Digital input pin for joystick X
int yPosition = 0; //  Digital input pin for joystick Y
const int RX_PIN = 10;
const int TX_PIN = 9;
int motorBRPin = 3;
int motorBLPin = 4;
int motorPRPin = 6;
int motorPLPin = 5;
int buttonState = 0; // Joystick state variable
Servo motor_br; // Declaration of servo with name of motor
Servo motor_pr;
Servo motor_bl;
Servo motor_pl;
SoftwareSerial BL(RX_PIN, TX_PIN);
const int BLUETOOTH_BAUD_RATE = 9600;
String state = "";

void setup() {
  Serial.begin(9600); // Begin serial monitor
  BL.begin(9600);
  pinMode(xPin, INPUT); // Declaring xPin as an input
  pinMode(yPin, INPUT); // Declaring yPin as an input
  pinMode(buttonPin, INPUT_PULLUP); // Declaring buttonPin as an input
  motor_br.attach(motorBRPin); // Telling servo which pin our servo motor is attached to
  motor_bl.attach(motorBLPin);
  motor_pr.attach(motorPRPin);
  motor_pl.attach(motorPLPin);
  }
void loop() {
  xPosition = analogRead(xPin); // Declaring the value of xPosition; The value given by the xPin read by the board at the analog input pin
  yPosition = analogRead(yPin); // Declaring the value of yPosition; The value given by the yPin read by the board at the analog input pin
  buttonState = digitalRead(buttonPin); // Declaring the value of buttonState;
  //Printing for reference
  /*Serial.print("X: ");
  Serial.print(xPosition);
  Serial.print(" | Y: ");
  Serial.print(yPosition);
  Serial.print(" | Button: ");
  Serial.println(buttonState);*/
  // If statements, if joystick is not pressed and is being pushed up, the motor will run clockwise at full speed.
  /*if (buttonState == 1) {
    if (xPosition >= 450 & xPosition <= 550) {
      if (yPosition >= 450 & yPosition <= 550) {
        motor_br.write(90);
        motor_bl.write(90);
      }
      if (yPosition > 550) {
        motor_br.write(0);
        motor_bl.write(0);
      }
      if (yPosition < 450) {
      motor_br.write(0);
      motor_bl.write(0);
      }
    }
    if (yPosition >= 450 & yPosition <= 550) {
      motor_br.write(90);
      motor_bl.write(90);
      motor_pr.write(90);
      motor_pl.write(90);
      if (xPosition < 450) {
        motor_br.write(0);
        motor_bl.write(0);
        motor_pr.write(0);
        motor_pl.write(0);
      }
      if (xPosition > 550) {
        motor_br.write(180);
        motor_bl.write(180);
        motor_pr.write(180);
        motor_pl.write(180);
    }

    }

    /*else if (xPosition < 450) {
      motor_br.write(0);
      motor_bl.write(0);
      motor_pr.write(0);
      motor_pl.write(0);
    }
    else if (xPosition > 550) {
      motor_br.write(180);
      motor_bl.write(180);
      motor_pr.write(180);
      motor_pl.write(180);
    }
    else if (yPosition >= 450 & yPosition <= 550) {
      motor_br.write(90);
      motor_bl.write(90);
    }
    else if (yPosition < 550) {
      motor_br.write(180);
      motor_bl.write(180);
    }
    else if (yPosition > 450) {
      motor_br.write(0);
      motor_bl.write(0);
    }
  }
  if (buttonState == 1) {
    if (xPosition >= 450 & xPosition <= 550) {
      motor_br.write(90);
      motor_bl.write(90);
      motor_pr.write(90);
      motor_pl.write(90);
    }
    else if (xPosition < 450) {
      motor_br.write(0);
      motor_bl.write(0);
      motor_pr.write(0);
      motor_pl.write(0);
    }
    else if (xPosition > 550) {
      motor_br.write(180);
      motor_bl.write(180);
      motor_pr.write(180);
      motor_pl.write(180);
    }
  }
  else if (buttonState == 0) {
    if (xPosition >= 450 & xPosition <= 550) {
      motor_br.write(90);
      motor_bl.write(90);
      motor_pr.write(90);
      motor_pl.write(90);
    }
    else if (xPosition < 450) {
      motor_br.write(0);
      motor_bl.write(0);
      motor_pr.write(0);
      motor_pl.write(0);
    }
    else if (xPosition > 550) {
      motor_br.write(180);
      motor_bl.write(180);
      motor_pr.write(180);
      motor_pl.write(180);
    }
  }*/
    while (BL.available()) {
      state = BL.read();
      state = Serial.read();
      Serial.print(state);
    }
    if (state == "a1" or "b1") {
      motor_br.write(90);
      motor_bl.write(90);
      state = "";
    }
    if (state == "a2") {
      motor_br.write(0);
      motor_bl.write(0);
      state = "";
    }
    if (state == "a3") {
      motor_br.write(180);
      motor_bl.write(180);
      state = "";
    }
    if (state == "b2") {
      motor_br.write(0);
      motor_bl.write(0);
      state = "";
    }
    if (state == "b3") {
      motor_br.write(180);
      motor_bl.write(180);
      state = "";
    }
    state = "";
  }

can you specify the problem you are facing.

You use 2 very different baudrates for master and slave. Though I don't know, if that really matters, as long as you don't spam the interface. Why are you sending the data twice on the master, once as ASCII and once as byte data (by using print/write)? And why are you setting the state variable twice on the slave, once from the Bluetooth connection and once from the hardware Serial?

It seems, that you mixed the master and slave code together. What should the joystick code do at the slave (which should be the robot from your description)?

How did you connect everything? Please provide schematics or a wiring diagram


text:
Burning Arduino Bootloader
I'm trying to use an atmega chip from an arduino on a breadboard, with minimal hardware (using the internal 8mhz clock).  I am using the article in the link provided.  When I reach the final step (burning the bootloader), I get an error telling me the device signature is wrong-
Arduino: 1.8.5 (Windows 10), Board: "ATmega328 on a breadboard (8 MHz internal clock)"
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.
Error while burning bootloader.
I am assuming the error is because the chip is from a uno clone, and uses an atmega328p-pu chip.  How am I able to override this check using -F, as described in the error message?  Or is there maybe some other way i can fix this?  Thanks in advance.
https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard

One of the parameters that you have to give avrdude is the microcontroller you are using, and then it checks the signature of the micro to ensuere that everthing is ok. this parameter is passed through -p flag
avrdude -p <microcontroller name>

For ATmega328 this parameter should be m328 and in your case, with ATmega328p this parameter should be m328p. All options avalible can be checked in man page.

Ok thanks.  How do I access and change the flag?

If you are using Arduino IDE to load micro, you will have to select what micro you are using in Tools > Board Menu or something like this. Anyway you can use terminal also.


text:
Arduino Smoothing does not work as expected
I using the standard example of smoothing:

/*
  Smoothing

  Reads repeatedly from an analog input, calculating a running average and
  printing it to the computer. Keeps ten readings in an array and continually
  averages them.

  The circuit:
  - analog sensor (potentiometer will do) attached to analog input 0

  created 22 Apr 2007
  by David A. Mellis  <dam@mellis.org>
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Smoothing
*/

// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

void setup() {
  // initialize serial communication with computer:
  Serial.begin(9600);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(1);        // delay in between reads for stability
}

to calculate power consumption for a load which changes it's value frequently (sometimes it stops and the consumption goes down to couple of watts).
My only modification of the above code is to pass a calculated power (V*I) value to it instead of the analogRead(inputPin);. The input value for the power calculation works fine because without this code I get the exact good values for power. I have also increased the numreadings from 10->100 and probably will needed to be increased a lot more since I need the average for 1 minute.
There are 2 major issues with this code:
1, When a constant load is attached, which let's say draws 500W the value generated by the code is floating around 312W and never reaches 500.
2, When the load is disconnected it and the current power consumption is 1-2watts standby this code jumps to -312W. I could cast it to be an unsigned integer on the first place but that's not really a good solution.
Anyone knows how to fix this?
Thanks

Consider the size of your array, the size of the Arduino RAM, and the number of items you will need in the array if you want to use this to generate an average over a minute or more.  Will it all fit?

Are your power readings int or float?

Ten analogRead values summed together can easily overflow int total.

@AnT how did you figure the sum of ten analogReads can overflow an integer? Even if they were the maximum (1023) that would surely easily fit into an integer- even if it were a 16 bit int. I am a bit confused by your comment..

@GMc: Frankly, I have no idea why I said that. A sum of ten should fit into a 16-bit int.

no problemo, at least it is cleared up now :)

Yes, change the variable type to something that can hold larger numbers, because now adding up 100 measurements will overflow your variable.


text:
PPM of Wasabi Eco
I'm currently trying to control a brushless DC motor (EMAX 1806-2280Kv) with a ESC called Wasabi Eco 12A (Wasabi Eco specifications#1 , Wasabi Eco specifications#2)
I'm trying to control the motor via an Arduino Uno, and using their IDE to begin with. I have the following code:
#include <Servo.h>
Servo ESC;     // create servo object to control the ESC
void setup() {
  delay(1000);
  ESC.attach(9, 1000, 2000); // (pin, min pulse width, max pulse width in microseconds)
  delay(2000);
   ESC.write(180);
  delay(300);
  ESC.write(0);
  delay(2000);

}

void loop() {

  ESC.write(1800);    // Send the signal to the ESC
  delay(100);
}

I have tried various of combinations and non of them seems to work. The motor sometimes beeps, but not in the correct way. I have tried to look for the PPM width (which is 1000 - 2000 μS in the code) but can't seem to find it anywhere. Any suggestions of what I'm doing wrong?

Probably you do not have the correct arming sequence.  If your question is about probing you need to explain what you tried.

I did as the datasheet said; full throttle and then minimum. But nothing seems to happen

This is really buried in the details of things you have not documented, but you could check if your "ESC" library requires that you set the pin as an output first.


text:
Reading contents of ESP8266 Flash from inside sketch
I am aware that there is a way to create a dump of the flash via esptool, but is there a way to read the contents of the sketch (just the sketch, not the full flash or SPIFFS) memory via the sketch itself? As in, have a program on the ESP8266 able to read its own machine code from the flash to do something with? I do not need write access, just read access.
I would like to be able to create a backup of the current sketch in SPIFFS so that it is possible to revert a bad sketch so long as the reversion trigger isn't broken. (For example, if a later part of the boot process is messed up, or if a function acts slightly wrong, a button could be held, and it would restore from the saved image. The restore process is something that I've figured out from my previous question, but I would like a way to write the sketch to SPIFFS that does not require a separate manual upload or a wrapper around the OTA process.)
[edit:]
Thank you for the comments.
I have created this code that SHOULD have copied the sketch to SPIFFS. However, it does not seem to have done so properly (since the result does not have the same checksums as the original file, and attempts to write it yield a nonfunctional device). Can I have someone look over it and see if they can figure out why?
unsigned long addr = 0;
unsigned long rem = ESP.getSketchSize();
uint32_t *data = new uint32_t[SPI_FLASH_SEC_SIZE];
File f = SPIFFS.open("/fw.bin", "w");
while (rem > 0) {
  ESP.flashRead(addr, data, SPI_FLASH_SEC_SIZE);
  int sz = SPI_FLASH_SEC_SIZE * sizeof(uint32_t);
  if (rem < sz)
    sz = rem;
  f.write(reinterpret_cast<uint8_t *>(&data[addr]), sz);
  addr += SPI_FLASH_SEC_SIZE;
  rem -= sz;
  yield();
  Serial.println(rem);
}
f.flush();
f.close();

I started looking into this after your previous question (because it's something I think would be useful for me as well) - if you look at how EEPROM is done, you'll see it uses spi_flash_read -which is defined in tools/sdk/include/spi_flash.h - now I think the firmware would be loaded starting at address 0 - and perhaps this python code (obviously converted to c++) may help in determining the exact size of the loaded firmware

actually, ... there's ESP.getSketchSize() to get the size of the sketch :p - so, in theory, it's just a matter of using spi_flash_read to read the sketch (in chunks, obviously, since the sketch is larger than RAM) and write it out to SPIFFS

I can't seem to get that to work. I've posted the code I wrote in the question now, but something is not working. I get a file with different contents, though it IS the right size.

what would be nice is if you could read it to see what's there - the unit32_t looks wrong for a start, your data would be 4 x SPI_FLASH_SEC_SIZE

I can understand that flash reading may be done with 32bits at a time, but not sure if the address is being manipulated correctly ... perhaps addr += SPI_FLASH_SEC_SIZE * 4;?

I also think that you are only getting SPI_FLASH_SEC_SIZE bytes, rather than dword's (32 bits) ... so you'd be writing a fair amount of junk - again, not sure, the documentation is vague at best

I think you're reading of flash is slightly wrong
while ESP.flashRead takes a unit32_t pointer for output data, the read "count" argument is in bytes - looking at Updater.cpp code it does this
uint8_t buff[128];
for(int i = 0; i < binSize; i += sizeof(buff)) {
  ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
  .....
}

so, the the address and count are in bytes - given that SPI_FLASH_SEC_SIZE is 0x1000 or 4096, your code is doing the following

reading 4096 bytes into a 16384 buffer
writing 16384 bytes (so the last 12288 bytes are zero, or random, not sure)
adding 4096 to the address
subtracting 16384 from size
repeat until all read

So, the written size will be correct, but the data will be three quarters wrong :p
Therefore, your code should be
unsigned long addr = 0;
unsigned long rem = ESP.getSketchSize();
uint8_t *data = new uint8_t[SPI_FLASH_SEC_SIZE];
int sz = SPI_FLASH_SEC_SIZE;
File f = SPIFFS.open("/fw.bin", "w");

while (rem > 0) {
    ESP.flashRead(addr, (uint32_t *)data, SPI_FLASH_SEC_SIZE);
    if (rem < sz)
        sz = rem;
    f.write(data, sz);
    addr += SPI_FLASH_SEC_SIZE;
    rem -= sz;
    yield();
    Serial.println(rem);
}

f.flush();
f.close();

That seems to have worked very well. Thank you. I will note that as written, it causes a compile error since f.write does not accept uint32_t.
I still cast the data for flash read, but defined 'data' as a uint8_t instead.

Oops I missed a unt32


text:
Arduino clients suddenly not able to connect (or publish) to MQTT
we are struggling with a project that has things (arduinos as clients) communicating to our MQTT broker (mosquitto) running on a DigitalOcean droplet (inside a docker). We have about 200 things at different locations sending about 20msg per minute each. Last week - after months without any issues - 20 clients suddenly were not able to connect to the server/publish anymore although they have been online. Today 4 other clients “went offline” the same second.
The latter 4 clients were fixed by simply restarting them. With the aforementioned 20 clients, we were able to test one (remotely) and we reflashed it (nothing changed with MQTT settings though) and it was then able to connect to the broker again...
First we thought it was a network issue but it all seems to be fine. Can you help us troubleshooting the issue? We run a DigitalOcean droplet for our mqtt server.

There’s not nearly enough information here to properly debug, but it sounds like a counter overflow to me. Things work fine for months, then an integer overflows, your code wasn’t prepared to deal with reading garbage, boom, dead in the water. Just a hunch.

Please post the code, versions of libraries and IDE used.


text:
Scanned RFID data is not appearing in the serial monitor
I am attempting to use this code to receive data from 2 ports, alternating between them:
/*
  Software serial multple serial test

  Receives from the two software serial ports,
  sends to the hardware serial port.

  In order to listen on a software port, you call port.listen().
  When using two software serial ports, you have to switch ports
  by listen()ing on each one in turn. Pick a logical time to switch
  ports, like the end of an expected transmission, or when the
  buffer is empty. This example switches ports when there is nothing
  more to read from a port

  The circuit:
  Two devices which communicate serially are needed.
   First serial device's TX attached to digital pin 10(RX), RX to pin 11(TX)
   Second serial device's TX attached to digital pin 8(RX), RX to pin 9(TX)

  Note:
  Not all pins on the Mega and Mega 2560 support change interrupts,
  so only the following can be used for RX:
  10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

  Not all pins on the Leonardo support change interrupts,
  so only the following can be used for RX:
  8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

  created 18 Apr. 2011
  modified 19 March 2016
  by Tom Igoe
  based on Mikal Hart's twoPortRXExample

  This example code is in the public domain.

*/

#include <SoftwareSerial.h>
// software serial #1: RX = digital pin 10, TX = digital pin 11
SoftwareSerial portOne(10, 11);

// software serial #2: RX = digital pin 8, TX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
SoftwareSerial portTwo(50, 51);

int RFIDResetPin = 13;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Start each software serial port
  portOne.begin(9600);
  portTwo.begin(9600);
}

void loop() {
  // By default, the last intialized port is listening.
  // when you want to listen on a port, explicitly select it:
  portOne.listen();
  Serial.println("Data from port one:");
  // while there is data coming in, read it
  // and send to the hardware serial port:
  while (portOne.available() > 0) {
    char inByte = portOne.read();
    Serial.write(inByte);
  }

  // blank line to separate data from the two ports:
  Serial.println();

  // Now listen on the second port
  portTwo.listen();
  // while there is data coming in, read it
  // and send to the hardware serial port:
  Serial.println("Data from port two:");
  while (portTwo.available() > 0) {
    char inByte = portTwo.read();
    Serial.write(inByte);
  }

  // blank line to separate data from the two ports:
  Serial.println();
}

I am using a mega2560, and have the pins placed in the 10 and 51 port. any help is appreciated.

Does it work, if you only use one Software serial interface? Why are you using Software Serial anyway? The Mega has 4 hardware serial interfaces. Currently I don't see, why your program should work reliably, since you are listening on the individual interfaces only for very short time intervals. Definitely not enough to receive much data at 9600 baud

@chrisl Im going to try to set a higher baud rate, maybe that will help.

This is still not a good way to read the two software serials. You could try to first read a full message from one software serial and then change to the second software serial and read a full message there. This would ensure, that you always read a valid message from each interface.

But again: Why SoftwareSerial? Why not hardware Serial interfaces?

@chrisl Yeah, I realized I was being dumb about it. I'm now using the hardware serial ports. I succesfully got serial1 to send to the serial monitor, now I a trying to set up serial2, so arduino will run through them sequentially. Any idea how to do that?

@chrisl If you are interested, the question is here


text:
Custom Arduino Due Random Lock up
I have built my own Arduino Due Circuit board. I am having issues with it randomly locking up. I have researched the libraries and have ruled out any issues with them such as the Wire library. I am wondering could an issue with the power supply cause a brown-out that would lock it up. The only way to recover is to unplug it and plug it back in. It can run for 1 hour 1 week or months before it locks up. Does anybody have any idea what could cause this issue and how I can resolve it? Could the fuse or lock bits being set wrong  cause this type of issue?

What is your BOD (brown Out Detect) fuse set to?

Welcome :-) "I have built my own Arduino Due Circuit board" So what did you change, compared to the original? Any component changes (type / value / not populated etc.)? Any layout changes or did you exactly copy the PCB layout too? Please edit your question to add those details. Also add details of any testing & analysis you've done so far, to avoid anyone wasting time suggesting things you've already done. Is your hypothesis of a brown-out based on any specific testing or analysis, or just a guess? Finally, please add photos of your board into the question (ctrl+G in the editor). Thanks.

Further questions: (a) To help confirm that this is a hardware problem, and not a problem with your code, have you had your custom board hang, while running only the most simple "blink LED" code (and if so, can you provide a copy of that code)? (b) Have you been able to change the frequency of the hangs (i.e. make them less frequent or more frequent) by doing anything, during your troubleshooting so far? (c) Also, based on your troubleshooting so far, have you been able to get confidence in a particular power source, for your subsequent tests? Thanks.