body:
I have a project with Arduino working as I2C slave.
The master request data each 300ms.

The code of Arduino is:

    /*
      Name:  SimpleClass_Applcation.ino
      Created: 5/26/2017 4:18:28 PM
      Author: Felipe Fonseca
      Description: Versão de Código para o Trocador de Calor de forma a simplificar
      a operçãoo para tornar possível a utilização em aulas
    */

    //includes

    //Libs dos sensores
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <Ultrasonic.h>

    //display lcd
    #include <LiquidCrystal.h>

    //timed action
    //#include <Utility.h>
    //#include <TimedAction.h>

    //lib i2c
    #include <Wire.h>

    //gerar sinais
    #include <waveforms.h>

    //Pinos de entrada e sa�da

    #define but1 A1  //no programa de testes 42; no original, trocar por A1  //
    #define but2 A2  //no programa de testes 44; no original trocar por A2
    #define pot A0 //no programa de testes A7; no original trocar por A0

    #define mode_switch 42  //no programa de testes 43; no original trocar por 42
    #define emergency_button 43 //no programa de testes 51; no original  trocar por 43

    #define ultrassonico_echo 50      //no original trocar para 50
    #define ultrassonico_trigger 48     //no original trocar para 48
    #define ONE_WIRE_BUS 52             //no original trocar para 52  - terminal do conjunto de sensores
    #define hf_sensor 9                //no original trocar para 9 -> pino de interrup��o para calculo da vaz�o agua fria
    #define TEMPERATURE_PRECISION 12

    #define led1 44                  // utilizado para sinalização geral
    #define led2 45                  // utilizado para sinalização geral
    #define led_heater 47            // no programa de testes 37; no original trocar para 47

    #define inversor_rele 49        //no programa de teste 47;no original trocar para 49
    #define heater_rele 10          //no programa de testes 49;no original trocar para 10

    #define MAX_MENU_ITENS 2         //numero de telas no menu

    //testes em prototipo
    #define LDR_PIN A3
    #define LM35_PIN A4
    #define RXLED 3
    #define oneHzSample 1000000/maxSamplesNum //gerador de sinais
    #define SIMULATORSAMPLETIME 500

    float LM35_value;
    float LDR_value;

    //vari�veis internas

    //armazenar valores de entrada
    bool switch_state;
    int pot_value;
    bool emergency_status;

    volatile int pump_onoff;
    volatile int heater_onoff;
    volatile float remote_pumpspeed;

    float temp[4];
    double vazao_quente;
    float vazao_fria;
    volatile int flow_frequency;

    //estrutura de dados para envio i2c
    typedef struct processData {
      float temp1;
      float temp2;
      float temp3;
      float temp4;
      float hotflow;
      float coldflow;
      float pump_speed;
      byte bstatus;
      byte chksum;
    };

    typedef union I2C_Send { //compartilha a mesma área de memória
      processData data;
      byte I2C_packet[sizeof(processData)];
    };

    I2C_Send send_info;
    int command; //processar o indice de comando enviado pelo Rpi

    //array de bytes auxilar para receber a velocidade da bomba
    byte data[4];

    //estrutura para receber um float para alterar velocidade
    typedef union PumpDataSpeed {
      float fspeed;
      byte bspeed[4];
    };

    //variáveis utilizadas no calculo de vazao de agua fria/quente
    unsigned long currentTime;
    unsigned long cloopTime;
    long microsec;
    float cmMsec;
    float nivel;
    //float vazao1_sf;   //se for necessário para a função de vazao quente, descomentar

    //variáveis auxiliares para operação local
    char flag_button1 = 0x00;
    char flag_button2 = 0x00;
    char flag_emergency = 0x00;
    String mode = "";

    //variáveis auxiliares para comando
    float pot_value_mapped;

    //variáveis para o simulador
    unsigned long current_sim_time;
    unsigned long simulator_time_elapsed;
    int indexwave;

    //inicialização de objetos
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    DeviceAddress deviceID[] =
    {
      { 0x28, 0xFF, 0x46, 0x02, 0x54, 0x16, 0x04, 0xF8 },
      { 0x28, 0xFF, 0xD3, 0xE6, 0x53, 0x16, 0x04, 0xA0 },
      { 0x28, 0xFF, 0xE8, 0xF0, 0x53, 0x16, 0x04, 0x65 },
      { 0x28, 0x1D, 0x9D, 0x27, 0x00, 0x00, 0x80, 0x2E }
    };
    //delay necessário para leitura dos sensores. Depende da resolução
    int delayTempRead = 0;
    int lastTempRequest = millis();

    Ultrasonic ultrasonic(ultrassonico_trigger, ultrassonico_echo);

    LiquidCrystal lcd(41, 11, 12, 40, 13, 38);  //no original deve-se utilizar  LiquidCrystal lcd(41, 11, 12, 40, 13, 38);

    //funções
    void ReadPotentiometer();
    float mapfloat(float x, float in_min, float in_max, float out_min, float out_max);

    //funções de navegação  - Display LCD
    void Menu(int op);
    void EmergencyStatus();

    //funções de leitura de grandezes
    void flow();                //função de interrupção para o calculo de vazao de água fria
    void PumpSpeed(float ref);  //função para alterar a velocidade da bomba
    void VazaoAguaFria();       //função para calcular a vazão de água fria
    void VazaoAguaQuente();     //função para calcular a vazão de água quente
    void Temperaturas();        //função para calcular as temperaturas dos sensores
    void new_Temperaturas();

    //funções do estado do arduino
    void LocalState();
    void RemoteState();
    void emergencia();

    //funções para fazerem a leitura periodica dos valores analógicos
    void runReads();
    void refresh_I2C_Packet();

    //função para receber o valor em bytes via i2c e retornar a velocidade em float
    void parseSpeed(byte data[]);

    //testes em prototipo
    void Temperaturas2();
    void Simulator();

    // the setup function runs once when you press reset or power the board
    void setup() {
      //painel
      pinMode(but1, INPUT_PULLUP);
      pinMode(but2, INPUT_PULLUP);
      pinMode(pot, INPUT);
      pinMode(mode_switch, INPUT);
      pinMode(emergency_button, INPUT);
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led_heater, OUTPUT);

      //sensores
      pinMode(ultrassonico_echo, INPUT);
      pinMode(ultrassonico_trigger, OUTPUT);
      pinMode(hf_sensor, INPUT_PULLUP);
      pinMode(ONE_WIRE_BUS, INPUT_PULLUP);

      //reles
      pinMode(heater_rele, OUTPUT);
      pinMode(inversor_rele, OUTPUT);

      //começar inversor desligado
      digitalWrite(inversor_rele, HIGH);

      //habilitar a interrupção para medição de vazão fria
      //attachInterrupt(hf_sensor, flow, RISING);

      //iniciar sensores de temperatura
      sensors.begin();
      for (byte i = 0; i <= 4; i++) {
        sensors.setResolution(deviceID[i], TEMPERATURE_PRECISION);
      }
      //modo de leitura assincrona
      //sensors.setWaitForConversion(false);
      delayTempRead = 750 / (1 << (12 - TEMPERATURE_PRECISION));

      //iniciar lcd
      lcd.begin(20, 4); //no original utilizar 20,4

      //resolução de escrita do DAC
      analogWriteResolution(10);

      //variáveis que guarda o status da bomba e do aquecedor
      pump_onoff = 0;
      heater_onoff = 0;

      //inicialização da serial
      Serial.begin(115200);

      //inicialização de variáveis
      vazao_fria = 0;
      vazao_quente = 0;

      //inicialização da estrutura i2c
      send_info.data.chksum = 27;
      Wire.begin(12); //arduino iniciado no endereço 12
      Wire.onReceive(receiveEvent); //callback para recebimento de comandos
      Wire.onRequest(requestEvent); //callback para responder à requisições

      //semente para o simulador
      randomSeed(analogRead(LM35_PIN));
      indexwave = 0;
    }

    // the loop function runs over and over again until power down or reset
    void loop() {

      // le o estado da chave
      switch_state = digitalRead(mode_switch);

      /* lê se o botão de emergencia está acionado ou não
          cobre os casos de pressionar o botão e despressionar o botão
      */
      if (digitalRead(emergency_button) == LOW) { //presisonado botão
        emergencia();
      }
      else if (!digitalRead(emergency_button) == LOW && flag_emergency) { //despressionado o botão
        flag_emergency = 0x00;
        emergency_status = 0;
        lcd.clear();
        if (switch_state) {
          RemoteState();
        }
        else {
          LocalState();
        }
      }
      else { //tudo normal
        if (switch_state) {
          RemoteState();
        }
        else {
          LocalState();
        }
      }
    }

    //função de interrupção para calcular a vazão
    /*void flow() {
      flow_frequency++;
    }*/

    //funções que gerenciam o estado do arduino

    void LocalState() {

      //efetua a leitura das grandezas
      runReads();

      //atualiza o lcd com os novos valores
      Menu(0);

      if (!digitalRead(but1)) flag_button1 = 0x01;
      if (!digitalRead(but2)) flag_button2 = 0x01;

      if (digitalRead(but1) && flag_button1) {
        flag_button1 = 0x00;
        //troca o estado da bomba
        digitalWrite(inversor_rele, pump_onoff);  //o estado da bomba � invertido
        //digitalWrite(led_pump, !pump_onoff);  -> N�o � para utilizar o led
        pump_onoff = !pump_onoff;
      }

      if (digitalRead(but2) && flag_button2) {
        flag_button2 = 0x00;
        //troca o estado do aquecedor
        digitalWrite(heater_rele, !heater_onoff);
        digitalWrite(led_heater, !heater_onoff);
        heater_onoff = !heater_onoff;
      }

      //controlar a velocidade da bomba
      ReadPotentiometer();
      PumpSpeed(pot_value_mapped);

      //enquanto modo local, a variável remote_pumpspeed deve ser atualizada para quando
      //ocorrer a mudança para o modo remoto, por exemplo, as informações sejam corretas
      remote_pumpspeed = pot_value_mapped;

      //atualiza a estrutura de envio de dados via i2c
      refresh_I2C_Packet();
    }

    void RemoteState() {
      //faz a leitura das variáveis
      runReads();

      //atualiza o lcd com os novos valores
      Menu(1);

      //atualiza a estrutura de envio de dados via i2c
      refresh_I2C_Packet();
    }

    void emergencia() {
      //digitalWrite(led_flow_mode, LOW);//Apaga LED 1
      digitalWrite(led_heater, LOW);//Apaga LED 2
      digitalWrite(inversor_rele, HIGH);//Desliga a bomba
      digitalWrite(heater_rele, LOW);//Desliga o aquecedor

      //atualiza variável de emergência
      emergency_status = 1;

      //vari�veis auxiliares
      pump_onoff = 0x00;
      heater_onoff = 0x00;
      remote_pumpspeed = 0.0;

      //para evitar blinkar o lcd
      if (!flag_emergency) {
        lcd.clear();
        EmergencyStatus();
      }
      flag_emergency = 0x01;
    }

    //funções para gerenciar a exibição do lcd

    void EmergencyStatus() {
      lcd.setCursor(0, 0);
      lcd.print("Emergencia");
      lcd.setCursor(0, 1);
      lcd.print("Comandos");
      lcd.setCursor(0, 2);
      lcd.print("Bloqueados");
    }

    void Menu(int op) {

      mode = (op == 1) ? "Remote Mode" : "Local  Mode";

      lcd.setCursor(0, 0);
      lcd.print(mode);

      lcd.setCursor(0, 1);
      lcd.print("TA: ");
      lcd.print(temp[0]);
      lcd.print("  ");
      lcd.print("TB: ");
      lcd.print(temp[1]);

      lcd.setCursor(0, 2);
      lcd.print("TC: ");
      lcd.print(temp[2]);
      lcd.print("  ");
      lcd.print("TD: ");
      lcd.print(temp[3]);

      lcd.setCursor(0, 3);
      lcd.print("V1: ");
      lcd.print(vazao_quente);
      lcd.print("  ");
      lcd.print("V2: ");
      lcd.print(vazao_fria);

    }

    //funções de leitura (e escrita) das grandezas

    void Temperaturas() {

      // call sensors.requestTemperatures() to issue a global temperature
      // request to all devices on the bus

      sensors.requestTemperatures();

      // print the device information
      for (byte i = 0; i <= 4; i++)
      {
        temp[i] = sensors.getTempC(deviceID[i]);
      }
    }

    void new_Temperaturas(){
      if(millis() - lastTempRequest > delayTempRead){
        for (byte i = 0; i <= 4; i++)
        {
          temp[i] = sensors.getTempC(deviceID[i]);
        }
      }
      lastTempRequest = millis();
      sensors.requestTemperatures();
    }

    void VazaoAguaFria() {
      currentTime = millis();
      // Every second, calculate litres/hour
      if (currentTime >= (cloopTime + 1000))
      {
        cloopTime = currentTime; // Updates cloopTime
        // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
        vazao_fria = (flow_frequency / 7.5); // (Pulse frequency) / 7.5Q = flowrate in L/min
        flow_frequency = 0; // Reset Counter
      }
    }

    void VazaoAguaQuente() {

      float vazao1_sf; //descobrir o porquê do nome da variavel

      microsec = ultrasonic.timing();
      cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
      nivel = 11.46 - cmMsec;
      vazao1_sf = (0.0537) * pow((nivel * 10), 1.4727);
      if (vazao1_sf > 1) {
        vazao_quente = 0.75 * vazao_quente + 0.25 * vazao1_sf;
      }
    }

    void Temperaturas2() {
      LM35_value = analogRead(LM35_PIN) * 0.48875855;
      LDR_value = analogRead(LDR_PIN) / 10.0;
      temp[0] = LM35_value;
      temp[1] = LDR_value;
    }

    void Simulator() {
      current_sim_time = millis();
      if (current_sim_time >= simulator_time_elapsed + SIMULATORSAMPLETIME) {

        simulator_time_elapsed = current_sim_time;

        for (int i = 0; i < 3; ++i) {
          temp[i] = mapfloat(random(1024), 0, 1023, 10, 50);
        }

        //ultima temperatura com valor senoidal
        temp[3] = mapfloat(waveformsTable[0][indexwave], 0, 4095, 0, 100);
        indexwave++;
        if (indexwave == maxSamplesNum) {
          indexwave = 0;// Reset the counter to repeat the wave
        }

        vazao_quente = mapfloat(random(1024), 0, 1023, 0, 30);
        vazao_fria = mapfloat(random(1024), 0, 1023, 0, 30);
      }
    }

    void PumpSpeed(float ref) {
      if (ref > 100)
        ref = 100;
      else if (ref < 0)
        ref = 0;
      analogWrite(DAC0, ref * 9.43 + 80);
    }

    void ReadPotentiometer() {
      pot_value = analogRead(pot);
      pot_value_mapped = mapfloat(pot_value, 0, 1023, 0, 100);
    }

    void runReads() {

        //Temperaturas();
        //VazaoAguaFria();
        //VazaoAguaQuente();
        //new_Temperaturas();

      //Temperaturas2();
      Simulator();
    }

    //funções callback do i2c
    void receiveEvent(int Nbytes) {
      command = Wire.read();

      switch (command) {
        case 49: //comando de teste
          //comando liga bomba
          digitalWrite(inversor_rele, LOW); //o estado da bomba é invertido
          pump_onoff = 1;
          break;

        case 50:
          //comando desliga bomba
          digitalWrite(inversor_rele, HIGH);
          pump_onoff = 0;
          break;

        case 51:
          //comando liga aquecedor
          digitalWrite(heater_rele, HIGH);
          digitalWrite(led_heater, HIGH);
          heater_onoff = 1;
          break;

        case 52:
          //comando desliga aquecedor
          digitalWrite(heater_rele, LOW);
          digitalWrite(led_heater, LOW);
          heater_onoff = 0;
          break;

        case 53:
          //comando alterar velocidade da bomba
          int i = 0;
          while (Wire.available()) {
            data[i] = Wire.read();
            i = i + 1;
          }
          parseSpeed(data);
          break;
      }
    }

    void requestEvent() {
      if (command == 54) {
        Wire.write(send_info.I2C_packet, sizeof(processData));
      }
    }

    void parseSpeed(byte data[]) {
      //o primeiro byte é o número de bytes do envio; deve-se ignorar
      PumpDataSpeed speed;
      speed.bspeed[0] = data[1];
      speed.bspeed[1] = data[2];
      speed.bspeed[2] = data[3];
      speed.bspeed[3] = data[4];
      //Serial.println(speed.fspeed);
      remote_pumpspeed = speed.fspeed;
      PumpSpeed(remote_pumpspeed); //envia o comando de velocidade para a bomba fisicamente
    }

    void refresh_I2C_Packet() {
      send_info.data.temp1 = temp[0];
      send_info.data.temp2 = temp[1];
      send_info.data.temp3 = temp[2];
      send_info.data.temp4 = temp[3];

      //se a bomba estiver desligada, ignorar o valor do potenciometro
      if (pump_onoff) {
        if (switch_state) {
          send_info.data.pump_speed = remote_pumpspeed;
        }
        else {
          send_info.data.pump_speed = pot_value_mapped;
        }
      }
      else {
        send_info.data.pump_speed = 0.0;
      }

      send_info.data.hotflow = vazao_quente;
      send_info.data.coldflow = vazao_fria;
      bitWrite(send_info.data.bstatus, 0, pump_onoff);
      bitWrite(send_info.data.bstatus, 1, heater_onoff);
      bitWrite(send_info.data.bstatus, 2, switch_state);
      bitWrite(send_info.data.bstatus, 3, emergency_status);
    }

    float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }

https://github.com/felipefonsecabh/ArduinoCode/blob/ArduinoNoNavigation/ArduinoCode.ino

My problem is ocasionally i'm receiving in master a crazy data.
For example:

    Normal block data
    [0, 0, 9, 66, 0, 192, 6, 66, 0, 128, 207, 65, 0, 0, 208, 65, 52, 171, 33, 64, 102, 102, 166, 64, 0, 0, 0, 0, 4, 27]

    Crazy data
    [120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120]

Any ideas?

Thanks a lot!

title: I2C Packet ocasionally send a garbage data

Answers: 1

body:
I have seen this exact same problem, and it took me quite a while to track down the answer.

The I2C protocol is a very raw protocol that is inexpensive to implement, but is very susceptible to noise on the bus.  When I put the SCL and SDA lines on my oscilloscope, I saw that occasionally there were spikes of high frequency noise on both lines. These turned out to be EMF noise. Most of the spikes were rejected by glitch filters on the master and slave chips, but occasionally the spikes lasted too long for the glitch filters, and were then read as data or as clock pulses.

When this happens, the master and the slave get out of sync, often resulting in the slave holding SDA low while awaiting a clock pulse, while the master is waiting for the slave to release SDA so it can send a final NAK.

I2C has no concept of a timeout, so this state will last forever unless you detect it and force a resolution.

In the meantime, your sensor library does not check for Wire errors (it has no way of doing so) so it is returning invalid data.

When you see the invalid data, you can try to recover by temporarily taking control of the SCL and SDA pins yourself and toggling them as follows:

 - Pulse the clock 9 times to force any slave that was sending data to
   finish sending the current byte, at which point it will release the
   SDA line. When SDA goes high, the slave will see the next clock pulse
   as a NAK, so it will stop sending any more bytes.  Any leftover clock
   pulses won't have any START marker, so will be ignored by the slaves.

 - Then send a STOP condition (take CLK low, then take SDA low, then
   take CLK high, and finally allow SDA to transition low-> high while
   CLK is high. All masters and slaves on the bus should now be OK
   again.

Another failure mode can occur in which the slave believes it has received a WRITE command, and it may write to addresses that can put it into an unknown state. To recover from that state, first do the pulsing as above, and then just stop and restart that sensor using library calls.

Finally, there is a failure mode in which the master thinks another master has control of the bus. To recover from that state, first issue the pulses as above, then stop and restart Wire, and then stop and restart any frozen sensors.

It would be nice if all this functionality were in the Wire library, but as of today that's not the case so you'll have to do it yourself. Fortunately that's not too difficult -- it's only a dozen lines of code.

Good luck!


body:
I'm trying to figure out how to process a voice signal for simple purposes. Wherever I look people using or suggesting recognition modules for Arduino.

What I'm wondering: is this possible to make a simple command recognition with Arduino, without modules?

I just simply want to attach a microphone to my Arduino and after I convert it I want to handle signal and program it in MATLAB or in an Arduino itself. How can I achieve that?

As you can see I'm newbie in this. Any help is appreciated. Thanks!

title: Voice recognition without module, is it possible?

Answers: 2

body:
No, it's not possible. The Arduino is not powerful enough to run the algorithms needed.

You need something with far more processing power, memory and storage. Something like a Raspberry Pi, maybe, or a desktop PC.

Or just use one of the many commonly available VR modules you can buy on the internet for next to nothing.

body: Sadly, that's never an easy thing to do as it seems like. I have tried with microphone , amplifier, ADC , and an EEPROM to store patterns of voltage produced by a human voice for different people. But it looked unreliable in the end. EasyVR is a popular voice recognition module usually used with UNO.


body:
I have an **Adafruit Trinket (5v, 16mhz, based off of the AtTiny85 chip)**, and am wishing to use it with a strip with 24 **3 pin, individually addressable LEDs (WS2812B)**. When I try to compile my code, I get this error:  `static_assert(validpin(), "Invalid pin specified");` I've tried using different pins, but of them are seeming to work. What can I do to fix this issue? Here's my current code:

    #include <FastLED.h>
    #define LEDCOUNT 24
    #define DATAPIN 0

    CRGB leds[LEDCOUNT];

    void setup() {
      FastLED.addLeds<WS2812B, LEDCOUNT>(leds, LEDCOUNT);
    }

    void loop() {
      leds[0] = CRGB::Red;
      FastLED.show();
      delay(30);
    }

title: FastLED: "Invalid pin specified"

Answers: 1

body:
I think what @IgnacioVazquez-Abrams is getting at is:

    void setup() {
      FastLED.addLeds<WS2812B, LEDCOUNT>(leds, LEDCOUNT);
    }

Has `LEDCOUNT` showing up for both the number of LEDs and the data pin identifier.

Try:

    void setup() {
      FastLED.addLeds<WS2812B, DATAPIN, GRB>(leds, LEDCOUNT);
    }

This puts `DATAPIN` in the right place, and also adds the color order typical for WS2812B, `GRB`


body:
I have this code:

    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>

    const char* ssid = "xxxx";
    const char* password = "xxxx";

    bool a = false;
    bool b = true;
    int heldVal = 0;

    WiFiServer server(80);

    void setup () {

      Serial.begin(115200);
      delay(10);

      pinMode(2, INPUT);

      // Connect to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

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

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

      // Print the IP address
      Serial.println(WiFi.localIP());
    }

    void loop() {
      if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

        // Check if a client has connected
        WiFiClient client = server.available();
        if (!client) {

          HTTPClient http;  //Declare an object of class HTTPClient

          int readVal;
          if (!a) {
            if(b) {
              readVal = digitalRead(2);
            }
          }
          else {
            a = false;
            readVal = heldVal;
          }

          if (readVal == 0)
            http.begin("http://192.168.1.100/gpio/0");  //Specify request destination
          else
            http.begin("http://192.168.1.100/gpio/1");

          int httpCode = http.GET();                                                                  //Send the request

          if (httpCode > 0) { //Check the returning code

            String payload = http.getString();   //Get the request response payload
            Serial.println(payload);                     //Print the response payload

          }

          http.end();   //Close connection
          return;
        }

        // Wait until the client sends some data
        Serial.println("new client");
        while (!client.available()) {
          delay(1);
        }

        // Read the first line of the request
        String req = client.readStringUntil('\r');
        Serial.println(req);

        // Match the request
        bool toWrite = true;
        if (req.indexOf("/gpio/0") != -1) {
          heldVal = 0;
          b = false;
        }
        else if (req.indexOf("/gpio/1") != -1) {
          heldVal = 1;
          b = true;
        }
        else if (req.indexOf("/mode") != -1) {
          toWrite = false;

          client.flush();

          Serial.println(String(heldVal));
          Serial.println("---in mode request---");

          String input = "{\"mode\":"+String(heldVal)+"}";
          DynamicJsonBuffer jsonBuffer; //----- PROBLEM LINE -----//
          JsonObject& root = jsonBuffer.parseObject(input);

          // Generate the JSON string
          root.printTo(Serial);

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println("Connection: close");
          client.println();
          root.printTo(client);
          delay(1);
        }
        else {
          Serial.println("invalid request");
          client.stop();
          return;
        }

        // Set GPIO2 according to the request
        if(toWrite) {
          a = true;

          client.flush();

          // Prepare the response
          String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
          s += (heldVal) ? "high" : "low";
          s += "</html>\n";

          // Send the response to the client
          client.print(s);
          delay(1);
          Serial.println("Client disonnected");

          // The client will actually be disconnected
          // when the function returns and 'client' object is detroyed
        }
      }
      else {
        ESP.restart();
      }

      delay(30000);    //Send a request every 30 seconds

    }

I put a comment, `//----- PROBLEM LINE -----//`, next to the problem line  above. The error is:

    /Users/eamonwhite/Documents/Arduino/tempcontrolesp/tempcontrolesp.ino: In function 'void loop()':
    tempcontrolesp:110: error: 'DynamicJsonBuffer' was not declared in this scope
           DynamicJsonBuffer jsonBuffer;
           ^
    tempcontrolesp:110: error: expected ';' before 'jsonBuffer'
           DynamicJsonBuffer jsonBuffer;
                             ^
    tempcontrolesp:111: error: 'JsonObject' was not declared in this scope
           JsonObject& root = jsonBuffer.parseObject(input);
           ^
    tempcontrolesp:111: error: 'root' was not declared in this scope
           JsonObject& root = jsonBuffer.parseObject(input);
                       ^
    tempcontrolesp:111: error: 'jsonBuffer' was not declared in this scope
           JsonObject& root = jsonBuffer.parseObject(input);
                              ^
    exit status 1
    'DynamicJsonBuffer' was not declared in this scope

I put it just inside the `loop` function and it is still giving the same error:

    void loop() {
      DynamicJsonBuffer jsonBuffer; //still throws error

How is it not being used correctly? Its just a declaration...

Answers: 1

body:
Did you forget to include the ArduinoJSON header file:

    #include <ArduinoJson.h>


body:
I was looking at this [schematic:][1] [![enter image description here][2]][2]

And I noticed that there are 2 microcontrollers (an Atmega328p and a ATmega16U2).  I was wondering why there need to be 2 microcontrollers.  Do they do different things that only 1 of them can do and the other can't ?

  [1]: https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf
  [2]: https://i.stack.imgur.com/J8kfm.png

title: Why does an Arduino Uno have 2 microcontrollers

Answers: 1

body:
Atmega328P is a microcontroller which are the heart of Arduino Uno, where the Atmega8U2 is the USB to serial convertor for arduino communicated with computer.

You can refer to this [link][1] for more information about this.

  [1]: https://www.arduino.cc/en/Main/ArduinoBoardUnoSMD


body:
My problem is, that my system takes 8 seconds to start the programm after I push the Reset button on my Leonardo.
During that period the L-LED is pulsating.

What could be the problem?

title: Why does the Leonardo take 8 seconds to restart?

Answers: 1

body: That's the firmware waiting for a programming connection. If you want alternate behavior them burn SparkFun's ATmega32U4 firmware to it. One press of Reset will reset the device, and two presses will put it into programming mode.


body:
I have built a custom Arduino Micro PCB, but I have made a mistake, I accidentally attached an interrupt pin for a Gyro sensor to pin 12 of the Micro, not realizing it wasn't an external interrupt pin.

I tried using the interrupt pin change command found on the Arduino website, but I am having some trouble getting it working. If there is a way to make pin 12 on the Arduino Micro an Interrupt pin, how would I go about doing that in the simplest way.

title: Arduino Micro Interrupt

Answers: 2

body:
this library will let you attach a function to a pin using pin-change-interrupt, api is quite simple

https://github.com/neu-rah/PCINT#api

Arduino pin change interrupt library compatible with AVR and SAM with consistent interface.

Allows handlers to be called with a predefined cargo (void*) for user data or just regular void returning functions with no params.

This library use meta-programing to achieve consistency.

**Example**

    #include <pcint.h>

    #define led 13
    #define btn 12

    void setled() {
      digitalWrite(led,digitalRead(btn));
    }

    void setup() {
      pinMode(led,OUTPUT);
      pinMode(btn,INPUT_PULLUP);
      PCattachInterrupt<btn>(setled,CHANGE);
      setled();//initial led status
    }

    void loop() {}

**API**

Just two methods:

    void PCattachInterrupt<pin>(userFunc,mode);
    void PCdetachInterrupt<pin>();

body:
> If there is a way to make pin 12 on the Arduino Micro an Interrupt pin

you should take a look at the device datasheet and see what other functionalities pin 12 has.

if it is a pcint pin, you are golden;
if it is a timer input pin or an input capture pin, they can be programmed to act like an interrupt pin as well.

all begins with reading the datasheet.


body:
[![enter image description here][1]][1]
I am working on Arduino Mega project where I want to add a PUSHBUTTON (Any other can be suggested) that will be programmed in my arduino code, such that if I would press the button arduino code should stop working and when I will press the button back the code should resume from the moment where it stopped.
Button will be attached to 5v pin so that will turn off/on the arduino.

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

title: On/off button for Arduino Mega for 5V input pin- hardware based auto on/off arduino(PUSHBUTTON NOT AS INTERRUPT)

Answers: 3

body:
>  if I would press the button arduino code should stop working and when I will press the button back the code should resume from the moment where it stopped.

the simplest would be use an interrupt trigger by the button to set a flag and the execution would either loop around the flag or go straight through, depending on the state of the flag.

body:
If you rewrite the code to be a state machine so that `loop()` never blocks it's pretty easy to add:

    bool paused = false;
    void loop(){
        //read button
        if(buttonPressed){
            paused = !paused;
        }
        if(paused){
            return;
        }
        //rest of code written so it never blocks and returns as fast as possible
    }

Then the resume part is handled by the extra already required by needing to be able resume on next call of loop.

If you go for full power off then you need to write out your state to non-volatile memory and read it back in on init.

body:
Your question is very badly written, and a lot of infos are missing. In any case, from what I understood from your comments, you want a button that works this way:

 - The arduino is not powered up
 - You press the button; the arduino turns on, and starts the operations.
 - You press the button; the arduino shuts down.
 - You press the button; the arduino turns on, and resumes the operations from where it was.

I'm not sure about the last point, so first of all I'll give you some hints about the first three points.

You can modify the circuit in a way similar to this:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/2GQ1B.png)

<!-- End schematic -->

(I named the two arduino pins as A and B because it is not important which pins you use, just two separate pins).

The diodes can be any diode (e.g. 1N4148). The PMOS and NMOS are not critical, provided that they can fully turn on with a 4-5V gate voltage and that the PMOS can bear the current you need.

When the arduino is shut down, the NMOS is off, and so is the PMOS. When you press the button, the voltage on the NMOS gate becomes about 4.5V, so it turns on. the PMOS turns on too, and so the arduino sees some power. At the very first moment, it has to pull pin B to 5V. This way even when the button is not pressed anymore, the board will be powered. When the user presses the button, the arduino can sense it through pin A. This way it can go into shutdown mode. Here is a sort of base for handling this behavior. Please note that I'm using the Bounce2 library, since I particularly like it when dealing with buttons (it automagically handles bounces and also give more info about the edges).

    #include <Bounce2.h>

    const byte pinA = the pin A number;
    const byte pinB = the pin B number;

    Bounce pinA_debounced = Bounce();

    void shutdown() {
     // Turn off the board
     digitalWrite(pinB, LOW);
     // Farewell, cruel world!
     while(1); // wait for a power off
    }

    void setup() {
     // Turn on the board
     pinMode(pinB,OUTPUT);
     digitalWrite(pinB, HIGH);

     // Initializate the debounced pin
     pinA_debounced.attach(pinA, INPUT_PULLUP);

     // Other setup instructions
    }

    void loop() {
     // Update the Bounce instance :
     pinA_debounced.update();

     if (pinA_debounced.rose())
      shutdown();

     // Other loop instructions
    }

If you want to save your data in order to resume it, well, this highly depends on your actual code. You will have to identify what is your "current status", then save it to EEPROM.

Here is, for instance, a program which outputs on serial one sequential number (from 0 to 254, then restart from 0) every second. When you shut it down, it will start again from the last one:

    #include <Bounce2.h>

    const byte pinA = the pin A number;
    const byte pinB = the pin B number;

    const byte valueAddress = 0x10; // Any value is fine for this
    // as long as it is in the available EEPROM

    Bounce pinA_debounced = Bounce();
    byte value;
    unsigned long lastMillis;

    void shutdown() {
     // Save status BEFORE turning down the power
     EEPROM.update(valueAddress, value);

     // Turn off the board
     digitalWrite(pinB, LOW);
     // Farewell, cruel world!
     while(1); // wait for a power off
    }

    void setup() {
     // Turn on the board
     pinMode(pinB,OUTPUT);
     digitalWrite(pinB, HIGH);

     // Initializate the debounced pin
     pinA_debounced.attach(pinA, INPUT_PULLUP);

     // Restore the current value from EEPROM
     value = EEPROM.read(valueAddress);
     Serial.begin(9600);
     lastMillis = millis() - 1000;
    }

    void loop() {
     // Update the Bounce instance :
     pinA_debounced.update();

     if (pinA_debounced.rose())
      shutdown();

     if ((millis() - lastMillis) >= 1000)
     {
      lastMillis += 1000;
      Serial.println(value);
      value++;
     }
    }


body:
I try move my projects from atmega to ESP8266-07 modules. I connect ESP8266-07 to FT232:

    (ESP) RX -------- TX (FT232)
    (ESP) TX -------- RX (FT232)
    (ESP) GND ------- GND (FT232)
    (ESP) VCC ------- VCC 3.3V (FT232)
    (ESP) EN -------- VCC 3.3V (FT232)
    (ESP) GPIO0 ----- GND (FT232)
    (ESP) GPIO15 ---- GND (FT232)

I can upload sketch and it's work. BUT...

... WHEN I restart ESP (software reset or hardware reset - unplug power) program no starting. I try change connections after upload like:

    Try 1:
    (ESP) RX -------- TX (FT232)
    (ESP) TX -------- RX (FT232)
    (ESP) GND ------- GND (FT232)
    (ESP) VCC ------- VCC 3.3V (FT232)
    (ESP) EN -------- VCC 3.3V (FT232)

    Try 2:
    (ESP) RX -------- TX (FT232)
    (ESP) TX -------- RX (FT232)
    (ESP) GND ------- GND (FT232)
    (ESP) VCC ------- VCC 3.3V (FT232)
    (ESP) EN -------- VCC 3.3V (FT232)
    (ESP) GPIO0 ----- VCC 3.3V (FT232)

    Try 3:
    (ESP) RX -------- TX (FT232)
    (ESP) TX -------- RX (FT232)
    (ESP) GND ------- GND (FT232)
    (ESP) VCC ------- VCC 3.3V (FT232)
    (ESP) GPIO0 ----- VCC 3.3V (FT232)

But everytime sketch does not start after upload. This is not a code problem, because I try start "blink" sketch or other. Everytime ESP work once, after upload.

title: ESP8266-07 no work after reboot

Answers: 2

body:
Thank you gre_gor. You were right about correct pins. If you want start ESP on "normal mode" you must plug pins like:

    (ESP) GND ------- GND
    (ESP) GPIO15 ---- GND
    (ESP) VCC ------- VCC 3.3V
    (ESP) EN -------- VCC 3.3V
    (ESP) GPIO0 ----- VCC 3.3V
    (ESP) GPIO2 ----- VCC 3.3V

But if we must use GPIO0, GPIO2 and GPIO15 how we have 9 GPIO, 2 UART and 1 ADC?

body: For me the same issue happened once ,i tries flashing the AT commands firmware (can download from espressif website)and then burned my test firmware to it ...worked.Try it..!


body:
I'm trying to combine a MySensors network with the usage of a SD card. Currently I'm working with the SD card reader on the EthernetShield v2.
The NRF24L01+ chip I'm using is also using SPI but we used Soft-SPI to change the pins that is uses so I'm not using pin 4 or 10 (that are used to select the SD card as far is I know).

To read from the SD card I'm using the SdFat library.
When I exclude the following part of code, the messages are getting send and I don't have any weird resets:
<!-- language-all: lang-cpp -->

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

But the card keeps resetting after booting and it gives these logs:

    0;255;3;0;9;!TSF:MSG:SEND,0-0-15-15,s=0,c=1,ne.
    0;255;3;0;9;MCO:BGN:INIT OK,TSP=1
    14;Gateway startup complete.
    0;255;0;0;18;2.1.1
    0;255;3;0;9;MCO:BGN:STP
    initialization done.
    0;255;3;0;9;MCO:BGN:INIT OK,TSP=1
    0;255;3;0;9;MCO:BGN:INIT GW,CP=RNNGA--,VER=2.1.1
    0;255;3;0;9;TSM:INIT
    0;255;3;0;9;TSF:WUR:MS=0
    0;255;3;0;9;TSM:INIT:TSP OK
    0;255;3;0;9;TSM:INIT:GW MODE
    0;255;3;0;9;TSM:READY:ID=0,PAR=0,DIS=0
    0;255;3;0;9;MCO:REG:NOT NEEDED
    0;255;3;0;14;Gateway startup complete.
    0;255;0;0;18;2.1.1
    0;255;3;0;9;MCO:BGN:STP
    initialization done.
    0;255;3;0;9;MCO:BGN:INIT OK,TSP=1
    0;255;3;0;9;!TSF:MSG:SEND,0-0-15-        15,s=0,c=1,t=24,pt=0,l=25,sg=0,ft=0,st=NACK:Message Gateway -> Pongno
    0;255;3;0;9;MCO:BGN:INIT GW,CP=RNNGA--,VER=2.1.1
    0;255;3;0;9;TSM:INIT
    0;255;3;0;9;TSF:WUR:MS=0
    0;255;3;0;9;TSM:INIT:TSP OK
    0;255;3;0;9;TSM:INIT:GW MODE
    0;255;3;0;9;TSM:READY:ID=0,PAR=0,DIS=0
    0;255;3;0;9;MCO:REG:NOT NEEDED
    0;255;3;0;14;Gateway startup complete.
    0;255;0;0;18;2.1.1
    0;255;3;0;9;MCO:BGN:STP
    initialization done.
    0;255;3;0;9;MCO:BGN:INIT OK,TSP=1

The code:

    #define MY_DEBUG

    #define MY_SOFTSPI
    #define MY_RF24_CE_PIN 11
    #define MY_RF24_CS_PIN 6
    #define MY_SOFT_SPI_SCK_PIN 8
    #define MY_SOFT_SPI_MISO_PIN 9
    #define MY_SOFT_SPI_MOSI_PIN 7

    #define MY_RADIO_NRF24
    #define MY_RF24_CHANNEL 69
    #define MY_NODE_ID 0
    #define MY_GATEWAY_SERIAL

    #include <MySensors.h>
    #include <SPI.h>
    #include "SdFat.h"
    SdFat SD;

    #define SD_CS_PIN 4

    File myFile;
    #define PONGNODEID 15

    MyMessage msg(MY_NODE_ID, V_VAR1);

    void setup() {
      // Open serial communications and wait for port to open:

      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
      msg.setDestination(PONGNODEID);

      pinMode(10, OUTPUT);
      digitalWrite(10, HIGH);

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

    }

    void presentation() {}

    long lastSent = 0;

    void loop() {
      if (millis() - lastSent >= 3000) {
        lastSent = millis();
        send(msg.set("Message Gateway -> Pongnode"), true);
      }
    }

title: Combining mysensors with SD card (on an Ethernet Shield v2)

Answers: 0


body:
I want to open a solenoid valve with an arduino, and have set up the following circuit

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

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

The plan is to add solenoids to every relay on the board. I am wondering if this circuit is any useful, or if there are major flaws present. I am worried about frying my components, especially the 12V 2A hooked up with a solenoid of 1A, however i want the 2A, since i want to be able to power multiple solenoids at the same time.

I tried switching the board directly from the arduino, and with its 5V to the VCC, but it was not enough to make the relays switch, maybe a transistor is in line, if so, which one?

title: Solenoid flyback, relayboard switch

Answers: 0


body:
I am a web developer and I am struggling with C code on Arduino. So this is What I have:

I have a backend written on PHP that returns a 0 or 1 depending of wether a pin should be high or low. I have an Arduino UNO with a W5100 Ethernet shield mounted, and I'm currently connecting correctly to my server, this is my Arduino code:

    #include <SPI.h>
    #include <Ethernet.h>

    // Enter a MAC address for your controller below.
    // Newer Ethernet shields have a MAC address printed on a sticker on the shield
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    // if you don't want to use DNS (and reduce your sketch size)
    // use the numeric IP instead of the name for the server:
    //IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
    char server[] = "www.api-qa1.enerzoo.com";    // name address for Google (using DNS)

    // Set the static IP address to use if the DHCP fails to assign
    IPAddress ip(192, 168, 0, 177);

    // Initialize the Ethernet client library
    // with the IP address and port of the server
    // that you want to connect to (port 80 is default for HTTP):
    EthernetClient client;

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

      // start the Ethernet connection:
      if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // try to congifure using IP address instead of DHCP:
        Ethernet.begin(mac, ip);
      }
      // give the Ethernet shield a second to initialize:
      delay(1000);
      Serial.println("connecting...");

      // if you get a connection, report back via serial:
      if (client.connect(server, 80)) {
        Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /api/DeviceState/1 HTTP/1.1");
        client.println("Host: www.api-qa1.enerzoo.com");
        client.println("Connection: close");
        client.println();
      } else {
        // if you didn't get a connection to the server:
        Serial.println("connection failed");
      }
    }

    void loop() {
      // if there are incoming bytes available
      // from the server, read them and print them:
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
      }

      // if the server's disconnected, stop the client:
      if (!client.connected()) {
        Serial.println();
        Serial.println("disconnecting.");
        client.stop();

        // do nothing forevermore:
        while (true);
      }
    }

 And this is the response it outputs:

    connecting...
    connected
    HTTP/1.1 200 OK
    Server: nginx/1.10.3 (Ubuntu)
    Content-Type: application/json
    Transfer-Encoding: chunked
    Connection: close
    Vary: Accept-Encoding
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
    Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With
    Cache-Control: no-cache
    Date: Fri, 17 Nov 2017 23:36:14 GMT
    Set-Cookie: laravel_session=eyJpdiI6ImIzTDJzQk1BUm1qY1BuZ1BJXC83Mk5BPT0iLCJ2YWx1ZSI6IlwvNjlmXC9FZWxDSW9vbGNcL1JZUU5tbTFvOVVXVjcxV0hHaDRKUzVGVVZCSmFCM1BcLzlSR2x5MmN4cnZ1ZHRvZmlcLzNSUWMrZEFDMTQzR05ORTk5R3dBUGc9PSIsIm1hYyI6IjM4ZjVhY2IxOWVmZTMzMGY2OGE1MTNmZWY0NzczNGVhNWJhZjVkYzlkYzY4ODg3ZGI0OWVhNDYwOTkwYjgxYTAifQ==; expires=Sat, 18-Nov-2017 01:36:14 GMT; Max-Age=7200; path=/; HttpOnly

    1a
    ||0||
    0

    disconnecting.

I need to get that zero that is enclosed between the double pipes

> ||0||

Any help would be really appreciated

title: How to get a character from a serial Parsed http response?

Answers: 2

body: You can send json format instead of pipes enclosed and parse the value. Else use regex expression to match ||0|| or ||1|| .

body:
This is how I solved it. I avoided using regex expressions and "complex" functions such as substring in order to save memory. I just detected two consecutive pipes and get the next character (in this case 0 or 1) using a counter. Since I need to continuously be checking the status of the device, I reset the counter to 0 once I get the current state.

      if (client.available()) {
        char c = client.read();
        if(c == '|' || counter == 2){
          counter++;
          if(counter == 3){
            counter = 0;
          }
          if(c == '1' || c == '0'){
            Serial.print(c);
          }
        }
      }


body:
I'm using [this][1] motor driver with 2 of [these][2] motors to control a skid steer robot. To get the robot to coast to a stop, I use this code:

      analogWrite(MotLPWM, 0);  //coast to stop
      analogWrite(MotRPWM, 0);
      digitalWrite(MotL1, HIGH);
      digitalWrite(MotL2, HIGH);
      digitalWrite(MotR1, HIGH);
      digitalWrite(MotR2, HIGH);

to get the robot to hard stop, I use this code:

    analogWrite(M1PWM, 0);
    analogWrite(M2PWM, 0);
    digitalWrite(M1INA, LOW);
    digitalWrite(M2INA, LOW);
    digitalWrite(M1INB, LOW);
    digitalWrite(M2INB, LOW);

I would like for the robot to stop and/or brake with something in between so it isn't so hard on the gears. The following snippet of the whole sketch is supposed to let the motors coast for 1/4 second then hard stop. Unfortunately, it doesn't coast and goes straight to the hard stop. Any ideas how to fix it?

        void allStop () {
    //COAST
      analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
      analogWrite(MotRPWM, 0);
      digitalWrite(MotL1, HIGH);
      digitalWrite(MotL2, HIGH);
      digitalWrite(MotR1, HIGH);
      digitalWrite(MotR2, HIGH);
    //HARD STOP
      if ((millis() - previousCoastMillis) > 250) {
      analogWrite(MotLPWM, 0);
      analogWrite(MotRPWM, 0);
      digitalWrite(MotL1, LOW);
      digitalWrite(MotL2, LOW);
      digitalWrite(MotR1, LOW);
      digitalWrite(MotR2, LOW);
        previousCoastMillis = millis();
      }
    }

The full sketch is here:

    int ledB = 5;

    int MotL1 = 8;
    int MotL2 = 7;
    int MotLPWM = 9;

    int MotR1 = 11;
    int MotR2 = 12;
    int MotRPWM = 10;

    unsigned long previousCoastMillis = 0;
    const int coastInterval = 500;

    void setup() {
      pinMode(MotL1, OUTPUT);
      pinMode(MotL2, OUTPUT);
      pinMode(MotLPWM, OUTPUT);
      pinMode(MotR1, OUTPUT);
      pinMode(MotR2, OUTPUT);
      pinMode(MotRPWM, OUTPUT);
      pinMode(ledB, OUTPUT);
    }

    void loop() {
      go();
      allStop();
    }

    void allStop () {
    //COAST
      analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
      analogWrite(MotRPWM, 0);
      digitalWrite(MotL1, HIGH);
      digitalWrite(MotL2, HIGH);
      digitalWrite(MotR1, HIGH);
      digitalWrite(MotR2, HIGH);
    //HARD STOP
      if ((millis() - previousCoastMillis) > 250) {
      analogWrite(MotLPWM, 0);
      analogWrite(MotRPWM, 0);
      digitalWrite(MotL1, LOW);
      digitalWrite(MotL2, LOW);
      digitalWrite(MotR1, LOW);
      digitalWrite(MotR2, LOW);
        previousCoastMillis = millis();
      }
    }

    void go () {
      analogWrite(MotLPWM, 150);
      analogWrite(MotRPWM, 150);
      digitalWrite(MotL1, HIGH);
      digitalWrite(MotL2, LOW);
      digitalWrite(MotR1, HIGH);
      digitalWrite(MotR2, LOW);
      digitalWrite(ledB, HIGH);
      delay(1000);

    }

  [1]: https://www.amazon.com/gp/product/B01N9Q3KJU/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1
  [2]: https://www.pololu.com/product/1574

title: motor hard stop vs coasting

Answers: 2

body:
You are trying to use a mix of `delay` and  `millis`

Instead you will want a proper state machine:

    void loop(){

        switch (state){
        case GOING: go();
           state = WAIT_FOR_COAST;
           transition = millis();break;

        case WAIT_FOR_COAST: if(millis()-transition > 1000){
                allStop(false);
                state = WAIT_FOR_STOP; transition = millis();
            }
            break;
        case WAIT_FOR_STOP: if(millis()-transition > 250){
                allStop(true);
                state = WAIT_FOR_GO; transition = millis();
            }
            break;
        case WAIT_FOR_GO: if(millis()-transition > 1000){
                allStop(true);
                state = WAIT_FOR_GO; transition = millis();
            }
            break;

        }

    }

Remove the delay in go and use a simple if-else in the allStop where parameter == true means hard stop and false means coast.

Another option is to use a extra mosfet to put a resistor across the motor instead of shorting it out (which is what the hard stop will do). That will reduce the breaking torque but defeats the isolation of the board.

body:
  This works. When allStop gets called, previousCoastMillis is reset. Then the motor coasts while it's stuck in the while loop for 150ms. Then it hard stops.

    void allStop () {
      previousCoastMillis = millis();
      while (millis() - previousCoastMillis < 150) {
        analogWrite(enA, 0);
        analogWrite(enB, 0);
        digitalWrite(in1, HIGH);
        digitalWrite(in2, HIGH);
        digitalWrite(in3, HIGH);
        digitalWrite(in4, HIGH);
      }

      analogWrite(enA, 0);
      analogWrite(enB, 0);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
    }


body:
Please help explain the meaning of `'\n'` and `'0'` in the lines

    if (isdigit(readValue) && readValue != '\n')
    {
      cellValue = cellValue * 10 + readValue - '0';
    }

title: Please help explain the meaning of '\n' and '0';

Answers: 2

body:
The '\n' in interpreted as a line-feed character.  It is one of many printable and non printable [ASCII][1] characters computers use.  Usually, character strings are terminated using a line-feed.  So this line of code is likely testing for the end of a string of characters.

The '0' is interpreted as the ASCII value for the character which looks like the number zero.  Strange enough, when printing characters, the ASCII value for the charter which looks like the number zero actually has a value of 48.  And one has a value of 49.  Two a value of 50.  Three a value of 51. And so on.  So, to convert a number found in a character string into numbers like 0, 1, 2 & 3, programmers subtract 48 from the character.  Using '0' instead of 48 works as both represent the same value.  And, by subtracting '0', it is clearer to the seasoned programmer that a conversion from ASCII numbers to normal numbers is underway.

  [1]: https://en.wikipedia.org/wiki/ASCII

body:
\n stands for new line feed. It is one of the many "escape sequences" in C. Escape sequences start with "\" and it imply a predefined meaning to compiler.

Refer: https://en.m.wikipedia.org/wiki/Escape_sequences_in_C

In ASCII, decimal numbers from 0-9 are represented in 7-bits, in the range 48-57. So if a and b are integers, then:
b = a - '0' means  b = a - 48

Refer:
https://ascii.cl/index.htm?content=mobile


body:
How to flash pre-compiled binary into NodeMCU using Ardunio IDE. Since every time it require to compile and flash it. Is there way to flash binary alone to nodeMCU via Arduino IDE ?

One can export binary file from IDE -> Sketch -> Export Compiled Binary. Binary will be copied into working directory. U can check the path Sketchbook location in File -> Preferences. But how to flash binary alone to nodeMCU.

I have fashed using esptool.py from linux. But is there a way to flash from IDE for handy ?

title: How to flash pre-compiled bin files into NodeMCU using Ardunio IDE

Answers: 1

body: You can't flash precompiled binary with Arduino IDE, you have to use esptool.py from the command line.


body:
I have been creating the example for bluetooth communication with arduino with hc_05  Problem I am facing are below.

    String statuss= "1.00,2.00,3.00";
    bluetooth.print(statuss);
    Serial.print(statuss);

This is the code where is get only last 2 digits i.e 00 in android while its showing me complete string in serial monitor.

    String statuss= "Hello";
    bluetooth.print(statuss);
    Serial.print(statuss);

Then I get the output as **ello** in Android n in Serial monitor it show **Hello**

Can Anybody suggest the whats the problem

title: #Ardunio Send Float values with bluetooth.print in arduino

Answers: 2

body: It is difficult to know your exact problem since you have not provided your code. However, I believe that you don't have a clear starting bit and a clear end bit, so that the modules don't know when to Start and End.

body:
I suspect (at first sight) a speed problem. Android runs Bluetooth at 115200 Bauds. So you must set your HC-05 o HC-06 at this speed to get proper result.

But as you perform "bluetooth.print(statuss);" and also "Serial.print(statuss);" this mean you have created a virtual port, probably using the Software Serial lib.
Unfortunatly, this lib is not very efective. At speed higher than 19200 Bauds, you lost data (I've had a lot of problem with that before understanding!!)
The only right way is to use directly the RX and TX port of the Arduino (pin 0 and 1) and use (eg) a LCD Display to display data and help you debugging your Arduino code (as when you plug the HC on Pin 0 and 1 you lost the access to the serial monitor).

A trick: with the HC on pin 0 and 1, each time you send the sketck to the Ardino, you must unplug RX as it's used for sending the code.

Hope this will help.


body:
What does this mean?? Stray\342 inprogram

    // Basic sketch for EmonWRT
    // Version 1.2

    #define FILTERSETTLETIME 15000 // Time (ms) to allow the filters to settle before sending data

    const int CT1 = 1;
    const int CT2 = 1; // Set to 0 to disable CT channel 2
    const int CT3 = 1; // Set to 0 to disable CT channel 3
    const int VOLT = 1; // Set to 0 to disable

    const int UNO = 1; // Set to 0 if your not using the UNO bootloader (i.e using Duemilanove) – All Atmega’s shipped from OpenEnergyMonitor come with Arduino Uno bootloader
    #include <avr/wdt.h>
    #include <JeeLib.h> // Download JeeLib: http://github.com/jcw/jeelib
    ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Attached JeeLib sleep function to Atmega328 watchdog -enables MCU to be put into sleep mode inbetween readings to reduce power consumption
    #include <EmonLib.h>
    EnergyMonitor ct1,ct2,ct3; // Create instances for each CT channel
    float power1, power2, power3;
    float voltage;
    const int LEDpin = 9; // On-board emonTx LED

    boolean settled = false;
    boolean firstsensor = true; // Just to know if a , must be added in the CSV output

    void setup()
    {
    delay(10000);

    Serial.begin(9600);
    Serial.println(“emonWRT CT123 and Voltage v1.2”);
    pinMode(LEDpin, OUTPUT); // Setup indicator LED
    digitalWrite(LEDpin, HIGH);

    if (UNO) wdt_enable(WDTO_8S); // Enable anti crash (restart) watchdog if UNO bootloader is selected. Watchdog does not work with duemilanove bootloader // Restarts emonTx if sketch hangs for more than 8s
    ct1.voltage(3, 225, 1); // Voltage: input pin, calibration, phase_shift

    }

    void loop()
    {

    power1 = ct1.Irms; //ct.calcIrms(number of wavelengths sample)*AC RMS voltage
    power2 = ct2.Irms;
    power3 = ct3.Irms;
    voltage = ct1.Vrms; // AC Mains rms voltage

    // because millis() returns to zero after 50 days !
    if (!settled && millis() > FILTERSETTLETIME) settled = true;

    if (settled) // send data only after filters have settled
    {
    digitalWrite(LEDpin, HIGH); delay(2); digitalWrite(LEDpin, LOW); // flash LED
    **Serial.println(“EMONWRT “);**

    if (CT1) {
    if (!firstsensor) Serial.println(" ");
    firstsensor = false;
    Serial.print(power1);
    }

    if (CT2) {
    if (!firstsensor) Serial.println(" ,");
    firstsensor = false;
    Serial.print(power2);
    }

    if (CT3) {
    if (!firstsensor) Serial.println(",");
    firstsensor = false;
    Serial.print(power3);
    }

    if (VOLT) {
    if (!firstsensor) Serial.println(" ");
    firstsensor = false;
    Serial.print(voltage);
    }

    firstsensor = true;

    //Serial.println(” “);
    Serial.println(" ");

    delay(100);

    Sleepy::loseSomeTime(5000); // sleep or delay in seconds – see emontx_lib
    }
    }

title: Stray\342 inprogram

Answers: 1

body:
Typographic quotes (**“** and **”**) are not part of C/C++ language for defining string literals.

For that you must use straight quotes (i.e. **"**).

Hence replace:

    Serial.println(“EMONWRT “);

with:

    Serial.println("EMONWRT ");

Typographical quotes might get automatically created when using a word processor (e.g. MS Word) to type your source code, or when copying code from a Word document into the Arduino IDE.

The best is to keep away from word processors when typing source code.


body:
I am a beginner with no coding background.
I am trying to figure out an alarm that tells people how long they have been sitting on their chair.
The concept is very simple when the person would sit in his chair it will trigger an event ( maybe a button press) which should trigger the counting of time. if the time exceeds a limit (let's say an hour) a buzzer will go off. The only way to stop the buzzer is to stay away from the chair for let's say a minute.
I don't know how to start writing this code, especially how do I make this time counter start with this sitting action ( which might press a button).
Its for my class project so any help is highly appriciated.

title: Using RTC DS3231 + Arduino UNO to calculate time lapsed

Answers: 2

body: One idea would be to use force/pressure sensor on chair. You have to find what the sensor outputs when an average person sits on it and calibrate the values accordingly in code. Finally you have to a set threshold value for it. Now if somebody sits on it and if that threshold is exceeded, it means somebody sat on it. So you can now trigger your rtc module or maybe you can use special peripherals called timers , which are inside arduino itself. Both can be used to keep track of time. Tutorials are available for both timers, and ds3231- arduino interfacing. You can easily code. Good luck :-)

body:
> The concept is very simple when the person would sit in his chair it will trigger an event ( maybe a button press) which should trigger the counting of time. if the time exceeds a limit (let's say an hour) a buzzer will go off.

multiple ways, all conceptually identical to yours ask:

1) when a person sits in the chair, it triggers a piece of code that sets an alarm in the dtc. once the dtc alarm goes off, it triggers a state change on a pin linking the dtc to the mcu, which triggers the buzzer;

2) the 2nd approach is similar except that the mcu pulls the dtc constantly for new time. once the new time passes the trigger time sufficiently, a buzzer sounds.

...

this whole thing can be done without the dtc, btw.


body:
I am not quite experienced with Arduino and Interrupts. Below I am trying to disable interrupt once it got detected and enable it again when I start loop again. But in below code I am not able to enable it.

    int L = 2;
    volatile int done0=0;
    volatile unsigned long leftT=0;

    void recordL()
    {
      if(done0 == 0)
      {
          leftT=micros();
      }
      done0 = 1;
      detachInterrupt(0);
    }

    void setup() {
      // put your setup code here, to run once:
      pinMode(L,INPUT);
      Serial.begin(9600);
      Serial.println("Start..");
    }

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

      attachInterrupt(0,recordL,RISING);
      done0 = 0;

      while(!done0)
      {

      }

      Serial.println("Sound..");
      Serial.println(leftT);
      delay(1000);
      Serial.println("After Delay");
    }

but I made small change in code. I shifted 'done0=0' above attachInterrupt() then it is working. Why is that happening? One more issue that I am facing here is when I enable it again one more saved value is coming. Does it store value when I have disabled it?

    int L = 2;
    volatile int done0=0;
    volatile unsigned long leftT=0;

    void recordL()
    {
        if(done0 == 0)
        {
            leftT=micros();
        }
      done0 = 1;
      detachInterrupt(0);
    }

    void setup() {
      // put your setup code here, to run once:
      pinMode(L,INPUT);
      Serial.begin(9600);
      Serial.println("Start..");
    }

    void loop() {
      // put your main code here, to run repeatedly:
      done0 = 0;
      attachInterrupt(0,recordL,RISING);

      while(!done0)
      {

      }

      Serial.println("Sound..");
      Serial.println(leftT);
      delay(1000);
      Serial.println("After Delay");
    }

Output for 2nd case (Sound is coming only once but I am getting sound after delay also):

       Start..
       Sound..
       2873000
       After Delay
       Sound..
       3873528
       After Delay

title: How to enable interrupt again after disabling it?

Answers: 3

body:
Normally, an [Arduino interrupt attachment][1] is made in the setup() method and is never removed.  Consider moving your call to attach the interrupt accordingly and removing your call to [detach the interrupt][2].

Your approach is understandable when considering normal embedded processor programming.  In such cases all aspects of the hardware must be considered.  This may include resetting the interrupt hardware for the next interrupt event.

When programming in the Arduino paradigm, many details are abstracted from the coder to make the coding experience simple and straight forward.  In the example found at the bottom of the [interrupt attachment Arduino Reference page][1], it is evident that no code needs to be added to manage the interrupt within the interrupt method.

To address your question specifically (why does the 2nd code listing work while the 1st does not) consider the actual (possible) sequence of events. The setup() method is 1st run followed by the loop() method.  In the 1st code listing you attached the interrupt then set your "done" flag allowing the code in the interrupt to run. You cause the interrupt by raising the input on interrupt pin 0.  This will likely work and you will then disconnect the interrupt.  If you try to cause the interrupt again before 1 seconds elapses it will appear that the interrupt did not work because the loop() method is still waiting for the 1 second delay you have added and has not re-attached the interrupt.  After the 1 second delay has ended, the loop() method will be called again.  It is likely this time the processor's hardware remembers you tried to cause an interrupt.  So when the interrupt is attached, the interrupt routine is called.  But the "done" flag has not yet been set to zero so the interrupt does not execute code controlled by the "done" flag.  In the 2nd code listing you have remedied this problem by setting the "done" flag before reattaching the interrupt.

  [1]: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
  [2]: https://www.arduino.cc/reference/en/language/functions/external-interrupts/detachinterrupt/

body:
> Below I am trying to disable interrupt once it got detected and enable it again when I start loop again.

not sure why you want to do that but interrupts are DISABLED in isr by hardware (unless you explicitly enable it in isr) so what you are trying to do is done for you automagically.

> But in below code I am not able to enable it.

mostly it involves enabling the respective interrupt mask, unless you want to enable / disable all interrupts.

body:
The code needs modifications. I presume you are using digital pin 2 as your interrupt pin here. But the first argument to your attachinterrupt () is simply 0. That's not a recommended way of passing argument. Check the below link.

Check -https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I think this is what happened -

In the first case, the code is stuck in the infinite while loop as interrupt routine might have called just after attachinterrupt() and done became 1. After that done becomes 0 and got stuck in while (!done) loop forever as interrupts are now disabled.

In the second case, after making done = 0, the code entered into the interrupt routine and made done = 1, comes out, skips while loop and prints output. Again in loop(), done is made 0 and interrupts are attached back. And again interrupt routine is executed again , possibly because it detected another rising edge. This issue is there with push buttons, due to bouncing. Here, sound sensor may not be outputting clean digital signal.

Note: Disabling interrupt inside interrupt routine is meaningless cz arduino by default disables all interrupts and queues further interrupts during the execution of an interrupt routine. So I really doubt its behavior. You better rectify it by removing that statement from there and put it in the main code after while().


body:
Why do I have to open Serial Monitor to display non-NaN values retrieved from DHT22,
what am I doing wrong in the code below?

<!-- language-all: lang-c -->

    #include <DHT.h>
    #include <Wire.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    // OLED display TWI address
    #define OLED_ADDR   0x3C
    // reset pin not used on 4-pin OLED module
    Adafruit_SSD1306 display(-1);  // -1 = no reset pin
    // 128 x 64 pixel display
    #if (SSD1306_LCDHEIGHT != 64)
    #error("Height incorrect, please fix Adafruit_SSD1306.h!");
    #endif
    #define DHTPIN D3
    #define DHTTYPE DHT22
    DHT dht(DHTPIN, DHTTYPE);
    void setup() {

    Serial.begin(115200);
    delay(100);
      dht.begin();
      pinMode (DHTPIN, OUTPUT);
      /// initialize and clear display
      display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
      display.clearDisplay();
      //  display.drawRect(1, 1, display.width()-1, display.height()-1, WHITE);   // draws the outer rectangular boundary on the screen
      display.display();
      // display a pixel in each corner of the screen
      display.drawPixel(0, 0, WHITE);
      display.drawPixel(127, 0, WHITE);
      display.drawPixel(0, 63, WHITE);
      display.drawPixel(127, 63, WHITE);
      // display a line of text
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(20, 18);
      display.print("Welcome");
      display.setCursor(25, 40);
      display.print("San");

      // update display with all of the above graphics
      display.display();
    }
    void loop() {
      // put your main code here, to run repeatedly:
      float h = dht.readHumidity();
      float t = dht.readTemperature();
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 1);
      display.print("Showing Temperature");
      // display Temperature
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(1, 18);
      display.print("T : ");
      display.print(t);
      display.setTextSize(1);
      display.print((char)247);
      display.setTextSize(2);
      display.print("C");
      display.setCursor(1, 40);
      display.print("H : ");
      display.print(h);
      display.print(" %");
      // update display with all of the above graphics
      display.display();
    }

After uploading code it does will display NaN but when I open serial monitor it works fine displaying actual values from DHT22  :o

below is the fritzing of the hookup, I do not have witty cloud in fritzing, so I have used wemos D1Mini instead. on wemos d1 mini 3v3 is VCC on witty cloud dev board.

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

It looks like loop function doesn't execute by itself unless I open the serial monitor, why is it so? please help

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

title: Why do I have to open Serial Monitor to display what is in loop function?

Answers: 2

body:
Hard to tell from your fritzing which actual ESP8266 pin you are using, but you require a pull up resistor on the data line of the DHT22.

My guess is that you are using one of the serial UART pins for the data connection, and opening the serial monitor activates the output of the onboard UART chip which then acts as your missing pullup resistor.

body: Serial monitor sends a RESET signal during its initialization - maybe this is the problem. Sometimes these Witty boards need an implicit RESET after power up / programming.


body:
I am making a program to use a rotary encoder instead of a button in the buttoncycler example in the Adafruit NeoPixel library.

I am using the US Digital S1-256-250-IE-B-D. Datasheet can be found here:
https://cdn.usdigital.com/assets/datasheets/S1_datasheet.pdf?k=636466553771569761

    #include < RotaryEncoder.h >
    void setup() {
    }
    void loop() {
   static int change =  0;
   static int pos = 0;
   static int oldPos = 0;
   //Read the Encoder's state
   encoder.tick();
   int enc = encoder.getPosition();
   pos = abs(enc) % 2;
      change = oldPos-pos;
   if (change != 0) {

     switch (pos) {
    case 0:
    //do a program that lasts 5 seconds
    break;
    case 1:
    //do a program that lasts 5 seconds
    break;
     }
  oldPos = pos;
  change = 0;
   }
    }
I was wondering if there is a way to change the program immediately after turning the rotary encoder, instead of having to wait for the program to complete.

title: How can I make a rotary encoder change between neopixel programs?

Answers: 2

body:
Your code (if it worked) is right.  All you need to do is turn the comments into function calls:

    #include <RotaryEncoder.h>

    // Define global variables
    int pos = 0;
    int oldPos = 0;

    void setup() {
    // Do stuff
    }

    void loop() {
      //Read the Encoder's state
      encoder.tick();
      pos = encoder.getPosition();
      const int change = (oldPos - abs(pos)) % 2;
      switch (change)
      {
          case 0:
            programOne();
            break;
          case 1:
            programTwo()
            break;
        }
        oldPos = pos;
      }
    }

    void programOne()
    {
    //Do Stuff
    }
    void programTwo()
    {
    // Do stuff
    }

body:
> I was wondering if there is a way to change the program immediately
> after turning the rotary encoder, instead of having to wait for the
> program to complete.

There is, but it's not completely trivial. The reason it is not trivial
is each animation is implemented as a function that takes a while to
execute. For doing what you ask, each of these animations should be
modified, with a way to exit early if needed.

One approach would be to manage the rotary encoder using an interrupt. I
let you investigate how to do that: you probably can find examples on
the Web. Once the encoder reading is interrupt-based, you would need to
do the following changes in your program:

At global scope, add

<!-- language-all: lang-c++ -->

    volatile bool stop_now = false;

This will be a sort of “flag” intended to inform the currently running
animation that it should return ASAP.

Then, inside the interrupt handler, add

    stop_now = true;

In loop(), just after `if (change != 0) {`, add

    stop_now = false;

In *each* animation, replace `delay(wait)` with:

    uint32_t start_time = millis();
    while (millis() - start_time < wait) {
        if (stop_now)
            return;
    }


body:
Every time I try to compile a program written in Arduino IDE 1.8.5 for NodeMCU (LoLIN version v3), I get the following error:

<!-- language: lang-none -->

    Arduino: 1.8.5 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"

    C:\Users\sumeetpatil\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-ar: unable to rename 'C:\Users\SUMEET~1\AppData\Local\Temp\arduino_build_831529/arduino.ar'; reason: File exists

    exit status 1
    Error compiling for board NodeMCU 1.0 (ESP-12E Module).

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

I have tried reinstalling several times, but I just can't get ahead of this step.

title: Arduino Sketch: NodeMCU compilation error

Answers: 1

body:
> Do a full uninstall of Arduino, then delete the Arduino folder and
> Arduino15 (back them up first if you have any sketches in there!!!!),
> as well as **any Arduino folders under Temp**. Make sure the folders and
> all contents are really gone, reboot and try again if not. Then, do a
> clean install of the IDE.

Cited from [here][1].

  [1]: https://github.com/esp8266/Arduino/issues/2987


body:
I have bought a NodeMCU (1.0) and a JSN-SR04T waterproof ultrasonic sensor compatible with HC-SR04.

If I upload my program to NodeMCU it works but sometimes it measures a wrong distance - it is an another question, but it may connect to this question.

If I press the reset button my application not starts or if it is unplugged and plugged in to usb power it not starts.

If I unplug the ultrasonic sensor 3.3V and ground it starts.

It starts with the following code:

    const int trigPin = D4;
    const int echoPin = D3;

    void flashLed() {
      digitalWrite(LED_BUILTIN, LOW);
      delay(400);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
    }

    void setup() {

      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
      pinMode(echoPin, INPUT); // Sets the echoPin as an Input

      flashLed();
      Serial.begin(115200);
      flashLed();
      delay(10);

      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        digitalWrite(LED_BUILTIN, HIGH);
        delay(1000);
        digitalWrite(LED_BUILTIN, LOW);
        delay(1000);
      }
      Serial.println("");
      Serial.println("WiFi connected");

      server.begin();

      Serial.println("Web server running. Waiting for the ESP IP...");
      delay(10000);

      Serial.println(WiFi.localIP());

      digitalWrite(LED_BUILTIN, HIGH);

    }

I have uploaded the full source code to github project:

https://github.com/kisdaniel/nodemcu-wif-http-HC-SR04/blob/master/HomeDashboardUltrasonicHttp.ino

Why it not starts?

**UPDATE:**

I have make a minimal version of code to reproduce the problem:

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
    }

    void loop() {
      digitalWrite(LED_BUILTIN, LOW);
      delay(1000);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(2000);
    }

Wiring:

    Node MCU 3.3V -  Vcc (ultrasonic sensor)
    Node MCU GND  -  GND (ultrasonic sensor)
    Node MCU D4   -  Trigger (ultrasonic sensor)
    Node MCU D3   -  Echo (ultrasonic sensor)

title: JSN-SR04T-2.0 with NodeMCU not starts after reset or reconnect usb power

Answers: 2

body:
> To enable ESP8266 firmware flashing GPIO0 pin must be pulled low
> before the device is reset. Conversely, for a normal boot, GPIO0 must
> be pulled high or floating.

The D3 pin is equivalent  GPIO0. For a normal boot, GPIO0 must be pulled high or floating while powering up or resetting the module. After that (normal boot), you can use the output for other purposes.

You can use a different output or try to use a pull-up resistor for the D3.

body:
I had the same problem. Eventually I worked out what was going wrong with the information at "[Startup Guide for ESP8266 NodeMCU WeMos][1]"

It explains -
"Using GPIO0 (D3), GPIO2 (D4) and GPIO15 (D8) can be bit tricky. There are certain reasons, for example, GPIO0 (D3) and GPIO2 (D4) are pulled HIGH (PULL-UP Resistor) for normal start up of ESP8266 while GPIO15 (D8) is pulled LOW (PULL-DOWN Resistor). It is recommended to not use these pins as INPUT."

The problem happens when one of the NodeMCU pins that goes HIGH in startup - D3 and D4 - is connected to the "ECHO" pin of the JSN-SR04T sensor while the supply and ground pins are connected. The "ECHO" pin has low impedance and reduces the voltage on either D3 or D4 to about 1 Volt. This prevents the NodeMCU from rebooting.

The problem doesn't happen if the D3 or D4 pin is connected to the "TRIGGER" pin of the JSN-SR04T sensor because it has high impedance and doesn't reduce the voltage on the NodeMCU pin connected to it.

This matches what the article I found recommended: using D3, D4 and D8 for OUTPUT is OK, but it is recommended to not use them for INPUT.

  [1]: https://hobbytronics.pk/startup-guide-esp8266/


body:
I'm trying to upload a script to my arduino uno (mega and nano doesn't work either). It works unless I `#include <Adafruit_SSD1306.h>`

    #include <Arduino.h>
    #include <Adafruit_GFX.h>
    #include <SimpleDHT.h>
    #include <Adafruit_SSD1306.h>

    #define OLED_RESET  4

    Adafruit_SSD1306 display(OLED_RESET);

    // initializing foo here. const static unsigned char foo_bits[] PROGMEM = {0x00, 0x00 ///

    void draw(void) {
        display.drawXBitmap( 0, 0,foo_bits, foo_width, foo_height, 1);
        display.display();
    }

    void setup(void) {
        display.begin();
        display.clearDisplay();
    }

    void loop(void) {
        draw();
    }

The error I'm getting is

    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `Adafruit_SSD1306::ssd1306_command(unsigned char)':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `TwoWire::beginTransmission(int)'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `TwoWire::write(unsigned char)'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `TwoWire::write(unsigned char)'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `TwoWire::endTransmission()'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `Adafruit_SSD1306::begin(unsigned char, unsigned char, bool)':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::begin()'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `SPIClass::beginTransaction(SPISettings)':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::interruptMode'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::interruptMode'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::interruptSave'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::interruptMask'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `SPIClass::interruptSave'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `Adafruit_SSD1306::begin(unsigned char, unsigned char, bool)':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:416: undefined reference to `TwoWire::begin()'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `Adafruit_SSD1306::display()':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:472: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:472: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:472: undefined reference to `TwoWire::beginTransmission(int)'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `TwoWire::write(int)':
    /opt/arduino/hardware/arduino/avr/libraries/Wire/src/Wire.h:78: undefined reference to `Wire'
    /opt/arduino/hardware/arduino/avr/libraries/Wire/src/Wire.h:78: undefined reference to `Wire'
    /opt/arduino/hardware/arduino/avr/libraries/Wire/src/Wire.h:78: undefined reference to `TwoWire::write(unsigned char)'
    libuno_Adafruit_SSD1306.a(Adafruit_SSD1306.cpp.obj): In function `Adafruit_SSD1306::display()':
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:475: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:475: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:475: undefined reference to `TwoWire::write(unsigned char)'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:479: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:479: undefined reference to `Wire'
    /opt/arduino/arduino-1.8.5/libraries/Adafruit_SSD1306/Adafruit_SSD1306.cpp:479: undefined reference to `TwoWire::endTransmission()'
    collect2: error: ld returned 1 exit status

My cMake file is

    cmake_minimum_required(VERSION 2.8.4)
    set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
    set(PROJECT_NAME touch)
    project(${PROJECT_NAME})
    include_directories(/opt/arduino/arduino-1.8.5/libraries/)
    set(${CMAKE_PROJECT_NAME}_SKETCH touch.ino)

    set(${CMAKE_PROJECT_NAME}_BOARD uno)
    set(${CMAKE_PROJECT_NAME}_PORT /dev/ttyACM0)
    generate_arduino_firmware(${CMAKE_PROJECT_NAME})

If I remove all of the `Adafruit_SSD1306` uploading works. The exact same program works from Arduino IDE. What could be the cause and how can I fix this?

title: Can't upload to arduino from clion

Answers: 0


body:
Im using an Arduino Uno - All code at github.com/robbrad/AirQuality

Current sketch usage:

    Sketch uses 23186 bytes (71%) of program storage space. Maximum is 32256 bytes.
    Global variables use 1428 bytes (69%) of dynamic memory, leaving 620 bytes for local variables. Maximum is 2048 bytes.

I wouldn't normally just spam code for a optimisation - but im looking to get about 10% memory back from this sketch

It basically checks a bunch of sensors sets the values to floats, build a string and posts that to a php page where some more processing happens.

I have tried everything to my knowledge but I just cant think of a smarter way to use less memory.

I tried an array, a function to build the data string, using one float and concatenating it to the string when it set

I even thought of reducing the Math.h include to just the math functions I was using

Maybe im just reaching the little boards limits (which are pretty good anyway :) ! )

    #include <SPI.h>
    #include <Ethernet.h>
    #include "DHT.h"
    #include <math.h>
    #include <Wire.h>
    #include "MutichannelGasSensor.h"
    #include "HP20x_dev.h"
    #include "KalmanFilter.h"

    unsigned char ret = 0;

    /* Instance */
    KalmanFilter t_filter;    //temperature filter
    KalmanFilter p_filter;    //pressure filter
    KalmanFilter a_filter;    //altitude filter

    // Enter a MAC address for your controller below.
    // Newer Ethernet shields have a MAC address printed on a sticker on the shield
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    // if you don't want to use DNS (and reduce your sketch size)
    // use the numeric IP instead of the name for the server:
    IPAddress server(192, 168, 0, 30); // numeric IP for Google (no DNS)
    //char server[] = "www.google.com";    // name address for Google (using DNS)

    // Set the static IP address to use if the DHCP fails to assign
    IPAddress ip(192, 168, 0, 40);

    // Initialize the Ethernet client library
    // with the IP address and port of the server
    // that you want to connect to (port 80 is default for HTTP):
    EthernetClient client;

    #define Vc 4.95
    //the number of R0 you detected just now
    #define R0 35.54
    #define DHTPIN A1     // what pin we're connected to

    // Uncomment whatever type you're using!
    //#define DHTTYPE DHT11   // DHT 11
    #define DHTTYPE DHT22   // DHT 22  (AM2302)
    //#define DHTTYPE DHT21   // DHT 21 (AM2301)

    DHT dht(DHTPIN, DHTTYPE);

    int pin = 8;
    unsigned long duration;
    unsigned long starttime;
    unsigned long sampletime_ms = 2000;//sampe 30s ;
    unsigned long lowpulseoccupancy = 0;
    float ratio = 0;
    float concentration = 0;
    String data = "";

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

      delay(150);
      HP20x.begin();
      delay(100);

      /* Determine HP20x_dev is available or not */
      ret = HP20x.isAvailable();

      pinMode(8, INPUT);
      starttime = millis();//get the current time;
      //Serial.println("power on!");

      pinMode(4, OUTPUT);
      digitalWrite(4, HIGH);

      //if (Ethernet.begin(mac) == 0) {
      //  Serial.println("Failed to configure Ethernet using DHCP");
      // try to congifure using IP address instead of DHCP:
      Ethernet.begin(mac, ip);

      // give the Ethernet shield a second to initialize:
      delay(10000);
      // Serial.println("connecting...");
      //}
      // give the Ethernet shield a second to initialize:
      //delay(1000);
      //Serial.println("connecting...");

      // Serial.println(Ethernet.localIP());

      gas.begin(0x04);//the default I2C address of the slave is 0x04
      gas.powerOn();
      //Serial.print("Firmware Version = ");
      //Serial.println(gas.getVersion());
      //Serial.println("Particles\tRS\tHCHO (PPM)\tNH3 (PPM)\tCO (PPM)\tNO2     (PPM)\tC3H8 (PPM)\tC4H10 (PPM)\tCH4 (PPM)\tH2 (PPM)\tC2H5OH (PPM)");
      dht.begin();
      delay(10000);

    }

    void loop() {

      if (client.available()) {
        char c = client.read();
        //  Serial.print(c);
      }

      float HATemp2;
      float HAPres2;
      float HAAlt2;
      float d;

      if (OK_HP20X_DEV == ret)
      {
        unsigned long HATemp = HP20x.ReadTemperature();
        d = HATemp / 100.0;
        HATemp2 = t_filter.Filter(d);

        unsigned long HAPres = HP20x.ReadPressure();
        d = HAPres / 100.0;
        HAPres2 = p_filter.Filter(d);

        unsigned long HAAlt = HP20x.ReadAltitude();
        d = HAAlt / 100.0;
        HAAlt2 = a_filter.Filter(d);

      }

      duration = pulseIn(pin, LOW);
      lowpulseoccupancy = lowpulseoccupancy + duration;

      if ((millis() - starttime) >= sampletime_ms) //if the sampel time = = 30s
      {
        ratio = lowpulseoccupancy / (sampletime_ms * 10.0); // Integer percentage 0=>100

        d = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve
        //Serial.print("concentration = ");

       lowpulseoccupancy = 0;
        starttime = millis();
      }

     //Serial.print("\t");
      //HCHO

      int sensorValue = analogRead(A0);
      double Rs = (1023.0 / sensorValue) - 1;

      double ppm = pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
      //Serial.print("HCHO ppm = ");

      //MultiChannel Gas
      float NH3 = gas.measure_NH3();
      float CO = gas.measure_CO();
      float NO2 = gas.measure_NO2();
      float C3H8 = gas.measure_C3H8();
      float C4H10 = gas.measure_C4H10();
      float CH4 = gas.measure_CH4();
      float H2 = gas.measure_H2();
      float C2H5OH = gas.measure_C2H5OH();

      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      float t = dht.readTemperature();

      data = String("dust=") + d + "&rs=" + Rs + "&hcho=" + ppm + "&nh3=" + NH3 + "&co=" + CO + "&no2=" + NO2 + "&c3h8=" + C3H8 + "&c4h10=" + C4H10 + "&ch4=" + CH4 + "&h2=" + H2 + "&c2h5oh=" + C2H5OH + "&temp=" + t + "&hum=" + h + "&HATemp=" + HATemp2 + "&HAPres=" + HAPres2 + "&HAAlt=" + HAAlt2;

      //Serial.println(data);

      if (client.connect(server, 80)) {
        Serial.println(F("connected"));
        client.println(F("POST /air_add.php HTTP/1.1"));
        client.println(F("Host:  192.168.0.30"));
        client.println(F("User-Agent: Arduino/1.0"));
        client.println(F("Connection: close"));
        client.println(F("Content-Type: application/x-www-form-urlencoded;"));
        client.print(F("Content-Length: "));
        client.println(data.length());
        client.println();
        client.println(data);
      }
      else
      {
        Serial.println(F("could not connect"));
      }

      Serial.println(data);

      if (client.connected()) {
        client.stop();
      }

      delay(300000);
    }

title: Reducing Memory Usage lots of Floats

Answers: 3

body:
Two basic approaches:

1) use fixed point math. or

1) use int16_t or int32_t in lieu of the floating types. for example, you can use x10 or x100 to designate variables with some decimal points. use x16 or x128 or even x256 for speed gains as well. you will need to make sure that it doesn't overflow.

edit: here is an example that hopefully will help you get it going.

    void setup() {
     Serial.begin(9600);
     var1=100;    //var1=1.00
     var2=123;    //var2=1.23
    }

    void loop() {
     var1+=var2;    //increment var1
     Serial.print("var1 = "); Serial.print(var1 / 100); Serial.print("."); Serial.print(var1 - (var1 / 100) * 100); Serial.println(".");
     delay(100);
    }

var1 (1.00 initially) is incremented by var2 (1.23), both are int32_t types.

here is the printout.

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

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

body:
I second the advice that has already been given to you about avoiding
`String`. Other than that, using fixed-point math could be a big win,
but given the math you do it won't be any easy.

Assuming you stick with floating point, I just found a couple of easy
optimization opportunities:

* Do not use `pow` to evaluate a polynomial. Use the [Horner's
  method](https://en.wikipedia.org/wiki/Horner's_method) which is way
  cheaper: `d = ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62`.
* The expression of ppm can be simplified:
  `ppm = 2500.33 * pow(Rs, -2.0803)`.

------------------------------------------------------------------------

**Edit**: You could also try to implement [chunked transfer
encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding). This
way you could send the data to the server on the fly, as you collet it,
instead of storing everything in memory and sending it in one go.

Example:

<!-- language-all: lang-c++ -->

    void send_chunk(Print &connection, const String &chunk)
    {
        connection.println(chunk.length, 16);
        connection.println(chunk);
    }

    void loop() {
        // ...

        // last header sent to the client:
        client.println(F("Transfer-Encoding: chunked"));
        client.println();

        // Now the data:
        String chunk;
        chunk = "dust=";
        chunk += ((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62;
        send_chunk(client, chunk);
        chunk = "&rs=";
        chunk += Rs;
        send_chunk(client, chunk);
        chunk = "&hcho=";
        chunk += 2500.33 * pow(Rs, -2.0803);
        send_chunk(client, chunk);
        chunk = "&nh3=";
        chunk += gas.measure_NH3();
        send_chunk(client, chunk);
        // and so on...
        chunk = "";
        send_chunk(client, chunk);  // Empty chunk means end of message.

        // ...
    }

Notice that there is no "Content-Length" header. Instead, each chunk is
preceded by its size in hex. And, most importantly, notice that this way
you can get rid of lots of variables.

------------------------------------------------------------------------

**Edit 2**: I came out with a better (more generic) way to implement
chunked encoding, which involves sending the data through a “chunker”
filter that does the encoding and outputs to the client. Here is my
`Chunker` class:

    /*
     * Transfer a message using the HTTP/1.1 "Chunked Transfer Coding".
     * C.f. https://tools.ietf.org/html/rfc7230#section-4.1
     */
    class Chunker : public Print
    {
    public:
        Chunker(Print &downstream) : downstream(downstream), pos(0) {}

        virtual size_t write(uint8_t c)
        {
            buffer[pos++] = c;
            if (pos == BUFFER_SIZE)
                send();
            return 1;
        }

        void end()
        {
            if (pos) send();
            send();  // empty chunk means end of message
        }

    private:
        static const uint8_t BUFFER_SIZE = 32;
        Print &downstream;
        uint8_t buffer[BUFFER_SIZE];
        uint8_t pos;

        // Send the buffer as a chunk.
        void send()
        {
            downstream.println(pos, HEX);
            if (pos) {
                downstream.write(buffer, pos);
                downstream.println();
                pos = 0;
            }
        }
    };

And here is how you would use it:

    Chunker message(client);  // instantiate the filter
    message.print(F("dust="));
    message.print(((1.1*ratio - 3.8)*ratio + 520)*ratio + 0.62);
    message.print("&rs=");
    message.print(Rs);
    message.print(F("&hcho="));
    message.print(2500.33 * pow(Rs, -2.0803));
    message.print(F("&nh3="));
    message.print(gas.measure_NH3());
    // and so on...
    message.end();  // terminate the chunked message

The main advantage of this method is that you completely avoid using the
`String` class, which means no dynamic memory allocation (a very
desirable thing). Also you can choose your buffer size. I've set it to
32 bytes, but you can make it smaller if needed.

body:
I counted the floats in the sketch:

    Global: 2
    setup: 0
    loop: 14
    Total: 16 floats -> 64 bytes.

If you want to reduce that, don't wait to have all your values before preparing your answer. You will use less memory if you do

      data = String("dust=") + dht.readHumidity();
      data+= "&rs=" + (1023.0 / sensorValue) - 1;
      data+= "&hch0=" + pow(10.0, ((log10(Rs / R0) - 0.0827) / (-0.4807)));
      ... and the rest ...

Your `data` String and concat's take way more space than the floats. Use char[] instead of string.

As last resort, you don't need to construct the complete POST before sending it to the server. Send it line by line, value by value. Use a fixed, big enough `Content-Length: `,  padding with spaces after you send the values and know the actual lenght.

Or you can switch your technology: MQTT need way less memory than HTTP.


body:
I think I forgot the reason for this SFR manipulation in microcontrollers; like, checking the TWSR in twi.

The technique for checking the values of the TWSR is by masking it with another variable or a value.

So, why not checking the TWSR directly in; for example, switch function for checking the values of TWSR?

Like, `switch (TWSR)`

instead of

`uint8_t Status;
  Status = TWSR & 0xF8;
  switch(Status)`

Or, substitute it in any function; like, `Serial.println(TWSR);` or `digitalRead(TWSR);`. DO I have to mask it? If so then why?

title: Why it's not possible to manipulate the TWSR directly?

Answers: 2

body: The mask is a must, because bit 0 and bit 1 are I2C clock speed bits and they are changeable between different I2C clock speed configurations.

body:
> Why it's not possible to manipulate the TWSR directly?
i2c c switch

Because your premise is wrong: it is routinely done to manipulate twsr directly.

As to the use of masks, well, because sometimes you only care about certain bits but not others. So you mask away those that you don't want.

Just that simple.