body:
Background: When working on the 2 modules separately they were working perfectly.

Problem: In the code attached we tried integrating them but Lora wouldn't receive any data unless we commented out parts of the SDC function. Is there a fix to this?

This is where the problem occurs:

```
Serial.print("Data received: ");
 Serial.print(received);

 if(received=="ANEMO"){
```
No matter how much we feed it with TRUE data from another Lora with these codes it simply shows blank and false.

Please Help this poor lamb. This for our school project. Hopefully, you can spare me some of your time. Thank you so much in advance.

for the CS pins:
Lora: pin 10,  SD: pin 5

other SPI pins follow the standard pins.

PS: In the code, we have commented out some of the lines within the SDC function as based on our observation:
```
myFile = SD.open("HG.txt", FILE_WRITE);
   myFile.close();
```
These 2 lines are the ones causing our Lora to not display the data it is receiving in the (String receive variable).

Thank you, good sir/ma'am, once again hopefully you can assist me.

Here is the complete code:

```
#include <SPI.h>
#include <SD.h>
#include <RH_RF95.h>
#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2
#define RF95_FREQ 868.0
RH_RF95 rf95(RFM95_CS, RFM95_INT);
unsigned long millisecs;
int cnt;
float valu;
String jh;
int code=1;
String received;

File myFile;

void setup(){
 Serial.begin(115200);
 if (!SD.begin(5)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  else{
  Serial.println("card initialized.");
  }

  delay(100);

 pinMode(RFM95_RST, OUTPUT);
 digitalWrite(RFM95_RST, HIGH);
 while (!Serial);
 Serial.println("Arduino LoRa RX Test!");
 digitalWrite(RFM95_RST, LOW);
 delay(10);
 digitalWrite(RFM95_RST, HIGH);
 delay(10);
 while (!rf95.init()) {
 Serial.println("LoRa radio init failed");
 while (1);
 }
 Serial.println("LoRa radio init OK!");
 if (!rf95.setFrequency(RF95_FREQ)) {
 Serial.println("setFrequency failed");
 while (1);
 }
 Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
 rf95.setTxPower(23, false);
}

void lorA(){
  while(code==1){
if (rf95.waitAvailableTimeout(1000)){
 Serial.println("dayun ");
 uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
 uint8_t len = sizeof(buf);
 if (rf95.recv(buf, &len)){
 cnt++;
 Serial.print("Data number: ");
 Serial.println(cnt);
 received=(char*)buf;
 Serial.print("Data received: ");
 Serial.print(received);

 if(received=="ANEMO"){
 uint8_t data[] = "And hello back to you";
 rf95.send(data, sizeof(data));
 rf95.waitPacketSent();
 Serial.println("Sent a reply");
 code=0;
 }
 }
 else{
 Serial.println("Receive failed");
 }
 }
 }
 }

void SDC(){
  while(code==0){
  Serial.println("SDC");
//  File dataFile = SD.open("HG.txt", FILE_WRITE);
//  String dataString="Hans";
//  if (dataFile) {
//  dataFile.println(dataString);
//  dataFile.close();
//    Serial.println("closed");
//    Serial.println(dataString);
    code=1;
//  }
//  else {
//    Serial.println("error opening datalog.txt");
//  }

  }
  }

void loop(){
  Serial.println("loop");
  lorA();
  Serial.println("mid");
  SDC();
}
```

title: SD Card and Lora module arduino uno

Answers: 1

body:
all of your problem can be solved through a simple trick ... Just follow it...

1. Use Sdfat library insted of SD
2. just follow SPI datasheet..

follow below code ... it works with LORA AND SD both together

    ...

    #include <SdFat.h>
    #include <SPI.h>
    #include <RHReliableDatagram.h>
    #include <RH_RF95.h>

    SdFat sd;
    SdFile myFile;

    #define chipSelect 4

    #define RFM95_CS 10 //
    #define RFM95_RST 9
    #define RFM95_INT 2

    // Singleton instance of the radio driver
    RH_RF95 rf95(RFM95_CS,RFM95_INT);
    //RH_RF95 driver(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W

    // Class to manage message delivery and receipt, using the driver declared above
    RHReliableDatagram manager(rf95, 2);

    void setup() {

      Serial.begin(9600);
      while (!Serial) {}  // wait for Leonardo

      delay(100);

      // Initialize SdFat or print a detailed error message and halt
      // Use half speed like the native library.
      // change to SPI_FULL_SPEED for more performance.
      pinMode(RFM95_CS, OUTPUT);
      digitalWrite(RFM95_CS, HIGH);
      digitalWrite(4, LOW);

      if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

    /*

    /*
     * //Open file and write  ...
     *
      // open the file for write at end like the Native SD library
      if (!myFile.open("mrinmoy.txt", O_RDWR | O_CREAT | O_AT_END)) {
        sd.errorHalt("opening test.txt for write failed");
      }

      // if the file opened okay, write to it:
      Serial.print("Writing to test.txt...");
      myFile.println("testing 1, 2, 3.");

      // close the file:
      myFile.close();
      Serial.println("done.");
      */

      /*
      // open the file for reading....

      if (!myFile.open("mrinmoy.txt", O_READ))
      {
        sd.errorHalt("opening test.txt for read failed");
      }

      Serial.println("mrinmoy.txt:");

      // read from the file until there's nothing else in it:
      int data;

      while ((data = myFile.read()) >= 0) Serial.write(data);
      // close the file:
      myFile.close();
      */

      // manual reset
      digitalWrite(RFM95_RST, LOW);
      delay(10);
      digitalWrite(RFM95_RST, HIGH);
      delay(10);

      digitalWrite(RFM95_CS, LOW);
      digitalWrite(4,HIGH);

      while (!manager.init()) {
        Serial.println("LoRa radio init failed");
        while (1);
      }
      Serial.println("LoRa radio init OK!");

     // digitalWrite(RFM95_CS, LOW);

    }

    void loop()
    {
       uint8_t data[] = " Hi.. This is node 1.";
     //   unsigned char sd_data[50];
    // Dont put this on the stack:
     // uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
       uint8_t buf[50];
      // nothing happens after setup

      //LoRa.setPins( LoRa_CS, LoRa_RST, DI0 );
      digitalWrite(4,HIGH);    //  deselet SD Card SPI
      digitalWrite(RFM95_CS, LOW);    //  SELECT (low) LoRa SPI
      SPI.begin();

      // Send a message to manager_client
      if (manager.sendtoWait((uint8_t*)data,sizeof(data),1))
      {
        Serial.print("successfully sent to: ");
        Serial.println(1);
      }
      else
      {
        Serial.println("send failed");
      }

      // receiver ....

       // Now wait for a reply from the server
       uint8_t len = sizeof(buf);
       uint8_t from;

       if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
        {
          Serial.print("Got Response From : 0x");
          Serial.print(from, HEX);
          Serial.print(": ");
          Serial.println((char*)buf);
        }
        else
        {

        }
     //   digitalWrite(4, LOW);
       SPI.end();

       digitalWrite(4, LOW);    //  deselet SD Card SPI
       digitalWrite(RFM95_CS,HIGH);    //  SELECT (low) LoRa SPI
       SPI.begin();

     if (!myFile.open("mrinmoy.txt", O_READ))
      {
        sd.errorHalt("opening test.txt for read failed");
      }

      Serial.println("mrinmoy.txt:");
      char ch;
      String str;
      int i=0;
      uint8_t sd_data[50];

      while (myFile.available()>0)
      {
        ch= myFile.read();
        str+=ch;
      }

      String str2=str;
      Serial.println(str2);
      Serial.println(str2.length());

      myFile.close();
      SPI.end();

      delay(500);
    }

use this trick ... your system will work perfectly ...


body:
I have setup a MCP3002 to convert an analog signal to digital signal. When I read it directly through serial and convert it to a wav file, it sounds relative clear. Serial is limited for samples per second though, I can get about 7000 sps.

When I send the signal directly to a server I can reach around 17.500 sps. however when I convert this to a wav file, it also sounds relative clear, but with a slight distortion/'robot voice' through the audio.

Is there a simple way to prevent this, or why is this happening?

The code how I read the SPI is in this question:
[Reading data from MCP3002][1]

  [1]: https://arduino.stackexchange.com/questions/69573/reading-data-from-the-mcp3002

title: Distorted audio from mcp3002

Answers: 1

body:
From the code you linked to, it appears the SPI port is completely
controlled by the software:

```c++
void loop() {
    ...
    msb = SPI.transfer(cmd);
    lsb = SPI.transfer(0);
    ...
}
```

This means that the timing of the SPI transaction (when exactly it
starts) and, by extension, the timing of the ADC conversion, is
dependent on the timing of your code execution. You have no good control
on that timing. It depends on what other things may be in your loop, and
on the other interrupt sources (timers, network...).

The least you can do is set up a timer interrupt, and run the SPI from
the interrupt handler. Your timings should then be more consistent. You
will still have some jitter due to the interrupt handler being delayed
by some critical sections, including other interrupts. But it may be
good enough for your application.

For best results, you would ideally want the timing to be completely
controlled by hardware. Maybe there is a way to trigger the SPI port
from a timer. This depends on the specific MCU you are using: you will
have to dig into the datasheet.


body:
I bought a beginners kit and can get all but one of the examples to work. I have tried different board layouts and varied the code with no success. When I first run the code the LED is off. When I ground pin 9 the LED comes on and stays on. Grounding pin 8 does not turn off the LED once it is lit.

    int ledPin = 5;
    int buttonApin = 9;
    int buttonBpin = 8;

    byte leds = 0;

    void setup()
    {
      pinMode(ledPin, OUTPUT);
      pinMode(buttonApin, INPUT_PULLUP);
      pinMode(buttonBpin, INPUT_PULLUP);
    }

    void loop()
    {
      if (digitalRead(buttonApin) == LOW)
      {
        digitalWrite(ledPin, HIGH);
      }
      if (digitalRead(buttonBpin) == LOW)
      {
        digitalWrite(ledPin, LOW);
      }
    }

[![Circuit diagram][1]][1]

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

title: Arduino beginners kit example not working

Answers: 1

body:
This kind of button has 4 pins. These pins are internally connected in pairs. It's easy to make a mistake when wiring. Please post the real picture of your wiring. Or you can refer to read more about button pin [in this post][1]

  [1]: https://arduinogetstarted.com/tutorials/arduino-button#content_about_button


body:
I've been reading [this][1] post while trying to optimize the usage of the WiFi module on my ESP8266.

My main goal was to be able to connect/disconnect (respectively turn on/off) the WiFi module so I can optimize electricity consumption of the chip (I am trying to solar power it).

So, the way I integrated the proposed solution is as follows as I am no where calling deepSleep:

    #include <RelayModule.h>
    #include <ESP8266WIFI.h>
    #include <rdm6300.h>
    #include <string.h>
    #include <ctime>

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

    RelayModule relay(RELAY_PIN);
    Rdm6300 rdm6300;

    int relayTurnedOnAt = 0;

    void WiFiOn();
    void WiFiOff();

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

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

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

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

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

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

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

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

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

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

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

  [1]: https://arduino.stackexchange.com/questions/43376/can-the-wifi-on-esp8266-be-disabled

title: ESP8266 WiFi doesn't reconnect

Answers: 0


body:
i recently bought me an pulse-heartbeat sensor.
Connected him to my brand new M1 mini as well.

I wrote a piece of Code which just outputs the Raw ADC Value from A0 (where the pulse sensor is connected).

Now I'm confused.. When i open Serial Plotter, i get this:

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

Which is confusing because i don't get useable Values when putting the sensor up side down, which is the promoted way to do this (i guess!!)

When i press the other side against my wrist, i get this:
[![enter image description here][2]][2]
Which i can work with..

But it still doesnt look like some of those perfect diagrams on the internet.

Any can help me understand why i get this type of behaviour?

thanks, nice friday , luca

  [1]: https://i.stack.imgur.com/r7CMe.png
  [2]: https://i.stack.imgur.com/QIP54.png

title: Pulse Sensor Working Bottom-Side-Up Better?

Answers: 1

body:
From what I see, this is a pulse sensor that work with light. It emits a bright light beam, that is reflected by the pulsing blood. To work, it must send the light directed to your veins. It should work well on your finger, because the probability to target a vein directly is much greater with a small finger then e.g. a wide wrist. Also the veins in your finger are closer to your skin and the oxygen situation is more different while pulsing, so the blood has more impact on the reflection.

The second curve might be a light source in your room, or an electrical wave. (?) I doubt it is your heart, because, if the numbers below the graph are milliseconds, then your heartbeat would be between 10-15 beats / second, i.e. 600 - 900 per minute. That would be too much even for a hummingbird ;-).


body:
I am using an Arduino Pro Mini with various sensors.  I am powering it with 2 3.7v 3400mA batteries which I recharge with a solar panel.  I take a reading from the batteries and if the  reading is above a certain number I disconnect the solar panel from the batteries using a relay.  Then when the battery reading gets below a certain number I switch back on the solar panel using the same relay.  This all works fine.
To conserve energy I want to delay the loop to the Arduino's activities for say two hours.
Right now I call lowPower(); at the end of the loop{.
void lowPower(){ is

    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

Which I continually repeat for the two hours I want.
The problem is during this two hours the high or low limit of the battery charge could be reached but I wouldn't know it.

What I would like to do is repeat

    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

for 15 minutes and then check the batteries and turn on or off the solar charger as need.
Then repeat the whole thing until two hrs is reached.
At that point I would rerun the loop{ to check all sensors etc.
I have tried the following

       void loop(){
        //code to run other sensors etc.
        if (Delay ==4) {
      delay(180000);
    //check the battery to begin with
    sensorBatValue = analogRead(batteryInPin);
      delay(500);
    if(chargeSwitch ==1){
     if(sensorBatValue < batteryNoCharge) {
      }
     else if(sensorBatValue > batteryNoCharge) {
         digitalWrite(10,HIGH);
       delay(1000);
       digitalWrite(10,LOW);
       chargeSwitch = 2;
      }
       }
    else if(chargeSwitch ==2){
        if(sensorBatValue > batteryCharge) {
        }
        else if(sensorBatValue < batteryCharge) {
          digitalWrite(13,HIGH);
        delay(1000);
       digitalWrite(13,LOW);
       chargeSwitch = 1;
        }
      }
    //put to sleep
    lowPower();
    //check battery again
    delay(180000);//real
    sensorBatValue = analogRead(batteryInPin);
      delay(500);
    if(chargeSwitch ==1){
     if(sensorBatValue < batteryNoCharge) {
      }
     else if(sensorBatValue > batteryNoCharge) {
         digitalWrite(10,HIGH);
       delay(1000);
       digitalWrite(10,LOW);
       chargeSwitch = 2;
      }
       }
    else if(chargeSwitch ==2){
        if(sensorBatValue > batteryCharge) {
        }
        else if(sensorBatValue < batteryCharge) {
          digitalWrite(13,HIGH);
        delay(1000);
       digitalWrite(13,LOW);
       chargeSwitch = 1;
        }
      }
    // put to sleep
    lowPower();
    //repeat for total of 2 hours.
    }

     void lowPower(){
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        //repeat until 15 minutes is reached
    }

This doesn't seem to work.  The Arduino waits the correct time but from what I can tell the battery is never checked.

Or should I try

        void loop(){
        everything
        if (Delay ==4) {
      delay(180000);//real
      sensorBatValue = analogRead(batteryInPin);
      delay(500);
    if(chargeSwitch ==1){
     if(sensorBatValue < batteryNoCharge) {
      }
     else if(sensorBatValue > batteryNoCharge) {
         digitalWrite(10,HIGH);
       delay(1000);
       digitalWrite(10,LOW);
       chargeSwitch = 2;
      }
       }
    else if(chargeSwitch ==2){
        if(sensorBatValue > batteryCharge) {
        }
        else if(sensorBatValue < batteryCharge) {
          digitalWrite(13,HIGH);
        delay(1000);
       digitalWrite(13,LOW);
       chargeSwitch = 1;
        }
      }
        //include the checking of the battery inside the lowPower
        void lowPower(){
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        etc.
        LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
        //check battery after 15 min.
        delay(500);
           sensorBatValue = analogRead(batteryInPin);
        delay(500);
        if(chargeSwitch ==1){
         if(sensorBatValue < batteryNoCharge) {
         }
         else if(sensorBatValue > batteryNoCharge) {
             digitalWrite(10,HIGH);
           delay(1000);
           digitalWrite(10,LOW);
           chargeSwitch = 2;
          }
           }
        else if(chargeSwitch ==2){
            if(sensorBatValue > batteryCharge) {
           }
            else if(sensorBatValue < batteryCharge) {
              digitalWrite(13,HIGH);
            delay(1000);
           digitalWrite(13,LOW);
           chargeSwitch = 1;
            }
          }
        //then repeat to two hours
        }

Do I need to do something to wake up the Arduino and Turn on the battery sensor pin and turn back on ADC?

Not sure how to do this Please HELP.

title: wake from powerDown to check sensor then put back to sleep

Answers: 3

body: Try to use an external timer. I have the same problem approximatly.

body:
In your function `lowPower()`, instead of repeating the LowPower.powerDown(), loop over that call enough time to make up the total sleep-time you need. That's the general case. For your specific case, where you need 15-minute intervals and 2-hour intervals, `lowPower()` should loop 113 times (15:04, since 15 *60 doesn't divide evenly by 8). In your `loop()` function, loop over `lowPower()` 8 times (to make 2 hours), and each time it returns, check your battery. When the loop over `lowPower()` exits, it's time to do your "every 2 hours" jobs.

Because the 8s doesn't evenly divide 15 minutes, this timing isn't exact (but neither is the watchdog timer!), so you may want to tweak things a little, such as using a 4-second sleep, which does divide evenly.

Also, when I indented your code, I found `void lowPower()` nested inside the `loop()` function. C doesn't support that. If that was unintentional, check the pairing of your braces.

body:
You have to note that if you go in "power down" mode, you will not be able to get the time as `millis()` will return the wrong time.

If you just want 15 minutes, you can just put it inside a for loop:
```
for(int j=0;j<112;j++) LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
```
So the next instruction will be executed approximately after 15 minutes (15 * 60 / 8 = 112).

I made a similar project with a Teensy. With it you have more functions for the time. Just remember that with the power down, you will not be able to have any time function without an external time module on the Arduino.

Battery measurement schematics is also important. If you insert 2 resistors like 1M and 4M you will not be able to measure it since the measurement is done internally over multiple measurements and the current is not enough to measure it more than 1 time every 10-20ms. You have to add a capacitor to read a good value.


body:
    //INCLUDED LIBRARIES
     #include <GPRS_Shield_Arduino.h>
    #include <SoftwareSerial.h>
    #include <Wire.h>

    //SERIAL PIN ASSIGNMENT, BAUDRATE, PHONE NUMBER, MESSAGE
    #define PIN_TX    2
    #define PIN_RX    3
    #define BAUDRATE  9600
    #define PHONE_NUMBER "+639158848570"       //CELLPHONE NUMBER
    #define MESSAGE  "Notice: Please be informed that your area is under Level 1 advisory with 4-inches flood depth. Continuous flood is expected due to the heavy rainfall. Be prepared and secure your important documents and belongings in high places. Avoid wirings from getting wet to prevent further injuries and accidents."  //COMPOSE YOUR MESSAGE HERE
    #define MESSAGE_LENGTH <=500
    char MESSAGE1;

    //SERIAL PIN ASSIGNMENT, BAUDRATE, PHONE NUMBER, MESSAGE
    #define PIN_TX    2
    #define PIN_RX    3
    #define BAUDRATE  9600
    #define PHONE_NUMBER "+639379488989"       //CELLPHONE NUMBER
    #define MESSAGE  "Notice: Please be informed that your area is under Level 1 advisory with 4-inches flood depth. Continuous flood is expected due to the heavy rainfall. Be prepared and secure your important documents and belongings in high places. Avoid wirings from getting wet to prevent further injuries and accidents."  //COMPOSE YOUR MESSAGE HERE
    #define MESSAGE_LENGTH <=500
    char MESSAGE2;

    //SERIAL PIN ASSIGNMENT, BAUDRATE, PHONE NUMBER, MESSAGE
    #define PIN_TX    2
    #define PIN_RX    3
    #define BAUDRATE  9600
    #define PHONE_NUMBER "+639357120147"       //CELLPHONE NUMBER
    #define MESSAGE  "Notice: Please be informed that your area is under Level 1 advisory with 4-inches flood depth. Continuous flood is expected due to the heavy rainfall. Be prepared and secure your important documents and belongings in high places. Avoid wirings from getting wet to prevent further injuries and accidents."  //COMPOSE YOUR MESSAGE HERE
    #define MESSAGE_LENGTH <=500
    char MESSAGE3;

    char phone[16];
    char datetime[24];

    GPRS GSMTEST(PIN_TX,PIN_RX,BAUDRATE);//RX,TX,BAUDRATE

    void loop() {
          // read the output on digital pins:
      int Level1 = digitalRead(5);
      int Level2 = digitalRead(6);
      int Level3 = digitalRead(7);

      // print out the value you read:s
      if (Level1 != 0){
        Serial.print("Level 1 =  "); Serial.print(Level1); Serial.print("   ");
        sendSMS();
      }
      else if (Level2 != 0){
        Serial.print("Level 2 =  "); Serial.print(Level2); Serial.print("   ");
        sendSMS();
      }
      else if (Level3 != 0){
        Serial.print("Level 3 =  "); Serial.print(Level3); Serial.println("   ");
        sendSMS();
      }
      delay(1);//delay ms

    //void setup() {
    //  loop();
    //}

    void sendSMS() {
      Serial.begin(9600);
      while(!GSMTEST.init()) {
          delay(1000);
          Serial.print("INIT ERROR\r\n");
      }
      Serial.println("GSM INIT SUCCESS");
      Serial.println("START TO SEND MESSAGE ...");
      Serial.print("..");
      delay(1000);
      Serial.println(".....");
      delay(1000);

      GSMTEST.sendSMS(PHONE_NUMBER,MESSAGE); //DEFINE PHONE NUMBER AND TEXT

    }

    void readSMS(){
         //READ THE INCOMING SMS MESSAGE
       Serial.println("   ");
       Serial.println("   ");
       messageIndex = GSMTEST.isSMSunread();
       if (messageIndex > 0) { //AT LEAST, THERE IS ONE UNREAD SMS
          GSMTEST.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);
          //IN ORDER NOT TO FUL SIM Memory, IS BETTER TO DELETE IT
          GSMTEST.deleteSMS(messageIndex);
          Serial.print("FROM NUMBER: ");
          Serial.println(phone);
          Serial.print("DATE/TIME");
          Serial.println(datetime);
          Serial.print("RECEIVED MESSAGE: ");
          Serial.println(message);
       }
    }

title: Please help. Error message “sendSMS not declared in this scope” im frustrated. :(

Answers: 0


body:
I'm using Timer1 on the Attiny85 clocked at 1MHz to toggle an LED every 1 second. However, I'm having some issues regarding prescaler and OSC value selection.

I'm using this formula, which I found in the [datasheet][1] for the Attiny.
```
fOCnx = fclk/(2*N*(1+OCRnx))
```
N = Prescaler
I'm taking fOCnx = 0.5Hz as I want a square wave
So based on the above formula, I tried the following cases

 1. N = 2048, OCR1C = 243
 2. N = 4096, OCR1C = 122
 3. N = 8192, OCR1C = 61
 4. N = 16384, OCR1C = 30

The LED toggles after an interval of 1s for cases 3 and 4. However, for cases 1 and, it seems to toggle after 2 seconds. Can anyone tell me why this is happening? Eventually, I want to use this to time data acquisition from a sensor I have so I need to be accurate.

Here's my code

```c
#include <SoftwareSerial.h>

int ledPin = 1;
int state = 0;

SoftwareSerial ser(3, 4);
void setup() {
  // put your setup code here, to run once:
  TCCR1 |= 0x8F;
  OCR1C = 30;
  TIMSK = (1 << OCIE1A);
  pinMode(ledPin, OUTPUT);
  ser.begin(9600);
}

ISR(TIMER1_COMPA_vect)
{
  state = !state;
  digitalWrite(ledPin, state);
  ser.println(state);
}

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

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

title: Having trouble figuring out CTC on Timer 1 with ATTiny85

Answers: 1

body:
The only explanation I have is, that the Software serial switch off the interrupts globally when it operates (`print`). If interrupts are locked when the timer completes, you loose a tick. It does not explain the different behavior of the four value pairs, but there are some issues reported in a german forum. They did not find an answer, but the assumed it depends on the 'delay()' function, that is used for the software serial and the fact that the interrupts are locked to make the delay function more exact.

If you want to be sure, you can try this by completely removing the Software Serial from your program. If you make the values switchable by e.g. a button press you can change it without having to reload the program. Then it's easier to see different  blinking intervals.

    int ledPin = 1;
    int state = 0;

    int regValues[] = { 0x8f, 0x8e, 0x8d, 0x8c };
    int cntValues[] = { 30, 61, 122, 243 };

    const int buttonPin = 2;
    int buttonState = LOW;

    long lastDebounceTime = 0;
    long debounceDelay = 80;
    int lastButtonState = LOW;

    int pairIndex = 0;

    void setup()
    {
      TCCR1 = regValues[ pairIndex ];
      OCR1C = cntValues[ pairIndex ];

      TIMSK = (1 << OCIE1A);

      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT);
    }

    ISR(TIMER1_COMPA_vect)
    {
      state = !state;
      digitalWrite(ledPin, state);
    }

    void loop()
    {
      int reading = digitalRead(buttonPin);

      if (reading != lastButtonState)
      {
        lastDebounceTime = millis();
      }

      if ( (millis() - lastDebounceTime) > debounceDelay)
      {
       if (reading != buttonState)
       {
          buttonState = reading;

          if (buttonState == HIGH)
          {
            if ( ++pairIndex > 3 )
            {
              pairIndex = 0;
            }

            TCCR1 = regValues[ pairIndex ];
            OCR1C = cntValues[ pairIndex ];
          }

        }

      }

    }

I wrote this code without having a attiny to testing it. So hopefully all is correct. If you would try it, can you please report any errors, so I can correct them?


body:
I'm trying to get error_x and error_y to display the difference between the target and the position. For some reason I cannot get error_x to function correctly. error_y has the same code, but works correctly. Can anyone help?

Here is the code on my Arduino:

    void setup() {
      Serial.begin(9600);
      Serial.print("Starting...\n");
    }

    int previousTime = 0;
    float lastError_x = 0;
    float lastError_y = 0;

    void loop() {
      //pid variables
      float Kp = 1;
      float Ki = 0;
      float Kd = 0;
      float pos_x;
      float pos_y;
      float target_x;
      float target_y;
      float error_x;
      float error_y;
      int currentTime;
      int elapsedTime;
      float cumError_x;
      float cumError_y;
      float rateError_x;
      float rateError_y;
      float output_x;
      float output_y;

      //invkinematic variables
      float inVec[4] = {1, -1.5, 3};
      float height = 3.5;
      float B = 4;
      float L = 3;
      float U = 3.5;
      float plateRadius = 5.5;
      float alpha[4] = {0, 0, 0};
      float normVec[4];
      float p1[4] = {0,0,0};
      float p2[4] = {0,0,0};
      float p3[4] = {0,0,0};
      float crosskv[4] = {0,0,0};
      float normSave;
      float dotSave;
      float radius;
      float gamma;
      float beta;

      //serial variables
      char buf[32];
      char str_temp1[6];
      char str_temp2[6];
      char str_temp3[6];

      //PIXY CAMERA CODE (outputs x and y)

      pos_x = 1;
      pos_y = 1;

      //DETERMINE TARGET LOCATION
      //default:(0,0)
      target_x = 0;
      target_y = 0;

      //PID CODE (inputs x and y and outputs normal vector and height)

      error_x = target_x - pos_x;
      error_y = target_y - pos_y;

      dtostrf(error_x, 5, 3, str_temp1);
      dtostrf(error_y, 5, 3, str_temp2);
      sprintf(buf, "error1:%s error2:%s\n", str_temp1, str_temp2);
      Serial.print(buf);

      currentTime = millis();
      elapsedTime = currentTime - previousTime;
      if(elapsedTime==0){elapsedTime = 1;}

      cumError_x += error_x * elapsedTime / 1000;
      cumError_y += error_y * elapsedTime / 1000;
      rateError_x = (error_x - lastError_x)/(elapsedTime/1000);
      rateError_y = (error_y - lastError_y)/(elapsedTime/1000);

      output_x = Kp*error_x + Ki*cumError_x + Kd * rateError_x;
      output_y = Kp*error_y + Ki*cumError_y + Kd * rateError_y;

      inVec[0] = output_x/plateRadius;
      inVec[1] = output_y/plateRadius;
      inVec[2] = plateRadius;

      lastError_x = error_x;
      lastError_y = error_y;
      previousTime = currentTime;

      //INVKINEMATIC (inputs normal vector and height and outputs alpha values)

      normVec[0] = inVec[0]/(sqrt(inVec[0]*inVec[0]+inVec[1]*inVec[1]+inVec[2]*inVec[2]));
      normVec[1] = inVec[1]/(sqrt(inVec[0]*inVec[0]+inVec[1]*inVec[1]+inVec[2]*inVec[2]));
      normVec[2] = inVec[2]/(sqrt(inVec[0]*inVec[0]+inVec[1]*inVec[1]+inVec[2]*inVec[2]));

      p1[0] = normVec[2];
      p1[2] = -1*normVec[0];
      normSave = sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]);
      p1[0] = plateRadius*p1[0]/normSave;
      p1[1] = plateRadius*p1[1]/normSave;
      p1[2] = plateRadius*p1[2]/normSave;

      crosskv[0] = normVec[1]*p1[2] - normVec[2]*p1[1];
      crosskv[1] = normVec[2]*p1[0] - normVec[0]*p1[2];
      crosskv[2] = normVec[0]*p1[1] - normVec[1]*p1[0];
      dotSave = normVec[0]*p1[0] + normVec[1]*p1[1] + normVec[2]*p1[2];
      p2[0] = -0.5*p1[0] + crosskv[0]*0.866 + normVec[0]*dotSave*1.5;
      p2[1] = -0.5*p1[1] + crosskv[1]*0.866 + normVec[1]*dotSave*1.5;
      p2[2] = -0.5*p1[2] + crosskv[2]*0.866 + normVec[2]*dotSave*1.5;
      normSave = sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]);
      p2[0] = plateRadius*p2[0]/normSave;
      p2[1] = plateRadius*p2[1]/normSave;
      p2[2] = plateRadius*p2[2]/normSave;

      p3[0] = -0.5*p1[0] + crosskv[0]*-0.866 + normVec[0]*dotSave*1.5;
      p3[1] = -0.5*p1[1] + crosskv[1]*-0.866 + normVec[1]*dotSave*1.5;
      p3[2] = -0.5*p1[2] + crosskv[2]*-0.866 + normVec[2]*dotSave*1.5;
      normSave = sqrt(p3[0]*p3[0]+p3[1]*p3[1]+p3[2]*p3[2]);
      p3[0] = plateRadius*p3[0]/normSave;
      p3[1] = plateRadius*p3[1]/normSave;
      p3[2] = plateRadius*p3[2]/normSave;

      p1[2] = height+p1[2];
      p2[2] = height+p2[2];
      p3[2] = height+p3[2];

      radius = sqrt((p1[0]-B)*(p1[0]-B)+p1[1]*p1[1]+p1[2]*p1[2]);
      gamma = atan2(p1[2],sqrt((p1[0]-B)*(p1[0]-B)+(p1[1])*(p1[1])));
      beta = acos((L*L+radius*radius-U*U)/(2*L*radius));
      alpha[0] = 3.1416 - (gamma + beta);

      radius = sqrt((p2[0]+0.5*B)*(p2[0]+0.5*B)+(p2[1]-0.866*B)*(p2[1]-0.866*B)+(p2[2])*(p2[2]));
      gamma = atan2(p2[2],sqrt((p2[0]+0.5*B)*(p2[0]+0.5*B)+(p2[1]-0.866*B)*(p2[1]-0.866*B)));
      beta = acos((L*L+radius*radius-U*U)/(2*L*radius));
      alpha[1] = 3.1416 - (gamma + beta);

      radius = sqrt((p3[0]+0.5*B)*(p3[0]+0.5*B)+(p3[1]+0.866*B)*(p3[1]+0.866*B)+(p3[2])*(p3[2]));
      gamma = atan2(p3[2],sqrt((p3[0]+0.5*B)*(p3[0]+0.5*B)+(p3[1]+0.866*B)*(p3[1]+0.866*B)));
      beta = acos((L*L+radius*radius-U*U)/(2*L*radius));
      alpha[2] = 3.1416 - (gamma + beta);

      dtostrf(normVec[0], 5, 3, str_temp1);
      dtostrf(normVec[1], 5, 3, str_temp2);
      dtostrf(normVec[2], 5, 3, str_temp3);
      sprintf(buf, "a1:%s a2:%s a3:%s\n", str_temp1, str_temp2, str_temp3);
      Serial.print(buf);

      //OUTPUT alpha to servos

      delay(1000);
    }

Here is the output with the error:

    Starting...
    error1: error2:-1.000
    a1:  NAN a2:  NAN a3:

    error1: error2:-1.000
    a1: a2:-0.033 a3:

    error1: error2:-1.000
    a1: a2:-0.033 a3:

    error1: error2:-1.000
    a1: a2:-0.033 a3:

    error1: error2:-1.000
    a1: a2:-0.033 a3:

title: Trouble with PID code, variable error_x acting strange

Answers: 1

body: Consider enlarging your character arrays.  When creating strings an extra character is likely necessary to indicate the end of a string.  This is usually the null character or zero.  If missing, many string related features will not see an end of a string and likely cause unexpected results.


body: I'm trying to create a multimeter that measures resistance and capacitance for a school project and the code must be under 30 lines. I have made both a resistance meter and a capacitance meter but the only problem is that on for my resistance meter, ground is connected to the to the known resistor and the arduino's output goes through the unknown component. Where as my capacitance meter is the opposite (ground to unknown, output to known), just wondering if their is an easy fix or if i need to rethink my entire project. Any help is appreciated, thanks.

title: How to swap ground and power for multimeter

Answers: 0


body:
I have Arduino Mega and ESP-12F module.
Via AT commands I am on my wifi.

Now, I need to call my script on my pages.
Can you tell me how?
This command can conenct to my pages:
Serial3.print("AT+CIPSTART=0,\"TCP\",\"www.artware.cz\",80\r\n");
But that's all, I am not able to call the script.

Sorry, if this is dumb question.
Thank you

title: How to call a PHP script with Arduino?

Answers: 0


body:
I'm working to develop a simple code for MCP23017 that I want to use to run LCD128x64.

I was succeeded to set `IODIRB` as output and blink LED as a test.

Now I want to read the pin state, but I couldn't. Here's my code. I'm using the nice twi library that comes with Wire library.

    uint8_t mcp23017_read(uint8_t add_reg){
     uint8_t data;
     twi_writeTo(MCP23017_ADD,add_reg,2,1,0);
     twi_readFrom(MCP23017_ADD,data,1,1);

     return data;
    }

I've tried this version too:

    uint8_t *mcp23017_read(uint8_t add_reg){
     uint8_t data[1];
     twi_writeTo(MCP23017_ADD,add_reg,2,1,0);
     twi_readFrom(MCP23017_ADD,data,1,1);

     return *data;
    }

==================================================

Here's Arduino call function:

    void loop() {
      // put your main code here, to run repeatedly:
      data = mcp23017_read(GPIOB);
      Serial.println(data);
      delay(100);
    }

title: How to read input pin on MCP23017?

Answers: 2

body:
I don't know how this lib works. But I'm pretty sure that you have to pass a pointer onto the `data` variable into the `twi_readFrom` method.

    uint8_t mcp23017_read( uint8_t add_reg )
    {
        uint8_t data;
        twi_writeTo( MCP23017_ADD, add_reg, 2, 1, 0 );
        // I inserted an & below
        twi_readFrom( MCP23017_ADD, &data, 1, 1 );

        return data;
    }

Or in case of the second function:

    // I removed the star operator
    uint8_t mcp23017_read(uint8_t add_reg)
    {
        uint8_t data[1];

        twi_writeTo( MCP23017_ADD, add_reg, 2, 1, 0 );
        // you pass the pointer to the array element 0
        twi_readFrom( MCP23017_ADD, data, 1, 1 );

        // I returned the element 0
        return data[0];
    }

**Update:**

Just for completeness: The OP found also a failure on the write function. He had posted a separate answer, I voted up to mark it. Because this is the accepted answer, I also copied his post to here for completeness and the readers convenience.

Original post by R1S8K:

> OK, I found a the answer and it was a good lesson in dealing with
> functions that receives pointers.
>
> I forgot that the writeTo function also receives a pointer and I have
> to pass an array for both read/write functions.
>
>     void mcp23017_read(uint8_t *add_reg, uint8_t *buffer){
>         twi_writeTo(MCP23017_ADD, add_reg, 1, 1, 1);
>         twi_readFrom(MCP23017_ADD, buffer, 1, 1);
>     }

body:
OK, I found one little mistake in my coding.

I forgot that the `writeTo` function also receives a pointer and I have to pass an array for both read/write functions.

    void mcp23017_read(uint8_t *add_reg, uint8_t *buffer){
     twi_writeTo(MCP23017_ADD, add_reg, 1, 1, 1);
     twi_readFrom(MCP23017_ADD, buffer, 1, 1);
    }


body:
I have a project where I'm using the HX711 library with a loadcell to weigh in a fruit that is on a conveyor belt. Each fruit has a weight which needs to be classed. The bigger fruits (200g) are class A so they have to "fall down" the conveyor belt at a later stage. The smaller fruits fall down earlier. This has to be done on a timed basis.

What I want to do is get the fruit size , calculate the class (using weight) and then send an interrupt to the dropping mechanism after x time. But while it must wait to drop the next fruit will be have come in and might be smaller than the first.

I can already weigh in and calculate the class of fruits. I've also done this in C using multithreading but adruino uno doesn't support that.

I also have to mention that there is about 50-200 fruits on a single conveyor belt at any given time.

title: How to wait a certain time before doing something while running other code?

Answers: 1

body:
You can use timestamp to avoid the blocking code. See [BlinkWithoutDelay][1] example

  [1]: https://arduinogetstarted.com/tutorials/arduino-led-blink-without-delay


body:
So the code is working individually for temperature sensor and for heartbeat sensor but  when i combine it together it shows wrong values
for the temperature sensor

I'm using lm35 temperature sensor and powering by USB

    #include <LiquidCrystal.h>

    const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8;
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

    int pulsePin = A0;

    int blinkPin = 5;                // pin to blink led at each beat

    // Volatile Variables, used in the interrupt service routine!
    volatile int BPM ;                   // int that holds raw Analog in 0. updated every 2mS
    volatile int Signal;                // holds the incoming raw data
    volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
    volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
    volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

    static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

    volatile int rate[10];                      // array to hold last ten IBI values
    volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
    volatile unsigned long lastBeatTime = 0;           // used to find IBI
    volatile int P = 512;                      // used to find peak in pulse wave, seeded
    volatile int T = 512;                     // used to find trough in pulse wave, seeded
    volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
    volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
    volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
    volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

    const int sensor = A5;
    int tempc ;
    float vout;

    void setup()
    {
      vout =analogRead(sensor);
      pinMode(sensor,INPUT);
      pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
      Serial.begin(9600);             // we agree to talk fast!
      interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
                                      // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
                                        // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
                                        //   analogReference(EXTERNAL);
     lcd.begin(16, 4);
     lcd.clear();
    }

    //  Where the Magic Happens
    void loop()
    {

    lcd.setCursor(0,0);
    lcd.print(" T in c = ");
    lcd.print(tempc);
    lcd.setCursor(0,1);

    delay(100);
       serialOutput();

      if (QS == true) // A Heartbeat Was Found
        {
          // BPM and IBI have been Determined
          // Quantified Self "QS" true when arduino finds a heartbeat
          serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
          QS = false; // reset the Quantified Self flag for next time
          tempc=(vout*500)/1023;

        }

      delay(20); //  take a break
    }

    void interruptSetup()
    {
      // Initializes Timer2 to throw an interrupt every 2mS.
      TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
      TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
      OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
      TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
      sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
    }

    void serialOutput()
    {   // Decide How To Output Serial.
     if (serialVisual == true)
      {
         arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
      }
     else
      {
          sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
       }
    }

    void serialOutputWhenBeatHappens()
    {
     if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
       {

         int din ;
          din = analogRead(4);

         Serial.print(BPM);
         Serial.print(", ");
         Serial.print(tempc);
         Serial.print(", ");
         Serial.print(din);
         Serial.print(", ");

         Serial.println();
         lcd.setCursor(0,2);
         lcd.print("Heart-Beat Found ");
         lcd.setCursor(6,3);
         lcd.print(BPM);
         delay(100);
         lcd.clear();
       }
     else
       {
         sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
         sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
       }
    }

    void arduinoSerialMonitorVisual(char symbol, int data )
    {
      const int sensorMin = 0;      // sensor minimum, discovered through experiment
      const int sensorMax = 1024;    // sensor maximum, discovered through experiment
      int sensorReading = data; // map the sensor range to a range of 12 options:
      int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
      // do something different depending on the
      // range value:
    }

    void sendDataToSerial(char symbol, int data )
    {
       Serial.print(symbol);
       Serial.println(data);
    }

    ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
    {
      cli();                                      // disable interrupts while we do this
      Signal = analogRead(pulsePin);              // read the Pulse Sensor
      sampleCounter += 2;                         // keep track of the time in mS with this variable
      int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                                  //  find the peak and trough of the pulse wave
      if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
        {
          if (Signal < T) // T is the trough
          {
            T = Signal; // keep track of lowest point in pulse wave
          }
        }

      if(Signal > thresh && Signal > P)
        {          // thresh condition helps avoid noise
          P = Signal;                             // P is the peak
        }                                        // keep track of highest point in pulse wave

      //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
      // signal surges up in value every time there is a pulse
      if (N > 250)
      {                                   // avoid high frequency noise
        if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
          {
            Pulse = true;                               // set the Pulse flag when we think there is a pulse
            digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
            IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
            lastBeatTime = sampleCounter;               // keep track of time for next pulse

            if(secondBeat)
            {                        // if this is the second beat, if secondBeat == TRUE
              secondBeat = false;                  // clear secondBeat flag
              for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
              {
                rate[i] = IBI;
              }
            }

            if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
            {
              firstBeat = false;                   // clear firstBeat flag
              secondBeat = true;                   // set the second beat flag
              sei();                               // enable interrupts again
              return;                              // IBI value is unreliable so discard it
            }
          // keep a running total of the last 10 IBI values
          word runningTotal = 0;                  // clear the runningTotal variable

          for(int i=0; i<=8; i++)
            {                // shift data in the rate array
              rate[i] = rate[i+1];                  // and drop the oldest IBI value
              runningTotal += rate[i];              // add up the 9 oldest IBI values
            }

          rate[9] = IBI;                          // add the latest IBI to the rate array
          runningTotal += rate[9];                // add the latest IBI to runningTotal
          runningTotal /= 10;                     // average the last 10 IBI values
          BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
          QS = true;                              // set Quantified Self flag
          // QS FLAG IS NOT CLEARED INSIDE THIS ISR
        }
      }

      if (Signal < thresh && Pulse == true)
        {   // when the values are going down, the beat is over
          digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
          Pulse = false;                         // reset the Pulse flag so we can do it again
          amp = P - T;                           // get amplitude of the pulse wave
          thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
          P = thresh;                            // reset these for next time
          T = thresh;
        }

      if (N > 2500)
        {                           // if 2.5 seconds go by without a beat
          thresh = 512;                          // set thresh default
          P = 512;                               // set P default
          T = 512;                               // set T default
          lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
          firstBeat = true;                      // set these to avoid noise
          secondBeat = false;                    // when we get the heartbeat back
        }
      sei();
                                     // enable interrupts when youre done!
    }// end isr

title: Issue connecting heartbeat & temperature sensor on arduino uno but working individually

Answers: 3

body:
Code seems to lack a repeating update of tempc via

    vout =analogRead(sensor);

An alternative might be changing the line for setting tempc to be

    tempc=(int) (analogRead(sensor) * 500.0f/1023.0f);

body:
Why do you compute tempc only after you print out the value in serialOutputWhenBeatHappens`? You also forgot to read the temperature continuously.

Here is how I would do it:

    void loop()
    {
      // read the sensor before it is printed on the LCD
      vout  = analogRead( sensor );

      // here I'm not sure what you are computing
      // you map the sensor voltage to a range from 0°C to 500°C
      // do you measure the heartbeat and temperature of a dragon? ;-)
      // this formula is the same as yours
      tempc = ( vout / 1023.0 ) * 500.0;

      // I would also clear the LCD before I write to it
      lcd.clear();

      lcd.setCursor( 0, 0 );
      lcd.print( "T in c = " );
      lcd.print( tempc );
      lcd.setCursor( 0,1 );

      // There is no need to slow down the loop here.
      // let it run ...
      // delay(100);

      serialOutput();

      // A Heartbeat Was Found
      if (QS == true)
      {
         // BPM and IBI have been Determined
         // Quantified Self "QS" true when arduino finds a heartbeat
         // A Beat Happened, Output that to serial.
         serialOutputWhenBeatHappens();

         // reset the Quantified Self flag for next time
         QS = false;
      }

      // take a break (Why?)
      // delay(20);
    }

body:
If the provided source is cut down to the lines that have to do with the temperature, it is just this. If you try this sketch it should behave equally "wrong":

    const int sensor = A5;
    int tempc;
    float vout;

    void setup()
    {
        vout = analogRead(sensor);
        pinMode(sensor, INPUT);
    }

    void loop()
    {
        lcd.print(tempc);
        tempc = (vout * 500) / 1023;
    }

In `loop()` the value of `tempc` is printed *before* it is re-calculated from `vout`.

But `vout` is written to just one time in `setup()`.

So the "wrong" values you are talking about are **always the same value** which was measured at start-up time. (You did *not* mention *what* is wrong.)

---

*Note: Like documented in the Arduino's library reference, there is no need to set a pin to `INPUT` mode because it's the default.*

---

I read your comment on @Abel's answer and even watched your video. Since it's not clear what you did I can't say anything why you have jumping values now. (Please write some prose and show the new code in your question the next time.)

If we apply his advice the source will look like this. I removed the setting of the pin mode (see above) and made the sequence of instructions in `loop()` more logical.

    const int sensor = A5;
    int tempc;
    float vout;

    void setup()
    {
    }

    void loop()
    {
        vout = analogRead(sensor);
        tempc = (vout * 500) / 1023;
        lcd.print(tempc);
    }

This sketch will show the current temperature tracking the actual value. If *not* you have another problem independent of the interrupt and the heartbeat sensor.

---

*Additional notes:*

1. `analogRead()` returns an `int`. You assign it to a `float` so here is an implicit conversion.
1. This `float` is fine because you do the mapping "by hand." If you'd use `map()` it could be an `int`.
1. The result of the mapping expression is of type `float` and you assign it to an `int`. Here is another implicit conversion which removes the fractional part. This is OK because of the accuracy of the measurement.

---

Now to your assumption that the interrupts disturb the measurement of the temperature.

From the source I don't see any reason. So you might like to proceed like this:

1. Comment everything that has to do with the heartbeat acquisition, including the timer interrupt. You can do this with `/* … */` or `#if 0`-`#endif`-pairs. The former can't be "stacked" and the latter need their own lines.
1. Check whether the temperature is tracked OK.
   - If yes, proceed.
   - If no, your temperature circuitry is faulty in some way. A schematic and a photo (edit your question for this) could be helpful for us. Don't proceed until this is solved.
1. The timer and its interrupt service routine is actived again but will execute nothing.
1. Check whether the temperature is OK.
   - If yes, proceed.
   - If no, I'm out of ideas for the moment.
1. Re-enable the heartbeat acquisition.
1. Check whether the temperature is OK.
   - If yes, proceed.
   - If no, I'm out of ideas for the moment.
1. Problem solved.


body:
I try to solve this a month..but still problem...

I want to make below led-matrix spectrum.

[Thumbnail image][1]

<https://youtu.be/X35HbE7k3DA>

**※Environment**

[Device UML][2]

One Raspberry pi 3 : 2019-09-26-raspbian-buster-full

Two arduino uno with each matrix shield and 16x32 matrix

One usb Microphone

If i attached two arduino Uno to raspberry pi and try to run Processing code(.pde) , one of them is reattached to raspberry pi.

The other one is still working well..

If i connect these arduinos to windows and running pde file...It works well.
(two matrix are showing spectrum well)

What should I do???
Is this code problem? or raspberry problem?

I really need to solve this...

**I already tried....**

1. Reloaded ino code to both arduino Uno.
(both arduino has same code)

2. Changed boardrate number 115200 -> other number
(but it must be 115200 to running well)

3. Add arduino to udev rules like below link.
<https://www.intorobotics.com/how-to-setup-raspberry-pi-to-identify-two-arduino-devices/>

4. Cross exchange each matrix and arduino.

5. Try to use arduino mega with same code.

**Here is the arduino code(.ino) and Processing Code(.pde)**
<https://github.com/snskreationz/Real-Time-RGB-Matrix-Spectrum-Analyzer>

**arduino Uno Matrix Pin number**
```arduino
#define CLK 8
#define LAT 10
#define OE  9
#define A   A0
#define B   A1
#define C   A2
```

**Main processing code**
```Processing
import ddf.minim.analysis.*;
import ddf.minim.*;
import processing.serial.*;

Serial port1;
Serial port2;

Minim minim;
AudioInput in;
FFT fft;

int buffer_size = 4096;
float sample_rate = 200000;

int freq_width = 250; // <-O-> set the frequency range for each band over 400hz. larger bands will have less intensity per band. smaller bands would result in the overall range being limited

//arrays to hold the 64 bands' data
int[] freq_array = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
float[] freq_height = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void setup()
{
  size(200, 200);

  minim = new Minim(this);
  port1 = new Serial(this, "COM8" , 115200); // <-O-> set baud rate and port for first RGB matrix
// Here can be changed to "/dev/ttyACM0" via Raspberry pi
  //port2 = new Serial(this, "COM5" , 115200); // <-O-> set baud rate and port for second RGB matrix
// Here can be changed to "/dev/ttyACM1" via Raspberry pi

  in = minim.getLineIn(Minim.MONO,buffer_size,sample_rate);

  // create an FFT object that has a time-domain buffer
  // the same size as line-in's sample buffer
  fft = new FFT(in.bufferSize(), in.sampleRate());
  // Tapered window important for log-domain display
  fft.window(FFT.HAMMING);
}
```

**Here are the kernel logs for Raspebrry pi**

```Kernel log
Nov 11 00:17:27 raspberrypi kernel: [ 5974.165722] Under-voltage detected! (0x00050005)
Nov 11 00:17:27 raspberrypi kernel: [ 5974.665649] usb 1-1.3: new full-speed USB device number 9 using dwc_otg
Nov 11 00:17:27 raspberrypi kernel: [ 5974.809539] usb 1-1.3: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
Nov 11 00:17:27 raspberrypi kernel: [ 5974.809556] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=220
Nov 11 00:17:27 raspberrypi kernel: [ 5974.809566] usb 1-1.3: Manufacturer: Arduino (www.arduino.cc)
Nov 11 00:17:27 raspberrypi kernel: [ 5974.809576] usb 1-1.3: SerialNumber: 55639313932351518040
Nov 11 00:17:27 raspberrypi kernel: [ 5974.810729] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device ---------------------> connected first arduino
Nov 11 00:17:28 raspberrypi kernel: [ 5975.685661] usb 1-1.2: new full-speed USB device number 10 using dwc_otg
Nov 11 00:17:28 raspberrypi kernel: [ 5975.829541] usb 1-1.2: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
Nov 11 00:17:28 raspberrypi kernel: [ 5975.829558] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
Nov 11 00:17:28 raspberrypi kernel: [ 5975.829569] usb 1-1.2: Manufacturer: Arduino (www.arduino.cc)
Nov 11 00:17:28 raspberrypi kernel: [ 5975.829578] usb 1-1.2: SerialNumber: 8563431373935121D0B2
Nov 11 00:17:28 raspberrypi kernel: [ 5975.830752] cdc_acm 1-1.2:1.0: ttyACM1: USB ACM device --------------------->  connected second arduino
Nov 11 00:17:33 raspberrypi kernel: [ 5980.405877] Voltage normalised (0x00000000) --------------------->  almost at this time starting processing code
Nov 11 00:17:37 raspberrypi kernel: [ 5985.121964] usb 1-1.2: USB disconnect, device number 10
Nov 11 00:17:37 raspberrypi kernel: [ 5985.122315] cdc_acm 1-1.2:1.0: failed to set dtr/rts
Nov 11 00:17:38 raspberrypi kernel: [ 5985.425669] usb 1-1.2: new full-speed USB device number 11 using dwc_otg
Nov 11 00:17:38 raspberrypi kernel: [ 5985.569812] usb 1-1.2: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
Nov 11 00:17:38 raspberrypi kernel: [ 5985.569831] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
Nov 11 00:17:38 raspberrypi kernel: [ 5985.569843] usb 1-1.2: Manufacturer: Arduino (www.arduino.cc)
Nov 11 00:17:38 raspberrypi kernel: [ 5985.569853] usb 1-1.2: SerialNumber: 8563431373935121D0B2
Nov 11 00:17:38 raspberrypi kernel: [ 5985.571468] cdc_acm 1-1.2:1.0: ttyACM2: USB ACM device --------------------->  reattached second arduino automatically
Nov 11 00:17:39 raspberrypi kernel: [ 5986.645829] Under-voltage detected! (0x00050005)
Nov 11 00:17:43 raspberrypi kernel: [ 5990.805775] Voltage normalised (0x00000000)
```

I really want to run both arduino spectrum via raspberry pi.

  [1]: https://i.stack.imgur.com/aK3Gi.png
  [2]: https://i.stack.imgur.com/pGFwC.png

title: Two adruino are connected to the raspberry via usb, but one is reconnected during processing code is running

Answers: 1

body:
`Under-voltage detected!` I think it says it all. Rapsberry have many times problem to feed itself from "common power source", not mentioning attached devices. Especially, if you power your LEDs from it too.

You need better power source for Rapsberry (and maybe even power it from pins, but then you need read much more to not damage it) and other powersource for those LEDs.

On normal PC the Power Source is way more powerfull and can feed a LOT of power to each USB.


body:
Hi i have recently started working on a Temperature and Humidity Sensor TinyShield (ASD2511-R-T) and faced the issue as shown in the image below: No device found on com5.

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

I have followed the tutorial as shown in the TinyShield webpage and worked through the steps. 1) Installed the Arduino IDE, 2) Installed the Si7021 Arduino Library, 3)Download the .zip file of the example program and open it in the Arduino IDE.

This is the following example code provided by the tutorial.
```
/*
  TinyCircuits Si7020 Temperature and Humidity Sensor TinyShield Example Sketch

  This demo shows the bare minimum to read temperature and humidity data from
  the Si7020 sensor using the Si7020 library written by Marcus Sorensen.

  This example is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Written 20 March 2016
  By Ben Rose
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

#include <Wire.h>
#include <SI7021.h>

SI7021 sensor;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Initializing sensor... ");
  if(!sensor.begin()){
    Serial.println("Sensor not found!");
    while(true);
  }
  Serial.println("Success!");
}

void loop()
{
  int celcius=sensor.getCelsiusHundredths()/100;
  int relativeHumidity=sensor.getHumidityPercent();
  Serial.print(celcius);
  Serial.print(" deg Celsius\t");
  Serial.print(relativeHumidity);
  Serial.println("% relative humidity");

  delay(500);
}
```

However, when I proceed to upload the program, the following error had occurred. This is the first time i am working on a TinyShield product.

Any help is appreciated! Thanks!

Do let me know if i need to provide any further information.

The options for COM 5 the only one avaliable.
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/uAqCP.png
  [2]: https://i.stack.imgur.com/N3kfs.png

title: Temperature and Humidity Sensor TinyShield (No device found on com5)

Answers: 1

body:
The below was the issue, i was using the wrong broad and processor.

Thanks for the help!

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

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


body:
#include <Servo.h>

Servo myservo;

void setup(){
  myservo.attach(8);
   pinMode(buttonPin, INPUT);
}

void loop()
{
  myservo.write(0);
  delay(3);
  myservo.write(90);
  delay(3);
}
 const int inPin=8;
 const int outPin = 9;
 int currentState = LOW;
  currentState = digitalRead (inPin);
  if (currentState== HIGH)
    digitalWrite (outPin,HIGH);
   else
    digitalWrite (outPin,HIGH);
   delay(10);
 }

title: I am trying to combine a button's coding and servo's coding. But it is still cannot be verified. What have I done wrong?

Answers: 1

body:
Do NOT use two loop() and setup() function.

You can refer to a similar combination between Servo Motor code and Potentiometer code [here][1].

  [1]: https://arduinogetstarted.com/tutorials/arduino-servo-motor-controlled-by-potentiometer


body:
I am trying to use a NodeMCU like an arduino,trying to read Temperature and Humidity using a DHT11,but when ever I check the serial monitor the it outputs : nan, Can anyone help me find the problem.(The data pin is D4 on NodeMCU)

        #include "DHT.h"

    DHT dht2(2,DHT11);

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

        }

    void loop()
    {

        Serial.println("Temperature: ");
        Serial.println((dht2.readTemperature( )));
        Serial.println("Humidity");
        Serial.println((dht2.readHumidity( )));
        delay(5000);

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

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

title: Unable to use DHT11 with NodeMCU(esp8266)

Answers: 1

body:
The esp8266 boot configuration pins 0, 2, 15 require a pull-up/pull-down  to ensure the required state at boot. The board (NodeMCU in this case) has pull-up resistor on io0 and io2 and a pull-down resistor on pin 15. The MCU pins io0, io2 and io16 are the NodeMCU pin D3, D4 and D8. You can use this pins in the sketch, but only to attach devices which are not in conflict with the required boot state and are not disturbed by the pull-up/pull-down.

**NodeMCU and "Wemos D1 R2 and Mini" esp8266 pins and io overview**

----------

**Serial**

RX io1 RX0

TX io3 TX0

----------

**boot config pins** with pullup or pulldown on board

D3 io0 PULLUP (LOW for boot to flashing mode)

D4 io2 TX1 PULLUP (Serial1 TX. no RX for Serial1)

D8 io15 PULLDOWN (SS pin if esp8266 is SPI slave)

----------

**untroubled GPIOs** with optional function for I2C or SPI bus:

D1 io5 default pin for I2C SCL

D2 io4 default pin for I2C SCA

D5 io14 SPI CLK

D6 io12 SPI MISO

D7 io13 SPI MOSI

----------

**RTC pin** for timed deep sleep wake-up (if connected to reset pin)

D0 io16 - optional internal pulldown, internal pullup not available

----------
**not useable**: S*x* pins io 6 to io 11 connect QIO SPI flash memory (in DIO flash mode the 2 QIO pins can be used as gpio) (in a very special setup the SPI bus can be used with other SPI device)

*note: most digital IO start as INPUT_PULLUP*


body:
I am using a third-party program to build the binary file and upload it under Arduino IDE's GUI, meaning I am not using the built-in avr-gcc nor avrdude for building and uploading. As there is a on-board DAP chip, uploading binary file is done by copy&paste the binary file into the flash memory recognized as a removable storage by the OS.

However, this make reading user's current port selection very difficult because the IDE is written in Java, but the thrid-party program I am using is in C++.

Knowing which port the user has currently selected is very important to me, as sometimes I need to program multiple boards at the same time and monitor their received data on the serial port.

If someone can point me into the right direction or link me to the previously-solved similar question , it will be much appreciated!

PS: I am working under Ubuntu&Windows10 OS and using latest Arduino IDE.

title: Is there a way to read real-time port selection on Arduino IDE when using third-party toolchain and uploading program?

Answers: 1

body:
After someone from Github gave me a link, I think I ve found the way to read the real-time port selection even using third party uploading program.

The key is command line argument in the "Platform.txt" file located under "arduino15" folder. If you have the same issue as mine, try look up this link, where you will find loads of useful information:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification

PS: rmb, after you change the command lines in the txt file, always close and restart your arduino IDE before those changes you made take effect.


body:
When passing an array to a function, you usually pass the length of the array along with it. You can compute the size of the array with `sizeof(myArray)/sizeof(myArray[0])`, which works just fine.

However, if you try to do this within the function that you pass the array to, this doesn't return the length of the array - eg. if it is an `int` array, it returns 1, if it is a `double` array, it returns 0.

Why is that so and is there any way to compute the size of an array that was passed as a parameter?

title: Compute the size of an array that was passed as a parameter to a function

Answers: 1

body:
You can't. You are passing a *pointer* to the array, and `sizeof` will give you the size of that pointer (2 on an 8-bit Arduino).

Instead the normal way is to pass the size of the array as a parameter to your function.

    myFunction(myArray, sizeof(myArray) / sizeof(myArray[0]));


body:
I have an Arduino Uno that I have connected to a servo motor. I used an adapter to plug it into my computer and my computer said "Setting up a device, this will only take a minute". When it was done setting up, I downloaded Arduino IDE and I wrote a code. When I clicked "Upload", I was told that a serial port was not selected. I went to Tools>Port>Arduino Uno. The program then uploaded, I unplugged it and began its process. After I uploaded, I wanted to make a change to my code so I plugged it back in and I heard the Windows _beepboopbeep_ sound. I edited the code and tried to upload again and it said that a serial port was not selected. I went to Device Manager and found it under another tab, something like Amtek USB ports. It was labeled as "Unknown Device". I tried to select it but it told me that it couldn't update driver. I looked it up and people said to unplug and replug in another USB port. I tried that 7 times yet it was still "Unknown Device". Am I doing something wrong?

Edit: I am using a HP AMD Radeon 7 Processor laptop running Windows 10 and my Arduino is not a copy, it is authentic.

title: How do change my Arduino Uno from an unknown device to a port?

Answers: 0


body:
I have created a library that contains an array. This is the .h file:

    class Lib {
      public:
        static int arr[];
    };
And this is the .cpp file:

    #include "Lib.h"

    int Lib::arr[] = {0, 1, 2, 3};
When trying to compute the size of this array from within the library, it works just fine. When trying to do this from a sketch, I get the error mentioned in the title. This is the sketch I'm using:

    #include <Lib.h>

    void setup() {
      sizeof(Lib::arr);
    }

    void loop() {}
What is the problem here?

title: Error: invalid application of 'sizeof' to incomplete type 'int []' when trying to compute the size of an array in a library

Answers: 1

body:
The reason is that in your sketch you import only the header file (which is good). However, there it is an array (`int[]`), not the initialized array.

For that you would need to include the cpp but that is bad practice (if even possible).

So instead, create a new (constant) variable, and assign it.

(more or less pseudo code, due to lack of a compiler):

Lib.h:

    class Lib {
      public:
        static int arr[];
        static int arr_length;
    };

Lib.cpp:

    #include "Lib.h"

    int Lib::arr[] = {0, 1, 2, 3};
    int Lib::arr_length = sizeof(Lib::arr);

Sketch:

    #include <Lib.h>

    void setup() {
      Lib::arr_length;
    }

    void loop() {}

See also the comment of LukasFun below. It is also possible to set the size of the array in the header file.

My advice though is keeping all assignments in the implementation (cpp) file. The header file is for defining items, the implementation file for initializing/assigning. But it works too, to initialize items in the header file.


body:
When creating an array like in the sketch

    #include <Lib.h>

    int myArray[Lib::len];

    void setup() {}

    void loop() {}

the variable len must be an integer constant that is known at compile time. Like shown in the sektch, I want to put the length of the array into a library and get it from there. The problem is that for this to work, you have to initialize the constant already in the .h file, which is against proper library standards. This is how you would do this (.h file of the library):

    class Lib {
      public:
        static const int len = 4;
    };

The .cpp file doesn't even have to contain anything in this case. The proper way to do things in a library would be like this though:

The .h file:

    class Lib {
      public:
        static const int len;
    };

The .cpp file:

    #include "Lib.h"

    const int Lib::num = 4;

But if done like this, `len` doen't have a value at compile time since the sketch only includes the .h file and not the .cpp file.

Is there any way to intitialize an array in a sketch with its length coming from a library while maintaining proper library design?

title: Creating an array with the length coming from a library

Answers: 1

body:
There is absolutely nothing wrong with putting it in the header.

> §9.4.2/4 If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.

Since you're just using it as a simple constant "integral" value there is nothing wrong with putting it in the header.


body:
Since some months, everyone can buy a board with this IC.

It is compatible with the ATMega328 and has some features like 12bit ADC (instead of 10 bit), DAC, unique ID and also 32MHz.

But I can't find it in the "normal" shops. Also on the LCSC it is not available. Only in this shop:
https://www.electrodragon.com/product/5pcs-logicgreen-lgt8f328p/
For 0.68$ compared to the 2$ for the atmega326P-AU of the other electronic parts shops (it is cheaper than the cheapest attiny with ADC!)

So the question. Is this chip just a clone for private use or can it be used as official alternative to the more expensive and original ATMega328?

title: Is the LGT8F328P legal?

Answers: 3

body:
As legal as any other clone CPU / MCU.  See

* [Intel vs The World](http://www.cpushack.com/2012/09/06/intel-vs-the-world-the-338-patent/)

In short:  if you copy the silicon design it's illegal. If you create it yourself from the ground up it's legal.

However, IANAL, so don't quote me on that.

body:
Legal or not, I DO NOT reccomend this clone. It is similar and compatible to some extend but it lacks features like an EEPROM. With fuses you can only reserve some FLASH to emulate an EEPROM. Thus have less space for your code.
Also the manual is only available in chinese. There are english translations but those are hard to read as the layout got screwed up.
It has some new features that sound great but I would not see them as replacement for the ATmega328P from Atmel/Microchip.

I bought an Arduino clone with LGT8F328P by accident. I find it barely usable as there are itches here and there which I don't want to deal with.

body:
My understanding is that it is legal since it is just engineered to be (somewhat) compatible with ATmega328p but their difference are substantial if you deep dive.

It has a RISC core and its core instructions are quite different from ATmega328p. Most multi-cycle instructions are replaced by single-cycle instructions or less cycle instructions. And the core runs at 32Mhz from 1.8V-5.5V.

The peripheral registers are largely (backward) compatible with ATmega328. However, LGT has more or advanced peripherals.
* 2 16-bit timers, with capture and compare output
* ADC has 12 bits instead of 10.
* DAC, so you don't need PWM to emulate DAC.
* 9 high current PWM. 3 complementary PWM with dead band control.
* PGA 1x-32x differential amp. Which saved me 1 op-amp.
* 16 bit computing accelerator/Co-processor.
* High and adjustable current GPIO (so you can light up LEDs without current limiting resistors).
These peripherals provide lots of additional registers for control and status reporting that don't exist on ATmega.

Development environment is also different. The best way for hobbyists to develop on this chip is either using LGT Arduino Core but not ATmega328 Arduino Core:
https://github.com/dbuezas/lgt8fx  (Arduino IDE)
or
https://community.platformio.org/t/how-to-add-lgt8fx-board/13294 (PlatformIO) Or you can use their official SDK for development which is very different from AVR's environment.

LGT8F328p also has SSOP20 and LFP48 package offering smaller or larger number of GPIOs, which are not so well known by DIY community since they are not similar to ATmega328p.

So in general LGT is a different, forward engineered chip and highly unlikely a direct silicon clone copied by reverse engineering.

In general having peripheral registers and pin compatibility are not illegal, unless the IP core of the peripherals are stolen from ATmega328p. And since CPU instructions (and clock trees) are quite different, if assembly language is used for development, developer would likely feel they are two distinct MCUs. It is just that a C compiler and Arduino framework can hide those details and make them similar.

However, the laws and regulations differ across countries and states so I am not sure if that applied to all markets. And there is natural murkiness in what is an IP and what is not. In software, API similarity could result in infringement but in the world of MCU pin compatibility would not, despite they are both "interface similarity" issues.


body:
I want to execute a action only once when I press web page button but as the page tries refreshing the action gets executed in a loop.
I am using the wifimanualwebserver example for esp8266.
Please suggest what should I do?

title: command keeps echoing because web page tries refreshing

Answers: 1

body: Not sure if it possible in your case, but you might send and ID with it which you increase every time the button has been (really) clicked (thus not refreshed). On the receiver side, check if the ID is already received, if yes, do not execute it.


body:
I'm very new to Arduino, currently undertaking a uni project in which my team wish to create a sort of slot machine-esque device that uses a step motor to rotate a drum (like one of the cylinders in a slot machine).

What I've currently tried to do is merge some code that uses a counter variable and button to enable a servo to rotate round multiple times with a single button, with code I found that i think is used to test a step motor? In my mind the code I have should allow me to rotate my stepper by 45 degrees after each button press, but I have no idea if my code makes any sense. Could you guys tell me if im close or is it a load of rubbish. if it does work ok, id look to set the speed higher and have the motor perform multiple full rotations before each stop, to make it work more like an actual slot machine spinner. any advice you could offer would be great, apologies in advance if i don't quite understand certain things  you may explain as I am new to coding, as I mentioned.

Here's the code:
<!-- language-all: lang-cpp -->

    #include <Stepper.h>

    //variables
    int counter = 0;
    const int buttonPin = 8;
    const int stepsPerRevolution = 90;

    Stepper myStepper(stepsPerRevolution,1,2,3,4);

    void setup() {

     pinMode(buttonPin, INPUT);
     myStepper.setSpeed(60);

    }

    void loop() {

      int buttonState;

      buttonState = digitalRead(buttonPin);

       if (buttonState == LOW)
      {
        counter++;

     delay(150);
      }

    if(counter == 0)
       myStepper.step(0);

     else if(counter == 1)
       myStepper.step(45);

     else if(counter == 2)
      myStepper.step(90);

     else if(counter == 3)
        myStepper.step(135);

    else if(counter == 4)
       myStepper.step(180);

     else if(counter == 5)
      myStepper.step(225);

    else if(counter == 6)
        myStepper.step(270);

    else if(counter == 7)
      myStepper.step(315);

    else if(counter == 8)
        myStepper.step(360);

      else
       counter = 0;

    }

title: Any advice you can give me on my step motor code?

Answers: 2

body:
The event of a button press is not deterministic in your case. Generally, your delay()-approach combined with reading the current button state is not how sth. like this works.
Instead, you have to detect when a button is **pressed/released**.
One way to do that is the following:

    #define buttonPin 8
    bool last_state=false;

    void loop(){
      if(!digitalRead(buttonPin)) {
        if(last_state) {
          //button has been released
          //increment your counter here
        }
        last_state=false;
      } else {
        last_state=true;
      }
    }

body:
First understand that myStepper.step(x) method is relative steps not absolute. So if you want the motor to do two rotations of 45 steps back to back you should write

    myStepper.step(45);
    myStepper.step(45);    /// NOT myStepper.step(90)  <-- that's 90 MORE steps

Second, it looks like your code will increase steps taken by 45 while HOLDING the button down but should also rotate the motor 45 steps for each button press as long as the subsequent presses do not occur while the motor is in mid rotation.

Furthermore, your can delete the following extra else if statements and it should still work.
```
else if(counter == 2)
  myStepper.step(90);

 else if(counter == 3)
    myStepper.step(135);

else if(counter == 4)
   myStepper.step(180);

 else if(counter == 5)
  myStepper.step(225);

else if(counter == 6)
    myStepper.step(270);

else if(counter == 7)
  myStepper.step(315);

else if(counter == 8)
    myStepper.step(360);
```


body:
please can someone help me with code, i want to have automatic trigger on specific hour, also i want to have button switch if needed, in my code i can press the button to trigger light relay, but my specific time trigger just flash at start time and does nothing, here is code:

    #include <LiquidCrystal_I2C.h>
    #include <DS3231.h>
    LiquidCrystal_I2C lcd(0x27, 2, 1,0,4,5,6,7,3, POSITIVE);
    DS3231  rtc(SDA, SCL);
    Time t;

    const int OnSec = 30;
    const int OffSec = 5;
    int relay_3 = 5 ;

    void setup() {
     lcd.begin(20,4);
     rtc.begin();

     pinMode(relay_3,OUTPUT);
     pinMode(8, INPUT_PULLUP);
    }

    void loop() {
      int button_4 = digitalRead(8);
      t = rtc.getTime();
      lcd.setCursor(0,1);
      lcd.print(rtc.getTimeStr());

      if(t.sec == OnSec)                                  //if is hh.mm.30 - just for 1 sec trigger relay
      {
      digitalWrite(5,HIGH);
      }
        else if(t.sec == OffSec)                         //if is hh.mm.05 - release relay
      {
      digitalWrite(5,LOW);
      }
          else if (button_4 == HIGH)                     //if button is pressed - trigger relay
      {
      digitalWrite(5,HIGH);
      }
            else
      {
      digitalWrite(5,LOW);
      }

      lcd.clear();
    }

i would be gratefull for any advice :)

title: DS3231 + button to trigger light

Answers: 1

body:
The else case is executed every time the other `if` and `else if` conditions are **not** true. That means if it is not 5 sec and not 30 sec and no button is pressed, the relay is switched off.

To achieve what you want is not that easy, because you have to synchronize button press and button release with the timer actions. First you must specify what you exactly want to do. e.g What happens if you have already pressed the button and release it in the time interval between 30 and 5. Releasing the button would switch off the light but should it stay on because you are within the on-time? This is just an example of what to think about.

I wrote a little code for fun doing the things as I would do it:

    #include <LiquidCrystal_I2C.h>
    #include <DS3231.h>
    LiquidCrystal_I2C lcd(0x27, 2, 1,0,4,5,6,7,3, POSITIVE);
    DS3231  rtc( SDA, SCL );
    Time t;

    const int OnSec = 30;
    const int OffSec = 5;
    int relay_3 = 5;

    int timerPhase = -1;
    int relayState = LOW;

    void setup()
    {
     lcd.begin( 20, 4 );
     rtc.begin();

     pinMode( relay_3, OUTPUT );
     pinMode( 8, INPUT_PULLUP );
    }

    void loop()
    {
      t = rtc.getTime( );

      int button_4 = digitalRead( 8 );

      lcd.setCursor( 0, 1 );
      lcd.print( rtc.getTimeStr( ) );

      // this only works if the off time is
      // less than the on time. (OffSec < OnSec)
      timerPhase = ( (t.sec > OffSec) && ( t.sec < OnSec ) ) ? 0 : 1;

      if ( button_4 == HIGH )
      {
        // a button overrides the timer phase
        relayState = HIGH;
      }
      else
      {
        if ( timerPhase == 0 )
        {
          relayState = LOW;
        }
        else
        {
          relayState = HIGH;
        }
      }

      digitalWrite( relay_3, relayState );

      lcd.clear();
    }

I could not try the code because I don't know which libraries you used and therefor got compiler errors. So there might be syntax errors in my code but I hope I wrote correct code. It would be nice if you report errors here, if you find one/some ;-).

The line

    timerPhase = ( (t.sec > OffSec) && ( t.sec < OnSec ) ) ? 0 : 1;

uses a ternary operator. It means if the condition `( (t.sec > OffSec) && ( t.sec < OnSec ) )` is `true`, take the first alternative `0` and assign it to the variable `timerPhase`, if it is `false` choose the second alternative '1'.


body:
I am trying to use addressable LED's to show various piano scales using the semi notes formula for each scale as an array and an input to indicate the starting note.

    int MajorScale[] = {2,2,1,2,2,2,1}; //represents the semi notes in a major scale
    int t= 8 //represents the led number that represent the first C on the keyboard

The following leds should light up -

(8, 8+2, 8+2+2, 8+2+2+1, 8+2+2+1+2, 8+2+2+1+2+2, 8+2+2+1+2+2+2 , 8+2+2+1+2+2+2+1)  // This is first C Major Scale on the Piano

so..
(8,10,12,13,15,17,19) // This is first C Major Scale on the Piano where 8 is the first c

Then light up all the other C Major scales available on the piano limited by the number of keys on the piano in this case 76 keys

As there are 12 notes for each octave , add this to the array

if i take just the C note

8, 8+12, 8+12+12 ,8+12+12+12, 8+12+12+12+12  etc

My code so far just lights up the semitone that i set up in the array

    enter code here
    #include "FastLED.h"
    #define DATA_PIN 5
    #define NUM_LEDS 76
    #define BRIGHTNESS 10
    CRGB leds[NUM_LEDS];
    int MajorScale[] = {2,2,1,2,2,2,1};
    int delayValue = 1000;

    void setup() {
    Serial.begin(9600); // open the serial port at 9600 bps:
    FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    }

    void loop() {
    for(int i = 0; i <=6; i++)
    {
        leds[MajorScale[i]] = CRGB::BlueViolet;
        FastLED.show();
         delay(delayValue);

    }

    FastLED.clear();
    }

title: Using Arrays and LED's to represent Piano Scales

Answers: 1

body:
Your current code will not show all notes of a scale. Only the notes at 1 and 2 will light up, since you don't sum up the numbers, that you have stored in `MajorScale`. But I think it is not a great idea to sum them up programatically, since this is a constant and you don't win much by representing the data this way. Instead you should directly initiate the `MajorScale` variable with the summed up values:

    int MajorScale[] = {0, 2, 4, 5, 7, 9, 11};

Then you can enclose your for loop with another for loop, that adds an offset corresponding to the octave:

    for(int j=0; j<NUM_LEDS; j+=12){
        for(int i=0; i<=6 && MajorScale[i]+j<NUM_LEDS;i++){
            leds[8+MajorScale[i]+j] = CRGB::BlueViolet;
            FastLED.show();
            delay(delayvalue);
        }
    }

So we set the LED number `8+MajorScale[i]+j`. 8 for the offset to C, `MajorScale[i]` as the position of the note in the current octave and `j` for the offset of the current octave relative to the C.

Note, that this is not tested in any way.


body: I'm fairly new to arduino, but I want to program a nano over SPI to skip the bootloader. I know I can program the nano with an uno as a programmer to do this, but I don't have an uno, but I do have a couple of nanos. Can I set up one as a programmer, connect it to another over SPI, and program the 2nd?

title: can I program a nano over SPI with another nano?

Answers: 1

body:
Yes, you can. They use ATmega328 / Atmega328P microcontrollers, which are basically the same.

(The differencies of those microcontrollers are about Brown Out Detection - how they could be set to react on too low voltage. No problem in nearly any Arduino operation.)

The boards differ mainly in the board size and places for pins.


body:
I already have this code, but I do not know how to make the LED blink.

CODE:
```c++
const int ledPin = 6; // The pin of your LED, D06
const int trigPin = 5; // The pin to which the TRIG is connected, D05
const int echoPin = 4; // The pin to which the ECHO is connected, D04
const int ledOnTime = 1000;
// The time that the LED stays on, after detecting the motion (in milliseconds, 1000ms = 1s)
const int trigDistance = 40;
// The distance (and lower than it) at which the sensor is triggered (in centimeters)
//
int duration;
int distance;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin, HIGH);
  delay(1);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  if (distance <= trigDistance) {
    digitalWrite(ledPin, HIGH);
    delay(ledOnTime);
    digitalWrite(ledPin, LOW);
  }
  delay(100);
}
```

title: I have to make an LED with an ultrasonic distance sensor, where the LED blinks faster when getting closer than a specific distance

Answers: 2

body:
I would say the way to go is using non-blocking code with `millis()`. Look into the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It doesn't use `delay()`, which is considered bad coding practice, since it is just busy waiting. Nothing else can happen during a delay, except for interrupts. Instead of waiting it is better to regularily check the clock, if it is time to do something (much like you would do in real life for example for baking a pizza).

The clock is provided by `millis()`, which returns the number of milliseconds since startup. Below you see the `BlinkWithoutDelay`example. The variable `interval` controls the blink frequency. If you remove the `const` keyword before it and change it according to the measurements from the ultrasonic sensor, you will get a changing blinking frequency with changing distance.

Try to combine the codes into one. Remove all `delay()` calls, except for the `delay(1)` (it is needed to trigger the ultrasonic sensor and it is small enough to not matter greatly).

    const int ledPin =  LED_BUILTIN;// the number of the LED pin

    // Variables will change:
    int ledState = LOW;             // ledState used to set the LED

    // Generally, you should use "unsigned long" for variables that hold time
    // The value will quickly become too large for an int to store
    unsigned long previousMillis = 0;        // will store last time LED was updated

    // constants won't change:
    const long interval = 1000;           // interval at which to blink (milliseconds)

    void setup() {
      // set the digital pin as output:
      pinMode(ledPin, OUTPUT);
    }

    void loop() {
      // here is where you'd put code that needs to be running all the time.

      // check to see if it's time to blink the LED; that is, if the difference
      // between the current time and last time you blinked the LED is bigger than
      // the interval at which you want to blink the LED.
      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the LED with the ledState of the variable:
        digitalWrite(ledPin, ledState);
      }
    }

The rest is up to you. If you need more information about the `BlinkWithoutDelay` example, you should google it. There are tons of tutorials. This is a great coding excerise, so have fun :)

body:
**step 1**: define your MIN_DISTANCE, MAX_DISTANCE

**step 2**: get distance from sensor

**step 3**: rescale the distance value to a value in between 0 and 255

**step 4**: fade led according to the rescaled value.

Note that: you should not use delay() to blink LED. Use analogWrite() instead. See [ the example][1]. We can change frequency of PWM to make LED from fading to blinking by using setPwmFrequency() function

  [1]: https://arduinogetstarted.com/tutorials/arduino-potentiometer-fade-led


body:
I have recently purchased this [Heart rate sensor](https://robu.in/product/max30100-pulse-oximeter-heart-rate-sensor-module) and was trying to make it work. I used this [MAX30100 library](https://github.com/oxullo/Arduino-MAX30100) I found on Github. For some reason when I use any of the given examples, they seem to work well when I use a Mega2560 I have but not on the Uno or Nano. Does this have to do with the processor? I don't think so because the README on Github mentions that they tested it on an Uno. But if it is so, how could I change the code to make it work with the Uno and nano?

Example Code I used:
```
// This example can be used to test connectivity and operation of the sensor
// check the README file on the repo's root for a troubleshooting guide in casem
// any of the tests running fail

#include <Wire.h>
#include "MAX30100.h"

MAX30100 sensor;

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

    Serial.print("Initializing MAX30100..");

    if (!sensor.begin()) {
        Serial.print("FAILED: ");

        uint8_t partId = sensor.getPartId();
        if (partId == 0xff) {
            Serial.println("I2C error");
        } else {
            Serial.print("wrong part ID 0x");
            Serial.print(partId, HEX);
            Serial.print(" (expected: 0x");
            Serial.println(EXPECTED_PART_ID, HEX);
        }
        // Stop here
        for(;;);
    } else {
        Serial.println("Success");
    }

    Serial.print("Enabling HR/SPO2 mode..");
    sensor.setMode(MAX30100_MODE_SPO2_HR);
    Serial.println("done.");

    Serial.print("Configuring LEDs biases to 50mA..");
    sensor.setLedsCurrent(MAX30100_LED_CURR_50MA, MAX30100_LED_CURR_50MA);
    Serial.println("done.");

    delay(1000);

    Serial.print("Lowering the current to 7.6mA..");
    sensor.setLedsCurrent(MAX30100_LED_CURR_7_6MA, MAX30100_LED_CURR_7_6MA);
    Serial.println("done.");

    delay(1000);

    Serial.print("Shutting down..");
    sensor.shutdown();
    Serial.println("done.");

    delay(1000);

    Serial.print("Resuming normal operation..");
    sensor.resume();
    delay(500);
    Serial.println("done.");

    uint32_t tsTempSampStart = millis();
    Serial.print("Sampling die temperature..");
    sensor.startTemperatureSampling();
    while(!sensor.isTemperatureReady()) {
        if (millis() - tsTempSampStart > 1000) {
            Serial.println("ERROR: timeout");
            // Stop here
            for(;;);
        }
    }

    float temperature = sensor.retrieveTemperature();
    Serial.print("done, temp=");
    Serial.print(temperature);
    Serial.println("C");

    if (temperature < 5) {
        Serial.println("WARNING: Temperature probe reported an odd value");
    } else {
        Serial.println("All test pass.");
    }

    Serial.println();
    Serial.println("Press any key to go into sampling loop mode");
    while (!Serial.available());

    sensor.resetFifo();
}

void loop()
{
    uint16_t ir, red;

    sensor.update();

    while (sensor.getRawValues(&ir, &red)) {
        Serial.print("IR=");
        Serial.print(ir);
        Serial.print(" RED=");
        Serial.println(red);
    }
}
```

title: I2C code working on Mega 2560 but not on Uno and nano

Answers: 1

body: I added pull-up resistors to the board and it started working. Turns out that the boards weren't well designed and the I2C lines were pulled up to 1.8V instead of Vin. By removing the pull-ups and adding pull-ups to Vin, the circuit started functioning. The circuit worked with Mega because it has in-built Pull-up Resistors.


body:
Before I will implementing some server application for Arduino client I should know:

Is it possible to connect from esp8266 module to end-point over HTTPS protocol?

Any links of tutorials are welcome.

Thank in advance.

title: Is it possible to connect from esp8266 module over HTTPS protocol?

Answers: 1

body:
Yes it's possible. Try this one tutorial.
https://circuits4you.com/2019/01/10/esp8266-nodemcu-https-secured-get-request/