body:
I am very new to micro controller and circuits. I am not at all with this field. But trying to create a home project where I have a device image attached below.

[![enter image description here][1]][1]

This is 18650 Lipo battery powered device. Here **I want to calculate the battery level**. After doing some research on google I found that I need to have Voltage Divider which I think I already included in this with 220k ohms and 100k ohms

[![enter image description here][2]][2]

People are using different ways to calculate it. Which I found in few examples. Which I am not able to understand at all, that what formula or values they are referring to calculate it.

if someone can help to understand that will be helpful. Here is how I am coding it which I saw somewhere on internet itself.

          #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    //#include "DHTesp.h"

    #define DHT_PIN       16

    //SSID and Password of your WiFi router
    const char* ssid = "Asus";
    const char* password = "Xmv02488!!**";

    ESP8266WebServer server(80); //Server on port 80

    /***************************************************************
     * SETUP
     **************************************************************/
    void setup(void){
      Serial.begin(115200);
      WiFi.mode(WIFI_STA);

      WiFi.begin(ssid, password);     //Connect to your WiFi router
      Serial.println("");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }

      //If connection successful show IP address in serial monitor
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());  //IP address assigned to your ESP

      server.on("/", handleRoot);      //Which routine to handle at root location

      server.begin();                  //Start server
      Serial.println("HTTP server started");

      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(A0, INPUT);

    }
    /***************************************************************
     * LOOP
     **************************************************************/
    void loop(void){
      server.handleClient();          //Handle client requests

    }

    /***************************************************************
     * This function converts IPAddress struct to a String
     **************************************************************/
    String IpAddress2String(const IPAddress& ipAddress)
    {
      return String(ipAddress[0]) + String(".") +\
      String(ipAddress[1]) + String(".") +\
      String(ipAddress[2]) + String(".") +\
      String(ipAddress[3])  ;
    }

    /***************************************************************
     * This rutine is exicuted when you open its IP in browser
     **************************************************************/
     void handleRoot() {
      IPAddress ip_address = WiFi.localIP();
      String ip_str = IpAddress2String(ip_address);

      int nVoltageRaw = analogRead(A0);
      float fVoltage = (float)nVoltageRaw * 0.00486;

      float fVoltageMatrix[22][2] = {
        {4.2,  100},
        {4.15, 95},
        {4.11, 90},
        {4.08, 85},
        {4.02, 80},
        {3.98, 75},
        {3.95, 70},
        {3.91, 65},
        {3.87, 60},
        {3.85, 55},
        {3.84, 50},
        {3.82, 45},
        {3.80, 40},
        {3.79, 35},
        {3.77, 30},
        {3.75, 25},
        {3.73, 20},
        {3.71, 15},
        {3.69, 10},
        {3.61, 5},
        {3.27, 0},
        {0, 0}
      };

      int i, perc;

      perc = 100;

      for(i=20; i>=0; i--) {
        if(fVoltageMatrix[i][0] >= fVoltage) {
          perc = fVoltageMatrix[i + 1][1];
          break;
        }
      }

      server.send(200, "text/plain", "Hello from esp8266!\n\rIP: " + ip_str +
        ".\n\rTemp: " + "NO" +
        ", Hum: " + "NO" +
        "\n\r" + "NO" +
        "\n\r" + "Voltage: " + fVoltage +
        "\n\r" + "Charge: " + perc + '%');
    }

This is a copied code. Where I am not sure about where they got the this formula and how they got the value of 0.00486

I copied this code from different source references. But I hope this will help you to understand the issue.

Any suggestions will be helpful!

Thank you! (In advance)

  [1]: https://i.stack.imgur.com/72QGO.png
  [2]: https://i.stack.imgur.com/aZuTb.png

title: Calculate the Li-Po Battery Level in ESP-Wroom-02

Answers: 3

body:
The problem with LiPo batteries is that the discharge curve is very flat.  Here's an example:

[![enter image description here][1]][1]

As you can see, for about 95% of the life of the battery there is very little change in voltage.  You can't just take the voltage between "full" and "empty" and get a percentage from that. Instead you have to map points along that curve to different percentages.

The simplest way is to just have a set of percentages that you are interested in - every 5% as in the code you have above. Then you say "If the voltage is above this value then it's 100%. If it's above this next value down it's 95%. If it's above the next value down then it's 90%". etc.

The array `fVoltageMatrix` contains that mapping.  For 100% the voltage must be 4.2V or greater.  For 95% it must be 4.15V or greater. And so on.

If we take those voltage values from the array and plot them on a graph they look like this:

[![enter image description here][2]][2]

As you see that looks kind of similar. Quite flat, with a sudden drop off.

The code that gets the percentage charge simply reads the value from the ADC and converts it to a voltage by multiplying it by 0.004861, then it steps through the array one element at a time. The first time it finds one that fails the test "This percentage's threshold is less than the voltage" makes it take the previous one in the list as the percentage.  Personally, I think that's backwards and a bad way of doing it.  Instead, it should be the first one that passes the test "The voltage is greater than or equal to this percentage's threshold" that should be taken.  I'd rewrite the loop like this:

    perc = 0;

    for(i=0; fVoltageMatrix[i][0] > 0; i++) {
      if(fVoltage >= fVoltageMatrix[i][0]) {
        perc = fVoltageMatrix[i][1];
        break;
      }
    }

----

1 The number 0.00486 is the number of volts applied to the input to give a 1 from the ADC. Incidentally, if I am using the right figures, I calculate it should be 0.003125.  1 * (1/1024) gives 0.000976563 (that's 1 volt maximum range on the ADC, multiplied by one bit - a 1024th since it's 10 bit resolution on the ESP8266). Multiply that by the ratio of the resistors ((R1 + R2)/R2) which is 3.2, and that gives 0.003125. To compress it, you get:  `x = (R1 + R2) / R2 * 1/1024` = `320000 / 100000 * 0.000976563` = `0.003125`

However, my numbers could be wrong...

  [1]: https://i.stack.imgur.com/Njfh3.png
  [2]: https://i.stack.imgur.com/bJ0aV.png

body:
One problem I have with the ESP8266 is the crappy results from the A/D converter. There are a number of hoops that you need to go through for the planets to align in order to get consistent readings. See  Fluctuating ADC with stabilized source https://github.com/esp8266/Arduino/issues/2070

The other issue I have is with the assumption that the range of operation of the A/D is 0-1.0 volts and that certainly is not the case.

> I calculate it should be 0.003125. 1 * (1/1024) gives 0.000976563
> (that's 1 volt maximum range on the ADC

The above shows how precise our calculations can be but unfortunately the six digits of precision gets thrown out the window if the assumed 1 volt top end has variations of 5%. Unfortunately there are no specifications given as far as the A/D converter in the miniscule spec sheet.

Yes the ESP8266 A/D can be calibrated, and measurements taken under controlled conditions. But make sure that you do the required work and verify the results under all operating conditions before you trust your results.

body: Another problem you can run into is that a lot of the A/D converters use the VCC as a voltage reference. Which means that as your input voltage drops (what you are trying to measure) the reference voltage also drops which means the values you are recording will not appear to change or at least will not give an accurate reference.


body:
Experimenting with external interrupts on a Mega. Pins 2 and 3 work with standard

 `attachInterrupt(digitalPinToInterrupt(iPin),ISR,FALLING);`

coding and call my ISR. With pins 18 and 19 I had to add

    EIFR = 4;
for pin 19, and

    EIFR = 8;
for pin 18 before calling attachInterrupt(...) to get them to work. Why?

BTW, I'll add this table that I filled in by trial and error for anyone interested in Atmel (AVR) external interrupt numbers to Arduino external interrupt numbers (I won't list the AVR chip pin numbers)

    AVR INT      5 .  4 .  3 .  2 .  1 .  0
    EIFR (Dec)  32 . 16 .  8 .  4 .  2 .  1
    Arduino Pin  3 .  2 . 18 . 19 . 20 . 21
    Arduino INT  1 .  0 .  5 .  4 .  3 .  2

I know writing a 1 to the EIFR bit for the appropriate interrupt clears the interrupt. When I reset the Arduino without clearing interrupts on pins 2 and 3 it's fine. If I don't clear 18 and 19 after a reset, it throws the interrupt right away. (Yes, I should OR the EIFR with the bit I want to change but I'm just playing) Didn't try 20 and 21 because I'm using them for comm.

title: Mega attachInterrupt on pins 18 or 19 require EIFR bit set first (to clear it)?

Answers: 1

body:
It's not that pins 18 or 19 are faulty, you are just lucky the other ones worked.

As I mention on [my page about interrupts](http://www.gammon.com.au/interrupts)* you are recommended to always write 1 to the appropriate EIFR bit before enabling interrupts because it (the interrupt condition) may have been set in the past.

I checked the source for `attachInterrupt` in the file WInterrupts.c and there is no mention of the EIFR register, therefore `attachInterrupt` never affects that register.

---

\* Also see my answer: https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards/30969#30969


body:
I am working on IoT based project and I want to control the device using mobile App. Everything works fine, I can switch the load and get the status back on mobile app, but I want to use my ESP8266 as a GPS using google API.
I have googling many many times but people work with standalone ESP8266 as a GPS using google API.
Here there are the two github project for Standalone ESP8266 as GPS:

1. [Google GeoLocation API wrapper for Arduino MKR1000, ESP8266 and ESP32][1]
2. [Google Geolocation API for fetching location on ESP8266 board without using any GPS hardware][2]

My Question is: how can I use my ESP8266 for IoT application (Controlling the Arduino pins) as well as GPS module using Google API?

In my case, I need to use an Arduino Mega/Uno because much more sensors were used in this project which I not mentioned here.

I attached my code, its working perfect, means I controlled the Arduino pins and Arduino send the status using ESP8266 on my mobile App.

    String server = ""; //variable for sending data to webpage
    boolean No_IP = false; //variable to check for ip Address
    String IP = ""; //variable to store ip Address
    char data;
    char values = 'c';
    int flag = 1;

     void setup()
    {
    Serial.begin(9600);
    Serial1.begin(9600);
    wifi_init();
    delay(200);
    showIP();

    }

        void loop()
    {
      delay(50);
      String temp = "";
    while(Serial1.available()) // Check the Esp Serial
    {
      temp = Serial1.readString(); // Read the String from Esp Serial
      Serial.println(temp);
      delay(50);
    }
    if ((temp.substring(11) == "a" or temp.substring(11) == "A") and flag == 1) // If "a" or "A" received
    {
      digitalWrite(13,HIGH); // Load conected on pin 13 ON
      Serial.println("Char received High");
      flag = 0;
      sendData("Light On");
      delay(1000);
    }

    else if ((temp.substring(11) == "a" or temp.substring(11) == "A") and flag == 0)
    {
      digitalWrite(13,LOW); // Load conected on pin 13 OFF
      Serial.println("Char received Low");
      flag = 1;
      sendData("Light Off");
      delay(1000);
    }
    else
    {

    }

    delay(200);

    } // Void loop End

These are the functions which is used to established the connection.

Note: I used the ESP 8266 in Station mode
Check in `void wifi_init() function, `
`

    void findIp(int time1) //check for the availability of IP Address
    {
      int time2 = millis();
      while (time2 + time1 > millis())  {
        while (Serial1.available() > 0)    {
          if (Serial1.find("IP has been read"))      {
            No_IP = true;
          }
        }
      }
    }

    void showIP()//Display the IP Address
    {
      IP = "";
      char ch = 0;
      while (1)
      {
        Serial1.println("AT+CIFSR");
        while (Serial1.available() > 0)
        {
          if (Serial1.find("STAIP,"))
          {
            delay(1000);
            Serial.print("IP Address:");
            while (Serial1.available() > 0)
            {
              ch = Serial1.read();
              if (ch == '+')
                break;
              IP += ch;
            }
          }
          if (ch == '+')
            break;
        }
        if (ch == '+')
          break;
        delay(1000);
      }
      Serial.print(IP);
      Serial.print("Port:");
      Serial.println(80);
    }

    void establishConnection(String Serial1and, int timeOut) //Define the process for sending AT Serial1ands to module
    {
      int q = 0;
      while (1)
      {
        Serial.println(Serial1and);
        Serial1.println(Serial1and);
        while (Serial1.available())
        {
          if (Serial1.find("OK"))
            q = 8;
        }
        delay(timeOut);
        if (q > 5)
          break;
        q++;
      }
      if (q == 8)
        Serial.println("OK");
      else
        Serial.println("Error");
    }

    void wifi_init() //send AT Serial1ands to module
    {

      establishConnection("AT", 100);

      establishConnection("AT+CWMODE=1", 100);
      establishConnection("AT+CWQAP", 100);
      findIp(5000);
      if (!No_IP)
      {
        Serial.println("Connecting Wifi....");
        establishConnection("AT+CWJAP=\"SSID\",\"PASSWORD\"", 7000);        //provide your WiFi username and password here
      }
      else
      {
      }
      Serial.println("Wifi Connected");
      // showIP();
      establishConnection("AT+CIPMUX=1", 5000);
      establishConnection("AT+CIPSERVER=1,80", 7000);
    }

    void sendData(String server1)//send data to module
    {
      int p = 0;
      while (1)
      {
        unsigned int l = server1.length();
        Serial.print("AT+CIPSEND=0,");
        Serial1.print("AT+CIPSEND=0,");
        Serial.println(l + 2);
        Serial1.println(l + 2);
        delay(100);
        Serial.println(server1);
        Serial1.println(server1);
        while (Serial1.available())
        {
          Serial.print(Serial.read());
          if (Serial1.find("OK"))
          {
            p = 11;
            break;
          }
        }
        if (p == 11)
          break;
        delay(100);
      }
    }

Is it possible to use ESP8266 for IoT applications as well as GPS module using google API?

  [1]: https://github.com/gmag11/WifiLocation
  [2]: https://github.com/techiesms/Geolocation/blob/master/Geolocation_without_display.ino

title: How to use ESP8266 with Google API for GPS as well as controlling Arduino pins

Answers: 0


body: What is the meaning of "volatile bool mpuInterrupt = false; " in Arduino Program interfacing MPU6050?

title: Interfacing MPU6050 with Arduino uno

Answers: 1

body:
The i2cdevlib has that declared in this file: https://github.com/jrowberg/i2cdevlib/blob/master/Arduino/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino

That is the "dmp" example.
Inside the MPU-6050 sensor is a "dmp" and a FIFO buffer. The "dmp" is a processing unit that collects the sensor data, does some calculations and puts the data in the FIFO buffer. After that the Arduino is signalled with a interrupt.

In the Arduino, in the interrupt routine, the flag 'mpuInterrupt' is set. In the loop() that flag is checked and the amount of data in the FIFO buffer is read. When there is enough data, that data is read and used in the sketch.

Since the variable 'mpuInterrupt' is used in a interrupt routine and in the loop(), it is made 'volatile'. That tells the compiler that the variable can change at any moment, so the compiler can keep that in mind when creating binary code for the loop().


body:
I am desperate need of help with my code. It is meant to be a biology project (a pcr machine) and I struggle with inplementing a time tracker. Everytime the cyclus goes to a function, I need it to save that exact time, and then lt it run for a certain amount of time (this variable is given in a parameter). So help is really really appreciated.

    //variabelen

    #include <Adafruit_MAX31855.h>

    int maxSO =  4;
    int maxCS = 5;
    int maxSCK = 6;

    Adafruit_MAX31855 thermocouple(maxSCK, maxCS, maxSO);

    int fan = 9; //connected to transistor base
    int temp;
    int tempMin = 18;   //variable to check if the thermocouple is connected
    int tempMax = 100;   //never exceed this temperature
    int fanSpeed;
    int RelayP = 3; //still got to check if it is 3 or 4
    int cyclusamount = 3; //still got to add a button

    //cyclussen op één rij
    float DENTEMP = 94;
    float ANTEMP = 62;
    float EXTEMP = 72;

    //tijden op een rij
    unsigned int INITDENTIME = 53000;
    unsigned int DENTIME = 33000;
    unsigned int ANTIME = 33000;
    unsigned int EXTIME = 33000;
    unsigned int ENDEXTIME = 42000;

    unsigned long timer1 = 0;
    unsigned long timer2 = 0;
    double temp;
    double MaxTempIncrease = 2;

    //int cycles = 0;
    int phase = 0;
    int a = 0;
    int g = -1;
    int phaseOfCyclus = 0;
    int timesArray[] = [33000, 33000, 33000];
    int tempsArray[] = [94, 62, 72];
    int cycluscounter = 0;

    const unsigned long startTime;
    unsigned long startMillis;

    void setup() {
      Serial.begin(9600);
      delay(500);
      pinMode(fan, OUTPUT);
      digitalWrite(fan, LOW);
      pinMode(RelayP, OUTPUT);
      digitalWrite(RelayP, LOW);
      delay(5500);
    }

    void loop() {
      //eerst is er een delay, na de delay zal a springen op a=1
    if(a == 0) {
        delay(1000);
        a++;
      }

    //wanneer a=1 geldt dan zal de temperatuur stijgen naar 94 graden, wanneer dit is bereikt wordt  a=2 en phaseOfCyclus=1
    else if(a == 1){
         raiseTemp(DENTEMP);
      }

    //wanneer a=2 geldt dan zal de temperatuur stabiel worden gehouden (dus 94 graden) voor de initiatie-stap duur, dat is ongeveer rond de 4minuten
    //wanneer deze tijd is verstreken dan wordt a=3 (en phaseOfCyclus=1 (nog steeds))
    else if(a == 2) {
        holdTemp(DENTEMP, INITDENTIME);
      }

    else if(a == 3) {

    //De eerste fase van één cyclus in de PCR machine begint met 94 graden voor 30 seconden.
    //de functie raiseTemp heeft 1 parameter en die wordt verkregen door het eerste getal uit de tempsArray
    //Is dit volbracht, dan wordt phaseOfCyclus=2
    if(phaseOfCycles = 1) {
      raiseTemp(tempsArray[1];
    }

    //de temperatuur wordt dan weer stabiel gehouden, de twee parameters geven de tijdsduur en de temperatuur van de fase waarin de cyclus van de pcr machine zich bevind
    //is dit volbracht en was phaseOfCyclus=2, dan wordt phaseofcyclus=3
    else if (phaseOfCyclus = 2) {
      holdTemp(tempsArray[1], timesArray[1]; //hoort 0

    }

    //dan zal de temperatuur afkoelen tot een bepaalde temperatuur, als dit is volbracht -> als phaseofcyclus=3 dan wordt phaseofcyclus=4
    else if (phaseOfCyclus = 3) {
      cooldown(tempsArray[2]; //hoort 1
    }

    //de temperatuur wordt weer stabiel gehouden, voor 30 seconden en als phaseofcyclus is 4 dan phaseofcyclus=5
    else if (phaseOfCyclus = 4) {
      holdTemp(tempsArray[2], timesArray[2]; //hoort 1

    }

    //dan zal de temperatuur verder afkoelen tot een bepaalde temperatuur, als dit is volbracht -> als phaseofcyclus=5 dan wordt phaseofcyclus=6
    else if (phaseOfCyclus = 5) {
      cooldown(tempsArray[3]; //hoort 2
    }

    //de temperatuur wordt weer stabiel gehouden, voor 30 seconden en als phaseofcyclus is 5 dan phaseofcyclus=6
    //bij één hele cyclus zal holdtemp 3x worden aangeroepen, elke keer als dit dus 3x gebeurt dan zal de cyclusamount +1 in hoeveelheid toenemen
    //als de cyclusamount niet gelijk is aan het aantal cyclussen dat iemand wil uitvoeren dan zal -> phaseofCyclus = 1
    //is dit wel groter of gelijk aan het aantal cyclussen dat iemand wil uitvoeren dan zal -> a =4  (als a = 3 en phaseofcyclus = 6)
    else if (phaseOfCyclus = 6) {
      holdTemp(tempsArray[3], timesArray[3]; //hoort 2
    }}

    //dan zal de extending temperatuur stabiel worden gehouden en als de tijd is verstreken dan zal a = 5 worden en zal de lcd zeggen dat de cyclus is volbracht
    else if (a == 4) {
       holdTemp(EXTEMP, 42000);
      }
    else if(a == 5) {
      digitalWrite(fan, LOW);
      digitalWrite(RelayP, LOW);
      Serial.println("Cyclus completed");
    }
    }

    void raiseTemp(double y) {
      double prevTemp = thermocouple.readCelsius();
      temp = thermocouple.readCelsius();

    if (temp < tempMin) {
       Serial.println("is the thermocouple connected???");
      }

    while (temp < y) {
        int waittime = min(650, ((650*(y-temp))));
        digitalWrite(RelayP, HIGH);
        delay(waittime);
        digitalWrite(RelayP, LOW);
        temp=thermocouple.readCelsius();

    if(temp >= y) {
        if(phaseOfCyclus = 1) {
          phaseOfCyclus = 2;
          a = 3;
        }
        else if (phaseOfCyclus = 0){
          phaseOfCyclus++;
          a = 2;
        }
          // break; //wat doet dit precies?
        }

    if((y-temp) < 1) {
          do  {
            prevTemp = temp;
            delay(250);
            temp = thermocouple.readCelsius();
          }
          while(temp > prevTemp);
        }

    if(temp >= TempMax)
         break;

    else {
          prevTemp = temp;
       }

       while ((temp-prevTemp) >= MaxHeatIncrease) {
         prevTemp = temp;
         Serial.print("HEATING UP TOO FAST! ");
         delay(1000);
         temp = thermocouple.readCelsius();
         Serial.println(temp);
       }

       while(temp >= y) {
         delay(1000);
         Serial.print("DANGER DANGER DANGER");
         Serial.println(temp);
       }
    }}

    void holdTemp(double phaseTemp, double duration) {
      g++;
      z = phaseTemp;

      startMillis = millis();
      unsigned long whatitneedstobe = startTime + duration;
      //startMillis < whatitneedstobe

      if(timegone < duration){
            temp = thermocouple.readCelsius();
          if(temp < z) {
            digitalWrite(RelayP, HIGH);
            delay(90);
            digitalWrite(RelayP, LOW);
          }
          else if (temp > (z+0.5)) {
            digitalWrite(fan, HIGH);
            delay(90);
            digitalWrite(fan, LOW);
            //or
            //fanSpeed = map(temp, tempMin, y, 32, 255);
            //analogWrite(fan, fanSpeed);
          }
         delay(210);
         timegone = millis() - startTime;
         }

      else {
        if(phaseOfClus = 1) {
          a = 3;
        }
        else if(phaseOfCyclus = 2) {
          phaseOfCyclus = 3;
        }
        else if(phaseOfCyclus = 4) {
          phaseOfCyclus = 5;
        }
        else if(g == 3) {
        g = 0;
        cycluscounter++;
        if(cycluscounter < cyclusamount) {
          a = 3;
          phaseOfCyclus = 1;
        }
        else(cycluscounter >= cyclusamount {
          a = 4;
        }
      }
      else if(a = 4) {
        a = 5;
      }
        }
      }

    void cooldown(double c) {
      unsigned long startTime = millis();
    while ((temp = thermocouple.readCelsius()) > (minTemp+0.75)) {
        digitalWrite(fanPin, HIGH);
        delay(300);
       }
       digitalWrite(fanPin, LOW);
    if(thermocouple.readCelsius() == c){
      if(phaseOfCyclus = 3) {
        phaseOfCyclus = 4;
      }
      else if(phaseOfCyclus = 5) {
        phaseOfCyclus = 6;
      }
    }
    }

title: How do I keep track of the time passed in this code? (PCR machine)

Answers: 1

body:
If you want the `holdTemp()` function to run for a specified duration,
you can write it like this:

    void holdTemp(double phaseTemp, unsigned long duration) {
        unsigned long start_time = millis();
        while (millis() - start_time < duration) {
            // whatever...
        }
    }

Note that if you use `delay()` inside the function, the time spent in it
may get longer than the requested duration, by as much as the duration
of the delay.


body:
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("-----------------------------");
    }

title: Seeed CAN Shield - Not receiving extended CAN-Message

Answers: 0


body:
Today we were programming something in university which dealt with really large numbers (even larger than unsigned long) and we had to create a code that broke the  numbers into an array and performed operations on them.

I know that an Arduino is an 8 bit MCU, but I was wondering if similar approaches could be used to do 32 bit double precision floating point operations (or even better,  i.e quad precision, etc) using the Arduino (e.g. create a quad precision calculator or similar applications).

I know it sounds silly or similar to a brute force method, but I'm really curious if it's possible to do such things.

title: Double precision floating point operations using Arduino

Answers: 0


body:
I have purchased a MI0283QT-9A TFT display (https://download.mikroe.com/documents/add-on-boards/other/display/tft-proto/tft-proto-manual-v200.pdf) which is
driven by the ILI9341 display controller.

I've managed to find the following board specification: http://pub.ucpros.com/download/tft_320_240_mi0283qt_9a_v1_3_spec.pdf

First of all, the pins are named differently from all the examples I can find for connecting it to my ESP32 microcontroller. For example, the TFT specs describe:

    33 SDO Serial Output Signal
    34 SDI Serial Input Signal
    35 RD Read execution control pin
    36 WRX(D/CX) Write execution control pin ; Serial Register select s Signal
    37 D/CX(SCL) Register select signal; Serial Interface Clock
    38 CSX Chip Select Signal
    39 TE Tearing effect out pin synchronize MPU to frame writng

But this Adafruit ILI9341 example (https://github.com/adafruit/Adafruit_ILI9341/blob/master/examples/graphicstest/graphicstest.ino) talks about CS, DC, MOSI, CLK, RST, and MISO.

I think these map as follows, **can anyone confirm that**?

    ESP32 = TFT
    --------------
    DC    = RS
    CLK   = WR, although maybe it should connect to DC???
    CS    = CSX
    MOSI  = SDI
    RST   = RST
    MISO  = SDO

I'm really unsure about the first two!

Second, in the PDF it refers to note 1 on page 11:

[![enter image description here][1]][1]

So as far as I can tell, I need to set the voltage high/low on the four IM* pins, depending upon the interface I want to use. So the second question is **which interface does the Adafruit ILI9341 library use**?

  [1]: https://i.stack.imgur.com/FcfbK.png

title: Connecting TFT Display MI0283QT-9A to ESP32

Answers: 2

body:
It sounds like you want a 4-wire 8-bit serial SPI compatible interface.  To get that you have to set the IMx pins to the right state to enable that interface.  That means:

* IM0 = LOW
* IM1 = HIGH
* IM2 = HIGH
* IM3 = HIGH

You can hard-wire those to GND for LOW and +3.3V for HIGH.

That will then configure it to work in the right mode for you, where it gives you access to the following pins:

    | Display  | ESP32   | Function                    |
    |----------|---------|-----------------------------|
    | SCL (RS) | SCK     | Serial clock                |
    | SDI      | MOSI    | Serial data Master -> Slave |
    | SDO      | MISO    | Serial data Slave -> Master |
    | D/CX (WR)| DC      | Data / Command register sel |
    | CSX      | CS      | Chip Select (Active Low)    |
    | RST      | RST     | Reset                       |

body:
Same (TFT proto board) tested Arduono DUE.

Pins IM1-3 HI, IM0 LO. (4-wire 8-bit data serial interface)

SDI - MOSI, SDO - MISO,RS - CLK, RD - HI, WR - D9, CS - D10, Reset - Reset (D8)

Driver UTFT myGLCD (ILI9341_S5P, MOSI, SCK, 10,8,9);

or

    // For the Adafruit shield, these are the default.
    #define TFT_DC 9
    #define TFT_CS 10
    Adafruit_ILI9341 tft = Adafruit_ILI9341 (TFT_CS, TFT_DC);

Backlight needs resistor!


body:
I am using the GsmSSLWebClient example which comes with the MKRGSM library.
The original example works just fine, I get the arduino ascii logo. But when I change the URL the arduino doesn't get any answer:

    //char server[] = "arduino.cc";
    //char path[] = "/asciilogo.txt";
    char server[] = "wepardi.fi";
    char path[] = "/robots.txt";

    Starting Arduino web client.
    connecting...
    connected
    GET /robots.txt HTTP/1.1
    Host: wepardi.fi
    Connection: close

    disconnecting.

From Firefox https://www.wepardi.fi/robots.txt is displayed correctly.
I tried also some other sites, and from some of them I get the ascii file content correctly, and from some others not.

Something wrong with my settings?

Prints from debug mode:

    connecting...

...

    AT+USECMNG=0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5",1239
    >
    +USECMNG: 0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5","cb17e431673ee209fe455793f30afa1c"

    OK
    AT+USOCR=6

    +USOCR: 0

    OK
    AT+USOSEC=0,1,0

    OK
    AT+USECPRF=0,0,1,4,"www.wepardi.fi"

    OK
    AT+USOCO=0,"www.wepardi.fi",443

    ERROR

    +UUSOCL: 0
    AT+USOCL=0

    ERROR
    connected
    GET /robots.txt HTTP/1.1
    Host: www.wepardi.fi
    Connection: close

    disconnecting.

Command
    AT+USOCO=0,"www.wepardi.fi",443
fails

GsmWebClient (no SSL) example works fine with any hosts I have tried.

title: Arduino MKR GSM 1400 SSL client example fails to connect

Answers: 2

body:
The problem you have is that of redirection.

You connect to `wepardi.fi` and request the file `/robots.txt` from that host. It immediately tells you "Ok, but that file is actually on `www.wepardi.fi/robots.txt`. Go get it from there.

But it won't.

You have to go direct to the source.

Here's a trace:

    GET /robots.txt HTTP/1.1
    Host: wepardi.fi
    Connection: close

    HTTP/1.1 302 Found
    Date: Tue, 08 Jan 2019 14:26:51 GMT
    Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.0.32
    Strict-Transport-Security: max-age=63072000; includeSubdomains;
    X-Powered-By: PHP/7.0.32
    Location: https://www.wepardi.fi/
    Cache-Control: max-age=1296000
    Expires: Wed, 23 Jan 2019 14:26:51 GMT
    Content-Length: 0
    Connection: close
    Content-Type: text/html; charset=UTF-8

And when you change to `www.wepardi.fi`:

    GET /robots.txt HTTP/1.1
    Host: www.wepardi.fi
    Connection: close

    HTTP/1.1 200 OK
    Date: Tue, 08 Jan 2019 14:27:49 GMT
    Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.0.32
    Strict-Transport-Security: max-age=63072000; includeSubdomains;
    X-Powered-By: PHP/7.0.32
    X-Robots-Tag: noindex, follow
    Link: <https://www.wepardi.fi/wp-json/>; rel="https://api.w.org/"
    Cache-Control: max-age=300
    Expires: Tue, 08 Jan 2019 14:32:49 GMT
    Content-Length: 67
    Connection: close
    Content-Type: text/plain; charset=utf-8

    User-agent: *
    Disallow: /wp-admin/
    Allow: /wp-admin/admin-ajax.php
    read:errno=0

body:
I finally found a solution to this problem. Disabling certificate validation in MKRGSM library makes the SSL connection succeed also to this site. In MKRGSM/src/GSMClient.cpp I changed

    //     MODEM.sendf("AT+USECPRF=0,0,1,4,\"%s\"", _host);
           MODEM.sendf("AT+USECPRF=0");

to use modem factory settings. I still don't know what was the problem with the certificates.
Thanks to everyone who tried to help with this.


body:
I want to make a simple digital voltage monitor. So I have a sketch:

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

    void loop() {
      int val = analogRead(A4);     // read the input pin
      val = 1;
      byte buf[4];
      buf[0] = 0;
      buf[1] = 0;
      buf[2] = val & 255;
      buf[3] = (val >> 8) & 255;
      Serial.write(buf, 4);             // report voltage value
    }

When I tried to read serial buffer on PC host, I noticed that sometimes 1 byte can be lost, which lead to shifts and headache. How should the streaming be done?

---
PS.

- host os: win7 x64;
- language: c/c++
- com port library: [CSerial](https://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2503/CSerial--A-C-Class-for-Serial-Communications.htm)

---
Loop is as follows:

    typedef int32_t sample_t;
    while (true) {
     int nBytesRead = serial.ReadData(lpBuffer, bufSize * sizeof(sample_t));
     size_t numRead = nBytesRead / sizeof(sample_t);
     if (numRead > 0)
      std::cout << "read: " << numRead << " samples\n"; // Calculate average here!
    }

title: Voltage meter ADC + serial: Bytes lost during communication

Answers: 1

body:
With help in a comments I've managed to deal with the task myself.

First of all, as @Majenko pointed out, I was dealing with some multi-byte data. So I need some control character, that separates packets. I choose hex output with '\n' delimeter as control character - that served good. I was able to read 3.5 to 5k packets per second (with voltage reading) from serial on the host.

Second improvement, credited to @Jot, is to stack some sequential values right in arduino, before sending.

Alongside with [increasing sampler frequency](http://yaab-arduino.blogspot.com/2015/02/fast-sampling-from-analog-input.html) that could be very good.

    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

    void setup() {
      sbi(ADCSRA, ADPS2);
      cbi(ADCSRA, ADPS1);
      cbi(ADCSRA, ADPS0);
      Serial.begin(115200);
    }

    void loop() {
      int val = 0;
      for( int i = 0; i < 32; ++i )
        val += analogRead(A0);
      Serial.print(val, HEX);
      Serial.print("\n");
    }

at the host recieve side, some simple conversion could be done:

    #include "Serial.h"
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <ctime>

    // sample to voltage
    double s2v(int sample) {
     return 5.0 * (static_cast<double>(sample) / 1024);
    }

    int main() {
        std::ofstream ofs("test.csv", std::ios::out | std::ios::ate);

     size_t comPort = 3;
     size_t baudRate = 115200; // 57600;

     CSerial serial;
     if (serial.Open(comPort, baudRate))
     {
      std::cout << "COM" << comPort << " opened @" << baudRate << "bit/s\n";

      // serial recv buffer
      size_t bufSize = 1048576;
      auto lpBuffer = new char[bufSize];

      // accumulator
      size_t nVals = 0;
      int nAcc = 0;

      // timer
      __time64_t destTime;
      __time64_t destTime2;
      _time64(&destTime);

      while (true) {
                SleepEx(10, false); // care of 100% cpu core usage, poll serial port lazily
       size_t nBytesRead = serial.ReadData(lpBuffer, bufSize * sizeof(lpBuffer[0]));

       //parse buffer:
       size_t cvtPtr = 0;
       for (size_t i = 0; i < nBytesRead; ++i) {
        if (lpBuffer[i] == '\n') {
         try {
          lpBuffer[i] = '\0';
          auto val = std::stoi(lpBuffer + cvtPtr, nullptr, 16);
          nAcc += val;
          nVals++;
         }
         catch (...) {
          // ignore, or warn that serial recieved junk/empty packet
         }
         cvtPtr = i + 1;
        }
       }

       //check if doom had come!
       _time64(&destTime2);
       if ((destTime2 - destTime) > 0) {
        auto fVoltage = ( s2v(nAcc) / 32 ) / nVals;
        std::cout << fVoltage << "\t(" << nVals << " ksps)\n";
                    ofs << destTime << "," << fVoltage << "," << nVals << "\n";
        if((destTime % 30 ) == 0) // care of disk, write only once in 30 seconds
         ofs.flush();
        destTime = destTime2;
        nVals = 0;
        nAcc = 0;
       }
      } // while
     } // if opened
     return 0;
    }

That gives voltmeter with high precision, about ±0.5mV, that is updated every second.

Also! It was stated about 10bit adc, 5.0V/1024 = 4.88mV, but i got some subthreshold oscillations in vivo, adding samples up. So you are wrong, noise can be attenuated and resolution can be artificially pumbed up, in a trade for increased sampling time. Here is 14bit ADC built on top of 10bit ADC: [![enter image description here][1]][1]. Its photovoltaic cell in a dark street, oscillations are caused by cars' front lights. Timescale is 1000 seconds per grid div

  [1]: https://i.stack.imgur.com/WNaYa.png


body:
I Want to measure AC current with current transformer but i dont know exact value of burden resistor or calculation formula...i want to measure current of borewell pump. company specified pump as 1.5Hp power.

[![current transformer ][1]][1]

  [1]: https://i.stack.imgur.com/BOhB5.jpg

title: Calculate burden resistor value of current transformer and measure ac current with arduino

Answers: 1

body:
There is no "You need X resistor for Y transformer". The resistor you choose depends on what current range you are working with and what voltage range you want that to be expressed as.

That transformer is a 100:5 (or more properly a 20:1) ratio.  That means for every 20A going through it you get 1A out.

That output current is then passed through a burden resistor and you measure the voltage across that resistor.

If you are, for example, working with sensing up to 1A current then the maximum current you'd get out of it would be 1/20A, or 50mA.  If you want that to be expressed reliably within the range of a 5V ADC then you would:

1. Work from the mid-range of the ADC as 0V to give ±2.5V (assuming AC)
2. Calculate the resistor that gives 2.5V across it when 50mA is passed through it
3. Pick the next-lowest common resistor value.
4. Reverse the calculation to get the voltage range you now have.

In this example, R=V/I, so 2.5/0.05 = 50Ω.  50Ω resistors aren't common, but 47Ω ones are, so you'd pick that.

Then reversing it gives V=IR = 0.05 * 47 = ±2.35V

Give it a 2.5V offset to the ADC and you can now read points on a sinewave between 0.15V and 4.85V at 1A sensed current.


body:
I am executing a function in Arduino by giving String input to the serial monitor.

The issue here is when I enter `SHOW$`, the function `showData()` works but when I enter the same `SHOW$`, it doesn't gets called.
I want to call the function `showData()` every time i enter the `SHOW$` text into the serial console.

My question here is to what mistake I am doing here, and what is the solution for this.

    String strReq = "";
    char inChar = 0;

    void setup() {

      Serial.begin(9600);

    }

    void loop() {

      while (Serial.available())
      {
        inChar = Serial.read();

        if (inChar == '$') {

         Serial.println(" Received String :");
         Serial.print(strReq);

         if (strReq.equalsIgnoreCase("SHOW"))
           showData();

         Serial.flush();
         strReq = "";

        } else {

          strReq = strReq + inChar;
        }
      }
    }

    void showData() {
      Serial.print("Showing Information");
    }

title: Command through Serial monitor does not properly work in Arduino

Answers: 2

body:
The solution was to use String.trim() function.
Thanks guys for giving a quick reply on the question.

body:
The root of your problem seems to be not knowing what `Serial.flush()` does.

It pre-Arduino 1.0.0 times `Serial.flush()` used to clear any data in the serial's RX buffer. It would throw it away.  In your code that would throw away the line ending `\r\n` that is sent along with the command.

However in Arduino 1.0.0 it was changed to instead block execution until all bytes had been sent out of the Serial TX buffer.  This was deemed more useful, and a replacement to the original functionality is very easy to implement if needed.

This change was not widely documented, but it is mentioned in the manual:

> Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.)

So with `Serial.flush()` acting like it does in current versions, you would get a different string the second time around.  You would see:

    SHOW$
    \r\nSHOW$
    \r\nSHOW$

and so on.

You have come up with a "fix", which uses `String::trim()` to discard any leading and trailing non-printable characters, which removes the line-endings from your subsequent strings.  However it would be far better to ignore them in the first place and not need to do the trimming.

The simplest way would be to only add characters to your string if they are printable:

    if (inChar == '$') {
     Serial.println(" Received String :");
     Serial.print(strReq);
     if (strReq.equalsIgnoreCase("SHOW"))
       showData();
     Serial.flush();
     strReq = "";
    } else if (inChar >= ' ') { // << Only add if a space or above
      strReq = strReq + inChar;
    }

A simple change, but one which then means you're not having to add the extra processing of trimming unwanted characters from the string.


body:
hi does anyone know how to

1) set Max Brightness

2) change the start up splash screen from being white to black

3) how to change settings so that text can be mirrored so when display is reflected into mirror or glass window the text reflects onto the mirror / glass so that it is readable

The code from the sketch may answer some of your tecnical question re the environment i am working with

    #include <Adafruit_GFX.h>    // Core graphics library
    #include <Adafruit_TFTLCD.h> // Hardware-specific library

    #define LCD_CS A3 // Chip Select goes to Analog 3
    #define LCD_CD A2 // Command/Data goes to Analog 2
    #define LCD_WR A1 // LCD Write goes to Analog 1
    #define LCD_RD A0 // LCD Read goes to Analog 0

title: 2.8 inch tft LCD displays / Max Brightness / Startup White Screen / mirror text for Head Up Display Usage

Answers: 1

body:
> 1) set Max Brightness

You set the brightness of the backlight (usually) using PWM.

> 2) change the start up splash screen from being white to black

That's not a splash screen. That's just the back light being on before the screen is initialised. Just don't turn on the back light until you need it.

> 3) how to change settings so that text can be mirrored so when display is reflected into mirror or glass window the text reflects onto the mirror / glass so that it is readable

Either do it in software (tricky) or look at the MADCTL (many have it called that) register in the datasheet.  The library probably won't support it, but it's part of how it deals with display rotation, so you could examine that function and compare it with what's in the datasheet (hint: 180° rotation is actually flipping both the X and Y axis).


body:
I have an Arduino Mega 2560, an Omron Optical encoder with an Index (360 steps), a 60 led NeoPixel ring (no Clk wire) and another Arduino Uno.
Here is my question, I have some code written that works with the Arduino Mega and optical encoder outputting decently to the serial monitor for diagnostic purposes.
When I add the additional code to run the Neopixel ring I get a terrible response on the ring.  I have tried the NeoPixel and FastLED libraries with the same terrible success.  It even states in their documentation that they don't work well with interrupts.  I started thinking about sending the 3 digit output to a Direct Pin output from the Mega to be read by another Mega/Uno to run the Neopixel Ring and a 4x20 LCD screen. Does anyone else have any ideas on this.  Below is my code for the Mega and the Encoder.

        // Wiring connections for my encoder:
        // Brown : VCC = 5V
        // Blue + Shield : 0V = GND
        // Black : ENCODER0PINA, Pin 18
        // White : ENCODER0PINB, Pin 17
        // Orange : ENCODER0PINI, Pin 19

        #define ENCODER0PINA         18      // this pin needs to support interrupts
        #define ENCODER0PINB         17      // no interrupt required
        #define ENCODER0PINI         19      // this pin needs to support interrupts

        // variables modified by interrupt handler must be declared as volatile
        volatile long encoder0Position = 0;
        volatile long interruptsReceived = 0;
        volatile byte INTFLAG1 = 0;

        // track last position so we know whether it's worth printing new output
        long previousPosition = 0;

        void setup()
        {
          // inputs
          pinMode(ENCODER0PINA, INPUT);
          digitalWrite(ENCODER0PINA, HIGH);  // turn on pullup resistor
          pinMode(ENCODER0PINB, INPUT);
          digitalWrite(ENCODER0PINB, HIGH);  // turn on pullup resistor
          pinMode(ENCODER0PINI, INPUT);
          digitalWrite(ENCODER0PINI, HIGH);  // turn on pullup resistor

          // interrupts
          attachInterrupt(5, onInterrupt, RISING);  // encoder track A on interrupt 3 - pin 18
          attachInterrupt(4, onReset, RISING);  // encoder Index track on interrupt 4 - pin 19

          // enable diagnostic output
          Serial.begin (115200);
          Serial.println("Ready.");
        }

        void loop()
        {
          // only display position info if has changed
          if (encoder0Position != previousPosition )
          {
            Serial.println(encoder0Position, DEC);

            previousPosition = encoder0Position;
          }
        }

    // interrupt function needs to do as little as possible

    void onInterrupt()
    {
      // read both directional inputs
      int a = digitalRead(ENCODER0PINA);
      int b = digitalRead(ENCODER0PINB);

      if (a == b)
      {
        // b is leading a (counter-clockwise)
        encoder0Position--;
        if (encoder0Position < 0)
        {
          encoder0Position = ((encoder0Position + 360) % 360);
        }
      }
      else
      {
        // a is leading b (clockwise)
        encoder0Position++;
        if (encoder0Position >= 360)
        {
          encoder0Position = ((encoder0Position - 360) % 360);
        }
      }
    }

    void onReset()
    {
      // read Index input
      int i = digitalRead(ENCODER0PINI);
      if (i == 1)
        {
      encoder0Position = INTFLAG1;
        }
    }

title: Encoder code using interrupts design question

Answers: 0


body: Hi I am hoping to design a custom board ATMEGA32u4 with practically a Arduino leonardo bootloader. I plan to control up to 12 servos while being able to read back the current sensor voltage of an INA169 current sensor on voltage changes. The  voltage reading will be read back into a digital pin through an ADC controlled by a  multiplexer. The question is am I able to manage all the current sensing on all 12 servos properly with this setup? or should I use a faster controller that act as a master to do the data collection from the current sensor while the ATMEGA32u4 focus on controlling the servos? I plan to store this data too, so is this the right way of doing things?

title: Question about controlling servos with PWM while being able to accurately read the current from a sensor

Answers: 0


body:
For some reason I cannot establish serial connection between the two devices. The shield is connected to the network because my number can be called, but I cannot send it any commands via the serial.
I tried several ways to wire it up:
shield rx&tx (the ones that require female jumper) to 7 & 8 of arduino, declaring 7 & 8 in the serial.
shield pins 7 & 8 (they have (serial) as label) to 7 & 8 of arduino, declarting 7 & 8 in the serial.
shield rx&tx the little holes to 7 & 8 of arduino, declaring 7 & 8 in the serial.
Tried even different pins other than 7 & 8. None worked.
I'm powering the shield with 12v transformator that can provide up to 3Ah and the arduino is connected to laptop.
Any suggestions ?
Here's the code:

    #include <SoftwareSerial.h>

    //Create software serial object to communicate with SIM900
    SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8

    void setup()
    {
      //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
      Serial.begin(9600);

      //Begin serial communication with Arduino and SIM900
      mySerial.begin(9600);

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

      mySerial.println("AT"); //Handshaking with SIM900
      updateSerial();

      mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
      updateSerial();
      mySerial.println("AT+CMGS=\"+ZZxxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
      updateSerial();
      mySerial.print("Last Minute Engineers | lastminuteengineers.com"); //text content
      updateSerial();
      mySerial.write(26);
    }

    void loop()
    {
    }

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

And also, why are there so many RX/TX on the shield ? I see RXD/TXD and RX/TX.

title: SIM900/Arduino UNO R3 serial communication not working

Answers: 2

body:
> And also, why are there so many RX/TX on the shield ? I see RXD/TXD and RX/TX.

There aren't.  There is only one of each. They just have them in multiple convenient places.

J11 selects the pins to use on the shield. Make sure that is set to D7 and D8. You then use pins D7 and D8 on the shield. Normally that would be mounted directly onto an Arduino and you would just use those pins in your code.

However, if you want to attach it to something that doesn't have an Arduino UNO footprint you can solder wires to the TX/RX pins in the J10/J17 "UART" header. That ignores the J11 jumpers, which only pertain to using the Arduino UNO shield headers.

As to why you can't communicate, my guess is:

* You have 9600 baud in your code:

----
    mySerial.begin(9600);

However, on the Amazon product you linked to:

> The factory default setting for the GPRS Shield UART is 19200 bps 8-N-1. (Can be changed using AT commands).

Using 19200 instead of 9600 should improve matters somewhat.

body:
To make everything work fine with this exact code and wiring from the *[lastminuteengineers][1]*, you need to change the jumper (black plastic piece) position in J11. it has to connect the pins **D8(RX)** and **D7(TX)**, which are the pins at the top of the **yellow plate**, to the two pins in the middle of the **yellow plate**.

  [1]: https://lastminuteengineers.com/sim900-gsm-shield-arduino-tutorial/


body:
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.

title: RN4678 Bluetooth doesn't respond

Answers: 1

body: 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


body:
I am having trouble reading data from an MCP3424 chip, specifically the one from this website:

https://uk.rs-online.com/web/p/general-purpose-adcs/6696086/

I have a pressure transducer that connects to the MCP3424 chip. The chip is then connected to a NodeMCU 1.0. Schematics are attached.

The pressure transducer comes from here:

https://www.edwards.com/gb/devices/pressure-monitoring/transducer?WT.ac=eu_truwave

It is run into a 9-pin VGA adapter

I am new to this kind of stuff, and I do not know what code is needed on the NodeMCU to read the data coming in from the pressure transducer via the MCP3424 chip. My code currently contains code from here:

https://github.com/bersch/MCP3424

My code is set to upload the error message I am getting from the MCP3424 to a spreadsheet so I can read the error. The error I get is "i2c". I am not sure what that means. I have tried contacting the author of the code but I have not received a response in a few weeks. I simply want to read the pressure I am getting from the pressure transducer from the MCP3424 chip.

Some useful information about the MCP3424 chip can be found here:

http://ww1.microchip.com/downloads/en/DeviceDoc/22088b.pdf

If anyone can provide any guidance, code, or helpful advice, that would be extremely appreciated.

Link to my post on the arduino forum, which includes my code, is here:

https://forum.arduino.cc/index.php?topic=588831.0

Thank you.

title: Unsure how to get pressure data from MCP3424

Answers: 0


body:
Using code similar to these examples from AVR

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__sleep.html

my program causes my Adafruit Feather 32u4 to often sleep. When the firmware has nothing to do it will sleep about 75% of the time. Typically after several hours of operation there will be corruption on the LCD display. The elapsed time to the corruption is not deterministic.

When it sleeps or wakes up from sleep I believe the processor sends garbage to the LCD module via the SPI (serial) lines. I have no oscilloscope to observe this but the problem seems to be removed if I comment out the sleep code.

A description of the Adafruit ST7565 LCD module is at this link

https://www.adafruit.com/product/250.

My Arduino setup code relevant to sleeping is this:

    cli(); // atomic operation begins here
    WDTCSR = bit(WDCE) | bit(WDE); // enter a very brief change mode
    WDTCSR = bit(WDP2); // prescaler without reset mode, 1001 means 8 seconds, 0101 means 0.5 seconds, 0100 means 0.25 seconds, 0011 means 0.125 seconds
    WDTCSR = bit(WDIE); // use interrrupt mode because we do not want an WDT triggered reset
    sei(); // global interrupt enable
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

My sleep code in the Arduino loop is adapted from the AVR webpage and is invoked if the firmware is not busy, is as follows:

    cli(); // atomic operation begins here
    sleep_enable();
    sei();
    sleep_cpu();
    sleep_disable();

The watchdog ISR for when it wakes up is an empty function, as follows:

    ISR(WDT_vect) // need this to avoid a reset
    { // no code here
    }

I have a little bit of other evidence that some lines are uncontrolled when the processor wakes up. The evidence comes from my rotary encoders. I see false encoder activity sometimes when the processor wakes up and I eliminated this problem by putting some "debounce code" in the watchdog ISR. I also make sure the encoder lines use the processor's internal pull-up resistors. Note that I already have debounce code for the encoders for the purpose of doing actual debouncing of the activity of actually touching the encoders. The additional "debounce code" in the watchdog ISR is for the situation in which I am not even touching the encoders but the processor is waking up and the lines are noisy. The encoder "debounce code" is not shown in the watchdog ISR code snippet because it's not relevant to my LCD problem.

The pull-up and debounce remedy for encoder input lines is not applicable to my LCD problem because the LCD involves output lines.

Edit: I tried to solve it by setting high the active low chip select of the LCD before sleep and then reverting the line upon waking up (in the watchdog ISR). This had the effect of making the display very sluggish. I update the display once per second and it seemed to be updating only once every 2 or 3 seconds. I have not analyzed whether my "direct intervention" is incompatible with the Adafruit library for this LCD.

The LCD library: https://github.com/adafruit/ST7565-LCD

The boards are as pictured. The encoder board has 2 encoders wired up and 2 encoders unused. The encoder board sits on a 3mm thick piece of foam and is clamped to the desk. The breadboard is attached to the desk via the double sided foam tape that seems to be standard on this item.

[![picture][1]][1]
Addendum: Given Nick Gammon's answer, I will run with the following to see if the problem is eliminated. Since the corruption is not deterministic, it may take many hours or days before I form an opinion.

      cli(); // atomic operation begins here
      WDTCSR = bit(WDCE); // enter a brief change mode
      WDTCSR = bit(WDIE) | bit(WDP2); // 1001=8s, 0101=0.5s, 0100=0.25s, 0011=0.125s
      sei(); // global interrupt enable
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);

After less than 10 hours there was corruption on the LCD. I will test with the following.

      cli(); // atomic operation begins here
      WDTCSR = bit(WDCE) | bit(WDE); // enter a brief change mode
      WDTCSR = bit(WDIE) | bit(WDP2); // 1001=8s, 0101=0.5s, 0100=0.25s, 0011=0.125s
      sei(); // global interrupt enable
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);

The above still failed after several hours.

  [1]: https://i.stack.imgur.com/roVEQ.jpg

title: noisy output lines when waking up from a sleep

Answers: 1

body:
    WDTCSR = bit(WDCE) | bit(WDE); // enter a very brief change mode
    WDTCSR = bit(WDP2); // prescaler without reset mode, 1001 means 8 seconds, 0101 means 0.5 seconds, 0100 means 0.25 seconds, 0011 means 0.125 seconds
    WDTCSR = bit(WDIE); // use interrrupt mode because we do not want an WDT triggered reset

Your code above is not doing a WDT interrupt every 0.25 seconds as you appear to be wanting, because you assign (not OR) in the third line. That means WDP0/WDP1/WDP2?WDP3 will all be zero which means the watchdog will fire every 16 ms.

> This had the effect of making the display very sluggish.

I'm not totally surprised, if you interrupt every 16 ms.

---

> I have a little bit of other evidence that some lines are uncontrolled when the processor wakes up.

The lines should remain what they were set to when the processor sleeps. It wouldn't be very useful to sleep if the processor started outputting random junk while asleep. I can't comment further as I can only see part of your code.


body:
I've a json string request coming from server and I convert it into json object

      StaticJsonBuffer<500> jsonStaticBuffer;
      JsonObject& root = jsonStaticBuffer.parseObject(String(msg));
      String reqId;
      String reqData;
      root["requestid"].printTo(reqId);
      root["data"].printTo(reqData);

I need to populate another char json string initiated at the beginning

    const char response[] = "{\"response\": {\"requestid\":, \"data\":}}";

such that I need to write `requestid` into the `response::requestid` and `data` `into response::data + ACK/NAK` . here is how i've tried;

      DynamicJsonBuffer jsonDynResponse;
      JsonObject& jsonResponse = jsonDynResponse.parseObject(response);
      String out;
      if (ACK) {
          jsonResponse["response"]["requestid"] = root["requestid"];
          jsonResponse["response"]["data"] = root["data"] + " ACK"; //THIS DOESN'T WORKS
          jsonResponse.printTo(out);
      } else {
          jsonResponse["response"]["requestid"] = reqId;
          jsonResponse["response"]["data"] = reqData + " NAK";
          jsonResponse.printTo(out);
      }

  I know this will definitely not work `root["data"] + " ACK"` because we can't combine const char with String. But this `reqData + " NAK"; ` resulted in `"\"data\" NAK""`. How can I concate root["data"] into another String ?
Thank you in advance :)

title: append a String on ArduinoJson Object value

Answers: 0


body:
I have the following code to write data on MAX7219 for light up a 8x8 LED Matrix:

    for (i = 0; i < 8; i++)
    {
        CLK = LOW;
        DIN = temp & MSBIT >> i;
        CLK = HIGH;
    }

The thing is, sadly, I just know that the code line `(DIN = temp & MSBIT >> i;)`, must be exactly like that, otherwise the LED´s won't show the expected, but I don't understand how it works...

Please, I really need explanation because I'm stuck....

Note: variable "temp" is always a hexadecimal number like `0x20`, and `"MSBIT" = 0x80`.

title: Upload data to MAX 7219

Answers: 1

body:
You have to send 16 bits to load data.  The first 8 are the register the data goes into, 0 to 15, the next 8 are the data to be displayed. Registers 1-8 are the data that gets displayed, the others are used to set up: intensity, display test, normal/shutdow, decode/no decode mode, and number of digits/columns connected (such as 4 digits, or 8 for an 8x8 matrix).

In Arduino, I use hardware SPI to send data to MAX7219 - SCK, MOSI, and SS.

    digitalWrite (ssPin, LOW);
    SPI.transfer(addressRegister); // 0 to 15
    SPI.transfer(dataToLoad);
    digitalWrite (ssPin, HIGH);

Do that for each register. The control registers only need to be written once. In Arduino, that is usually in setup().  Intensity might be changed later for brightness (0 to 15 as valid data).

In loop(), use the above to update your display for the 8 display data registers (1-8).


body:
    #include "_ffmc16.h"
    #include "extern.h"
    #include "monitor.h"

    void initLCD();
    void delay();
    void instCtrl4(unsigned char data);
    void display(unsigned char temp);
    void display1(unsigned char pulse, int counter);
    void decoder(int newtemp);
    void instCtrl(unsigned char data);
    void dataCtrl(char data);

    #define RS IO_PDR2.bit.P24
    #define RW IO_PDR5.bit.P53
    #define E IO_PDR5.bit.P52
    #define LCD IO_PDR2.byte
    #define BUZZER IO_PPGC23.bit.PEN1

    unsigned char AD_DATA, temperature, bpm;
    int count = 0, counter=0;
    int UpperThreshold = 518;
    int LowerThreshold = 490;
    int IgnoreReading = 0;
    int FirstPulseDetected = 0;
        unsigned char FirstPulseTime = 0;
        unsigned char SecondPulseTime = 0;
        unsigned char PulseInterval = 0;
        unsigned char BPMResult;

    void main()
    {
     __set_il(7);
     __EI();

     IO_DDR2.byte = 0x1F;
     IO_DDR5.bit.D53 = 1;
     IO_DDR5.bit.D52 = 1;

     IO_ADER.bit.ADE3 = 0;
     IO_ADER.bit.ADE2 = 0;

     //BUZZER
     IO_PPGC23.bit.PE1=0x01;
     IO_PPG23.byte=0x00;
     IO_PRL23.byte.PRLL3=0xFA;
     IO_PRL23.byte.PRLH3=0xFA;

     initLCD();
     instCtrl(0x84);
     dataCtrl('T');
     dataCtrl('E');
     dataCtrl('M');
     dataCtrl('P');
     dataCtrl('E');
     dataCtrl('R');
     dataCtrl('A');
     dataCtrl('T');
     dataCtrl('U');
     dataCtrl('R');
     dataCtrl('E');
     dataCtrl(':');

     instCtrl(0x99);
     dataCtrl('P');
     dataCtrl('U');
     dataCtrl('L');
     dataCtrl('S');
     dataCtrl('E');
     dataCtrl('R');
     dataCtrl('A');
     dataCtrl('T');
     dataCtrl('E');
     dataCtrl(':');

     while(1)
     {
     counter++;

     IO_DDR5.bit.D55 = 0; /* PORT5 DDR set(AD1) */
     IO_ICR03.byte = 0x00; /* A/D INT level set */
     IO_ADCSH.bit.BUSY = 0; /* ADC stop */
     IO_ADER.byte = 0x02; /* ADC input enable, ch-1 */
     IO_ADCSL.byte = 0xAD; /* ADC mode set */
     IO_ADCRLH.byte.ADCRH = 0xF8; /* set 8bit-AD, comp.176cycle, sample.128cycle */
     IO_ADCSH.bit.INTE = 1; /* interrupt enable */
     IO_ADCSH.bit.STRT = 1; /* start ADC */

      display(AD_DATA);

      /*if(temperature>38)
      {
       BUZZER=0x01;
      }
      else if(temperature<34)
      {
       BUZZER=0x01;
      }
      else
      {
       BUZZER=0x00;
      }*/

     IO_DDR5.bit.D54 = 0; /* PORT5 DDR set(AD1) */
     IO_ICR03.byte = 0x06; /* A/D INT level set */
     IO_ADCSH.bit.BUSY = 0; /* ADC stop */
     IO_ADER.byte = 0x10; /* ADC input enable, ch-1 */
     IO_ADCSL.byte = 0xA4; /* ADC mode set */
     IO_ADCRLH.byte.ADCRH = 0xF8; /* set 8bit-AD, comp.176cycle, sample.128cycle */
     IO_ADCSH.bit.INTE = 1; /* interrupt enable */
     IO_ADCSH.bit.STRT = 1; /* start ADC */
      display1(AD_DATA, counter);
     }
    }

    void delay()
    {
     for(count=0; count<1000;count++)
     {
     }
    }

    void initLCD()
    {
     delay();
     instCtrl4(0x03);
     delay();
     instCtrl4(0x03);
     delay();
     instCtrl4(0x03);
     delay();
     instCtrl4(0x02);
     delay();
     instCtrl(0x28);
     instCtrl(0x08); //off
     instCtrl(0x01); //clear
     instCtrl(0x06); //entry mode: increment or shift mode
     instCtrl(0x0C); //display on; cursor on;blink on
     instCtrl(0x01);
    }

    void instCtrl4(unsigned char data)
    {
     LCD = data;
     RS = 0;
     RW = 0;
     E =1;
     delay();
     E =0;
    }

    void display(unsigned char temp)
    {
     temperature = (temp * 500) / 255;
     instCtrl(0xC8);
     decoder((temperature/10));
     decoder(temperature);
     dataCtrl(0xDF);
     dataCtrl('C');
    }

    void display1(unsigned char pulse, int counter)
    {

     /*if(pulse > UpperThreshold && IgnoreReading == 0)
     {
            if(FirstPulseDetected == 0)
            {
              FirstPulseTime = counter;
              FirstPulseDetected = 1;
            }
            else
            {
              SecondPulseTime = counter;
              PulseInterval = SecondPulseTime - FirstPulseTime;
              FirstPulseTime = SecondPulseTime;
            }
            IgnoreReading = 1;
          }

          // Heart beat trailing edge detected.
          if(pulse < LowerThreshold)
          {
            IgnoreReading = 0;
          }

          BPMResult = (1 / PulseInterval) * (60000);*/

          //bpm= pulse; /* default n ??*/

     instCtrl(0xD9);
     decoder((BPMResult/100));
     decoder((BPMResult/10));
     decoder(BPMResult);
     dataCtrl('B');
     dataCtrl('P');
     dataCtrl('M');
    }

    void decoder(int newtemp)
    {
     switch(newtemp)
     {
      case 0:
       dataCtrl('0');
       break;
      case 1:
       dataCtrl('1');
       break;
      case 2:
       dataCtrl('2');
       break;
      case 3:
       dataCtrl('3');
       break;
      case 4:
       dataCtrl('4');
       break;
      case 5:
       dataCtrl('5');
       break;
      case 6:
       dataCtrl('6');
       break;
      case 7:
       dataCtrl('7');
       break;
      case 8:
       dataCtrl('8');
       break;
      case 9:
       dataCtrl('9');
       break;
     }
    }

    void instCtrl(unsigned char data)
    {
     LCD=data>>4;
     RS =0;
     RW=0;
     E=1;
     delay();
     E=0;
     LCD=data;
     RS=0;
     E=1;
     delay();
     E=0;
    }

    void dataCtrl(char data)
    {
     LCD=data>>4;
     RS=1;
     RW=0;
     E=1;
     delay();
     E=0;
     LCD=data;
     RS=1;
     E=1;
     delay();
     E=0;
    }

    __interrupt void ADC_int(void)
    {
     IO_ADCSH.bit.INT = 0;  //interrupt flag clear
     AD_DATA = IO_ADCRLH.DATA8; //A/D conversion interrupt vector
    }

    /* Vector Table */
    #pragma section INTVECT, locate=0xfffc00
    #pragma intvect _start  0x8  0x0 /* Reset Vector */
    #pragma intvect ADC_int  18  /* AD converter vector */

title: Fujitsu FMC-16LX(MB90F387) Pulse Sensor BPM formula displaying only 96BPM

Answers: 0


body:
I am trying to setup my first relay module with live environment. I have attached the relay module image below.

[![enter image description here][1]][1]

Which I am using to control 4 devices in my switch board as follows:

 1. Fan (working fine),
 2. 6w celling LED panel (2 connected in series) (Working fine)
 3. 15w celling LED panel (2 connected in series) (Sometimes work sometimes don't)
 4. Spotlights 3 lights in series and some LED strips connected to it (Sometimes works sometimes don't.).

I have cut one wire which is connected to main normal mechanical switch WHICH IS NOT A HOT WIRE its just the another wire connected to the button.

But I am not sure why its not working? Do I need to connect neutral to the another end of the relay. As I have only 2 wires connected to the relay for each of the switches. Here is a screenshot of specifications 15watt LED panel which is connected to my house, if this can help to understand better.

[![enter image description here][2]][2]

If I connect Neutral on the first pin of relay and when I close the relay switch, do the current will go into the neutral wire as well?

If I keep my 3w spotlights ON or more then 3-4 hours and try to close the relay on connected to it. The relay LED light for that connected relay goes OFF but the light don't. Seems like the mechanical relay is not getting enough power to move the mechanical relay off.

I want to know why this is happening? And how can I solve this issue? Attaching a neutral (earth) wire will help to reduce this? But if connect neutral to first (off side of relay) pin, then will get the current?

Any suggestions will be helpful. Also I added 3.3v from NodeMCU to VCC (instead of jumper) pin. But that is also not helpful.

  [1]: https://i.stack.imgur.com/vA0Pq.jpg
  [2]: https://i.stack.imgur.com/tReNp.jpg

title: 5V 10A 4 channel relay to 2 lights15W light in series in 220V AC supply

Answers: 1

body:
You need to connect Vin from NodeMCU (Raw 5V from USB) to Vcc on the relay board.

And as stated in the comments, the relay need 5V for operating reliable.

In has the same problem, two LEDs and a resistor. To enhance it would be to replace the indicator LED (DS1-4) with a wire.

2 x LEDS á ~1.8V and a resistor á ~1.4V = 5 Volt.

1 x LED á ~1.8V and a resistor á ~1.4V = 3.2 Volt.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/14WTN.jpg


body:
We had used a voltage sensor unit to measure the voltage of the odroid board using an Arduino Uno. wWhen I uploaded the sketch and got the output, the value which was being displayed was around 4.7 to 4.9V, but when I measured the top of the voltage sensor module using a multimeter, it had a stable voltage of 5.08V. Is their any particular reason why this is happening?

[Voltage sensor module][1]

  [1]: https://www.google.com/search?q=voltage sensor module&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjX58W-0-DfAhXJPo8KHaH9CV4Q_AUIDigB&biw=1920&bih=928#imgrc=FeDCSiiT_1sBYM:

    int analogInput = A0;
    float vout = 0.0;
    float vin = 0.0;
    float R1 = 30000.0;
    float R2 = 7500.0;
    int value = 0;
    void setup() {
    pinMode(analogInput, INPUT);
      Serial.begin(9600);
      Serial.print("DC VOLTMETER");
    }
    void loop() {
      // read the value at analog input
    value = analogRead(analogInput);
    vout = (value * 5.0) / 1024.0;
    vin = vout / (R2 / (R1 + R2));
    Serial.print("INPUT V= ");
    Serial.println(vin, 2);
    delay(500);
    }

title: Voltage sensor Calibration

Answers: 1

body:
Multimeters are designed to provide a stable response. It would be averaging the readings.

As far as the difference in voltage reading, if you are using the Arduino board as is the default is to assume a reference voltage for the A/D as being 5.0 volts.(for your calculations) That may not be the case. Also there may be a tolerance issue on the measurement board, but I think the reference for the A/D on the Arduino is the bigger issue.


body:
I am working on this tutorial,

https://www.hackster.io/SURYATEJA/morse-code-communication-using-laser-module-both-ea1b01

and the author created a "Send" and "Receive" code for encoding and decoding Morse code. He created the "Send" code with the entire alphabet A-Z, but his receive code only has 9 letters.

I thought I could easily add in the missing characters, and even add in numbers, but I am stuck.

His code has 2 values to decode the morse - "a" and "f"

In his receive code he has a value "f" that is supposed to be calculated by the number of spaces, but I cannot see how he comes up with his result.

For example, this is his sending code for "a"

        case 'a':
    MorseDot();
    LightsOff(elemPause);
    MorseDash();
    LightsOff(elemPause);
    break;

Then this is the receive code;

    if(a==4 && f==10) {   Serial.print("a");

I understand the value of 4 for "a", but I cannot understand the value of 10 for "f"

"a" is calculated by assigning a value of 1 for a dot and 3 for a dash and adding the values (in this case one dot and one dash, 1+3 = 4)

He explains how to calculate "f" here in his tutorial, but I still don't understand.

2. When the LASER falls on the LDR, the value goes beyond 1000, and then it will enter into a loop.

3. Now quantize the values i.e. if the value goes beyond 1000, then assign it as '1', otherwise assign it as '0'.

4. Inside a loop, calculate the number of '1's and '0's. Set the counters 'a' and 'f'. Count the number of '1's and store it in 'a' and similarly count the number of '0's and store it in 'f' respectively.

5. Now check the specific values of 'a' and 'f' respectively. Each character will have different set of 'a' and 'f'. The matching value will be displayed.

That seems to indicate;
Laser on = Over 1000 = 1
Laser off = Under 1000 = 0

So for the letter a, I only see 2 times the laser goes off, not 10.Minof formatting changes

title: Question on how "f" value is calculated in converting Morse Code to laser audio from this tutorial

Answers: 1

body:
This is not a good tutorial. The receiver works by assuming 14 `dotLen` time periods for each character. There is a loop that runs 14 times, with a 200ms delay between each iteration. If the laser is detected, then `a` is incremented, otherwise `f` is incremented. This means that the sum of `a` and `f` is always 14, and the case where `a==0` means nothing was transmitted. The incomplete receiver code shows only 10 options for received characters and leaves out `a==5` (which would be `R` or `U`), but does define 1 through 10 otherwise.

The receiver code does not differentiate between dots and dashes, it only counts the number of `dotLen` transitions where light is detected. This is not Morse Code.

The receiver code cannot distinguish between `S` (dot-dot-dot) and `T` (dash) because they both have 3 `dotLen` value. Same for `A` (dot-dash) vs. `N` (dash-dot).

If you want to understand decoding morse code, this is not a good tutorial to follow. It does not decode morse code, and I cannot see how it would work even with it's companion transmitter program.


body:
I've got an Adafruit Bluefruit NRF52 hooked up to the Adafruit BNO055 9-axis orientation sensor, but when I use Serial.write to send the data, serial monitor displays blank values only. The scroll bar drops so something I definitely appearing, it just seems to be empty.

Serial.print works fine, but I cannot use this for my application, as it uses too much memory.

I'm gathering 3 axis of absolute orientation plus 3 axis of acceleration (6 floats in total) plus a three digit number representing the calibration of each sensor.

Each line should look something like

    303 68.69   4.19    -2.19   -0.12   0.14    -0.40

My code:

    void displayCalStatus(void)
    {

      uint8_t system, gyro, accel, mag;
      system = gyro = accel = mag = 0;
      bno.getCalibration(&system, &gyro, &accel, &mag);

      /* Display the individual values */
      Serial.write(gyro);
      Serial.write(accel);
      Serial.write(mag);
      Serial.write("\t");
    }

    void loop()
    {
      imu::Vector<3> accel = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);

      /* Get a new sensor event */
      sensors_event_t event;
      bno.getEvent(&event);

      displayCalStatus();

      /* Display the floating point data */
      Serial.write(event.orientation.x);
      Serial.write("\t");
      Serial.write(event.orientation.y);
      Serial.write("\t");
      Serial.write(event.orientation.z);
      Serial.write("\t");

        /* Display the floating point data for Linear Acceleration */
      Serial.write(accel.x());
      Serial.write("\t");
      Serial.write(accel.y());
      Serial.write("\t");
      Serial.write(accel.z());
      Serial.write("\n");
    }

title: Serial.write printing blank values

Answers: 1

body:
**Problem 1:**

You wish to send/display on the *Serial Monitor* the `int` and `float` values generated by your sensor, but `Serial.print()` uses too much memory.

**Solution 1:**

Optimize your sketch to use less memory.

----------

**Problem 2:**

`Serial.write()` doesn't cause the values to show up on Serial Monitor, but *something* is getting sent, because I see scrolling activity.

**Solution 2:**

`Serial.write()` sends raw bytes, whereas `Serial.print()` converts a variable to a string (or series of ASCII bytes) and sends that string. For example, `Serial.write(65)` sends `A` to the Serial Monitor because the ASCII value of `A` is `65`; `Serial.print(65)` sends `65` to the Serial Monitor because it converts the numeric value `65` into a string containing the character `6` and the character `5`, and sends that string to Serial Monitor.

The Serial Monitor expects only ASCII data. You are using Serial Monitor for development/debugging, but your final application does not require ASCII, only to transmit the numbers.

`Serial.write()` comes in a few forms. One is `Serial.write(val)` which sends a single byte (named `val`, of type `byte` or compatible). Another is `Serial.write(buf, len)` which sends a series of `len` bytes, starting at the address of memory pointed by by `buf`. (This is often when `buf` is an array of bytes, so `buf` points to the first element of the array.)

If you wanted to send the 4 bytes of a `float` using `Serial.write()`, you could call:

    Serial.write(&(event.orientation.x), sizeof(event.orientation.x);

As an alternative, you can use *bit shifting* to send one byte at a time of the 4-byte float:

    Serial.write((byte)((event.orientation.x & 0xFF000000) >> 24);
    Serial.write((byte)((event.orientation.x & 0x00FF0000) >> 16);
    Serial.write((byte)((event.orientation.x & 0x0000FF00) >>  8);
    Serial.write((byte)((event.orientation.x & 0x000000FF)      );

On the receiving end, you need to reconstruct your float by doing the reverse.

But you have multiple 4-byte values to send, in rapid repeating loop, so what happens if your receiver and transmitter get out of sync? Then you might want to put in a "flag" value to indicate the start of a sequence of data and a different flag for the stop of a sequence of data. What happens if your start or stop "flag" value actually shows up as one of the bytes you send as part of a real data byte? Then you need to find some way to modify the "real" data so that it's not to be construed as a flag.

This looks to be getting complicated now? Fortunately, these problems have existed and been solved for decades. Unfortunately, there is no consensus on the best or right way.

I did a quick search and found this arduino library that facilitates packet-based serial communication:

https://github.com/bakercp/PacketSerial

Perhaps that can help you take a bundle of numbers and send them reliably to some other system. I don't know that library in particular, and there are probably others that do something similar. This one claims to be compatible with the PySerial, COBS, and SLIP modules for dealing with packetized serial data communications.


body:
I have faced this problem for few years ago and I solved it on Ubuntu 14.04 but I don't know why my solution doesn't work right now on Ubuntu 16.04

The Error :

> avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied

I'm using the same solution from [The guide][1]

Here what I've done :

> ls -l /dev/ttyACM*
>
 from the result : The owner is "root" and the group with access is " dialout

Then I applied

sudo usermod -a -G dialout UserName

sudo chmod a+rw /dev/ttyACM0
 Finally logged out and logged in .

After all should be worked but  I still have the same Error , it doesn't work at all , I removed the software and re-installed it didn't work as well

  [1]: http://www.arduino.cc/en/Guide/Troubleshooting#upload

title: Uploading my code gets an error : permission denied on Ubuntu 16.04

Answers: 0


body:
I have a very simple code of door sensor (magnetic) which gives results in 1 & 0 format. But I want to run the NodeMCU only when a door is open or close. Rest of time I want to keep it in deep sleep mode. Here is my code looks like :

    int doorClosed = 1;

    #define REED_SWITCH D5

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

      Serial.begin(115200);
      pinMode(BUILTIN_LED, OUTPUT);
      digitalWrite(BUILTIN_LED, HIGH);

      pinMode(REED_SWITCH, INPUT_PULLUP);
    }

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

       Serial.println(digitalRead(REED_SWITCH));

        if ((digitalRead(REED_SWITCH) == HIGH) && (doorClosed == 1))
        {
          Serial.println("DOOR OPEN!!");
          doorClosed = 0;
          digitalWrite(BUILTIN_LED, LOW);
          ESP.deepSleep(0);
        }
        else if ((digitalRead(REED_SWITCH) == LOW) && (doorClosed == 0))
        {
          Serial.println("DOOR CLOSED!!");
          doorClosed = 1;
          digitalWrite(BUILTIN_LED, HIGH);
          ESP.deepSleep(0);
        }
        delay(500);
    }

Here I am able to put the NodeMCU in deep sleep. But it never wakes up. How can I wake up my chip. After attaching the D0 with RST, I don't event get Serial Logs. I am not sure what kind of behaviour is this. If someone can help me to fix this code will be great!

Thank you!

title: Deep Sleep NodeMCU with Door Sensor

Answers: 2

body:
According to this [guide][1]:

> The RST pin of the ESP8266 is always HIGH while the ESP8266 is
> running. However, when the RST pin receives a LOW signal, it restarts
> the microcontroller.
>
> If you set a **Deep Sleep timer** with the ESP8266, once the timer ends,
> GPIO 16 sends a LOW signal. That means that GPIO 16 when connected to
> RST pin can wake up the ESP8266 every time the timer ends.

The only way to wakes up ESP8266 from deep sleep mode **without timer** is set a LOW signal on RST pin.

Example without timer:

    ESP.deepSleep(0);

Connect D0 (GPIO 16) to RST is available only when ESP8266 is in sleep mode **with timer**.

Example with 30sec timer:

    ESP.deepSleep(30e6);

In your case, you can use deep sleep with timer and connect Door sensor to D0 and will act as switch between the RST and D0.

  [1]: https://randomnerdtutorials.com/esp8266-deep-sleep-with-arduino-ide/

body:
My response is late but herewith my experience that may be of help to others.

NodeMcu in deep sleep will wake-up from external source on receiving a pulse from high to low on the RST pin.

An ADXL345 accelerometer raises an interrupt HIGH on sensing motion and remains high until (I2C) READ to prevent multiple devices from interfering with each other

The following post was instrumental in my finding a solution

https://electronics.stackexchange.com/questions/158015/how-to-turn-continuous-signal-into-a-short-pulse-using-logic-gates


body:
Should this code pulse the PB3 and PB4 pins (MOSI and MISO of an Arduino Uno) at 2ms interval ?

    #include <avr/io.h>

    int main(void)
    {

    //  for (byte i = 0; i < 32; i++)
    //    pinMode(i, INPUT);

      DDRB |= (1 << PB4);
      DDRB |= (1 << PB3);
    //  pinMode(PB4, OUTPUT);
      while (1)
      {
        PORTB &= ~(1 << PB4);
        PORTB &= ~(1 << PB3);
      //  digitalWrite(PB4, LOW);
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //      __asm__ __volatile__("nop");
    //    delayMicroseconds(10000);
        delay(1);
        PORTB |= (1 << PB4);
        PORTB |= (1 << PB3);
      //  digitalWrite(PB4, LOW);
    //    delayMicroseconds(10000);
        delay(1);

      }
    }

If used for SPI MOSI can do 1 MHz just fine - so my logic analyzer says. MISO would not behave when used by SPI. MISO works in other non-SPI scenario: I am able to use the Arduino for in-system programming other AVR boards.

But the code above pulses neither MISO nor MOSI, as pointed out by the same logic analyzer in the same setup. Should it?

**update**

There has been some issue with the board. Changed it and all works fine now, regardless of using `int main()` alone or also calling `init()` as per @Majenko 's answer

title: Lines not pulsed fast enough (?))

Answers: 1

body:
The code *content* works fine while compiled as an Arduino program - that is, using the proper `setup()` and `loop()` structure:

    void setup() {
        DDRB |= (1 << PB4);
        DDRB |= (1 << PB3);
        while (1) {
            PORTB &= ~(1 << PB4);
            PORTB &= ~(1 << PB3);
            delay(1);
            PORTB |= (1 << PB4);
            PORTB |= (1 << PB3);
            delay(1);
        }
    }

    void loop() {
    }

However the same code will *not* work when using it in `main()`. This is simply because `delay()` will never work. Normally `main()` calls `init()` which then configures TIMER0 to generate the `millis()` and `micros()` count used for the `delay()` functions.

So either use `setup()` and `loop()` instead of `main()`, or make your program call `init()` before anything else:

    int main() {

     init();

        DDRB |= (1 << PB4);
        DDRB |= (1 << PB3);
        while (1) {
            PORTB &= ~(1 << PB4);
            PORTB &= ~(1 << PB3);
            delay(1);
            PORTB |= (1 << PB4);
            PORTB |= (1 << PB3);
            delay(1);
        }
        return 0;
    }


body:
This code keeps on returning 'S' with the Serial.read().

    #include <Servo.h>
    #define trig 10
    #define echo 9
    int pinMotorRN=3;
    int pinMotorRP=4;
    int pinMotorLN=5;
    int pinMotorLP=6;
    long distance;
    long duration;
    Servo myservo;
    void setup() {
      pinMode(pinMotorRP, OUTPUT);
      pinMode(pinMotorRN, OUTPUT);
      pinMode(pinMotorLP, OUTPUT);
      pinMode(pinMotorLN, OUTPUT);
      Serial.begin(9600);
      pinMode(trig, OUTPUT);
      pinMode(echo, INPUT);
      myservo.attach(8);
    }
    void loop() {
      Lid();
      while(Serial.available() == 0);
      char val = Serial.read() ;//reads the signal
      delay(1);
      Serial.println(val);
      if(val == 'F'){
        Forward();
      }
      else if(val == 'B'){
        Backward();
      }
      else if(val == 'R'){
        Left();
      }
      else if(val == 'L'){
         Right();
      }
      else
        Stop();
    }
    void Stop()
    {
      digitalWrite(pinMotorRP, HIGH);
      digitalWrite(pinMotorRN, HIGH);
      digitalWrite(pinMotorLP, HIGH);
      digitalWrite(pinMotorLN, HIGH);
    }
    void Backward()
    {
      digitalWrite(pinMotorRP, HIGH);
      digitalWrite(pinMotorRN, LOW);
      digitalWrite(pinMotorLP, HIGH);
      digitalWrite(pinMotorLN, LOW);
    }
    void Right()
    {
      digitalWrite(pinMotorRP, HIGH);
      digitalWrite(pinMotorRN, LOW);
      digitalWrite(pinMotorLP, LOW);
      digitalWrite(pinMotorLN, HIGH);
    }
    void Left()
    {
      digitalWrite(pinMotorRP, LOW);
      digitalWrite(pinMotorRN, HIGH);
      digitalWrite(pinMotorLP, HIGH);
      digitalWrite(pinMotorLN, LOW);
    }
    void Forward()
    {
      digitalWrite(pinMotorRP, LOW);
      digitalWrite(pinMotorRN, HIGH);
      digitalWrite(pinMotorLP, LOW);
      digitalWrite(pinMotorLN, HIGH);
    }
    void Lid(){
      digitalWrite(trig, LOW);
      delayMicroseconds(2);
      digitalWrite(trig, HIGH);
      delayMicroseconds(10);
      digitalWrite(trig, LOW);
      duration = pulseIn(echo, HIGH);
      distance = duration*0.034/2;
      distance = 11;
      if(distance <= 10){
        myservo.write(180);
        delay(2000);
      }
      else
        myservo.write(0);
    }

title: Serial.read() keeps returning the same value over and over

Answers: 0


body:
Here is modified version of Blink example

    #define D8  13

    String p = "D8";

    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(D8, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
      byte pin[2];
      p.getBytes(pin, sizeof(pin));

      digitalWrite(D8, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(D8, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a second
    }

D8 defined above is a byte of length 2. So LED turns on/off if I mention D8 on digitalWrite(D8, HIGH). Similarly I am getting the same byte D8 from `String p = "D8"`, and converting it into byte of length 2, but assigning `pin` to digitalWrite(pin, HIGH/LOW) doesn't works. Has anyone tried something similar before ? any help would be appreciated :)

title: Assign and control Digital pin from String

Answers: 1

body:
C and C++ programs get compiled in multiple passes through various programs/steps. One of the first is the *C Preprocessor*, which handles the `#define` *preprocessor directive*.

It's basically a big find/replace function. After the preprocessor is done, anywhere you had `D8` outside of a string literal, would have the value `13`. It's not a variable or a string -- it's simply the number 13.

But the `String` `p`, which has content `"D8"` doesn't get replaced by the `#define` directive because it's part of a string, and the preprocessor doesn't modify strings in that way.

Also, `p` converted to a `byte` array of length 2 does not have anything like `13` as the value. It has `0x44` and `0x38` (or, in decimal, `68` (ASCII `'D'`) and `56` (ASCII `'8'`)). Disregarding that `digitalWrite()` and `pinMode()` do not accept byte arrays, only bytes, you are passing in a byte that doesn't represent pin 13.

If you want to assign the pin via a string, then you would need to use programming to examine the string and pick the right byte value, and each possible value would have to be explicitly enumerated and checked for.


body:
I have an ESP12F WiFi module and I need it to work in access point mode. I burned the example code to it using Arduino IDE and it worked at first. I could connect to the WiFi provided by it using my laptop. But when I removed it from power and connected it again it was not working. I couldn't even see its hotspot in my laptop WiFi. What happened to it? Can you please help trouble shoot it?

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #ifndef APSSID
    #define APSSID "ESPap"
    #define APPSK  "thereisnospoon"
    #endif
    const char *ssid = "ESPap";
    const char *password = "thereisnospoon";

    ESP8266WebServer server(80);

    void handleRoot() {
    server.send(200, "text/html", "
You are connected
");
    }

    void setup() {
    delay(1000);
    Serial.begin(115200);
    Serial.println();
    Serial.print("Configuring access point...");

    WiFi.softAP(ssid, password);

    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    server.on("/", handleRoot);
    server.begin();
    Serial.println("HTTP server started");
    }

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

title: ESP12F module not working as an access point

Answers: 0


body:
I'm writing a library for a project i created, but it depends on the Neopixel library from adafruit. I want to remove this dependency and have my library be a stand-alone library.

Is there a way to run a ws2811 chip without the neopixel or similar library?

title: How do you remove dependencies from a library?

Answers: 1

body:
The [Adafruit Neopixel library][1] is licensed under GPL v3. You can fork a copy of this library into your own code and modify it to suit your own requirements, but if you distribute your code, your compiled project, or a product containing the library or any portion of it, you must ensure you follow the rules of the license by which the library is governed. Those terms of license may include release of the source code if you use any portion of the licensed library in a product. Opinions differ on the exact meaning of GPL v3 with libraries.

You should be able to copy the library into your own codebase and strip out the color-specific routines, put in your own application-specific data-setting routines, but use the same underlying protocol implementation.

  [1]: https://github.com/adafruit/Adafruit_NeoPixel