text:
delay() not working inside loop() block
Edited and attached code here.
This section didn't execute.
The delay(15000); doesn't execute, I mean the sketch didn't execute this line no matter where to put it.
    // include the SPI library:
    #include <SPI.h>

    // set pin 53 as the slave select for the digital pot:
    const int slaveSelectPin = 53; //WAS 10 on Arduino uno.
    const int shutdownPin = 7; // was 7 on uno.
    const int wiper0writeAddr = B00000000;
    const int wiper1writeAddr = B00010000;
    const int tconwriteAddr = B01000000;

    const int tcon_0off_1on = B11110000;
    const int tcon_0on_1off = B00001111;
    const int tcon_0off_1off = B00000000;
    const int tcon_0on_1on = B11111111;

    const int analogInPin_c = A5;  // center Vc=Vss/2 from the PAD, use for set ini V. here no use, Vc directly goes to pad.

    const int analogInPin_x = A1;  // Analog input pin that the potentiometer is attached to
    const int analogInPin_y = A2;  // Analog input pin that the potentiometer is attached to

    const int analogOutPin_x = wiper0writeAddr; // write MCP POT
    const int analogOutPin_y = wiper1writeAddr; // write MCP POT

    int sensorValue_c = 0;        // value read from the PAD, Vc=Vss/2
    int sensorValue_x = 0;        // value read from the PAD, Vc=Vss/2
    int sensorValue_y = 0;        // value read from the PAD, Vc=Vss/2

    //?int outputValue_c = 0;        // value output to the PWM (analog out)
    int outputValue_x = 0;        // mid variable stored the value from 'sensorValue_c' and MAP that for use
    int outputValue_y = 0;        // mid variable stored the value from 'sensorValue_c' and MAP that for use

    int Vcr = 0;        // value read from the PAD, Vc=Vss/2
    int Vc = 0;        // value read from the PAD, Vc=Vss/2
    const int LEDpin1 = 47;
    const int LEDpin2 = 46;
    int count = 0;

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

      // set the slaveSelectPin as an output:
      pinMode (slaveSelectPin, OUTPUT);
      // set the shutdownPin as an output:
      pinMode (shutdownPin, OUTPUT);
      // start with all the pots shutdown
      digitalWrite(shutdownPin, LOW);
      // initialize SPI:
      SPI.begin();
      Serial.println("Setup complete");
      //??
      Serial.println("Starting loop");
      digitalWrite(shutdownPin, HIGH); //Turn off shutdown
    }

    void loop() {
      AnalogInOut(); //
      ArduinoDAC(); //
    }
    void AnalogInOut() {
      // take from some where used for testing joystick control LED,
      //need change to get date fron RC and write to MCP pots
      // read the analog in value:

      Vcr = analogRead(analogInPin_c);
      delay(1000);
      Serial.print("Vcr= ");
      Serial.println(Vcr);
      Vc = map(Vcr, 0, 1023, 165, 225);
      Serial.print("Vc = ");
      Serial.println(Vc);
      delay(10);
      Serial.print("count_ini= ");
      Serial.println(count);

      if (count = 0)  {

        if (Vc > 188)   {

          digitalWrite(LEDpin1, HIGH);
          Serial.print("Vc TOO HIGH: ");
          Serial.println(Vc);
          exit(0);
          delay(100);
        }

       if (Vc < 165) {

          digitalWrite(LEDpin2, HIGH);
          Serial.print("Vc TOO LOW = : ");
          Serial.println(Vc);
          exit(0);
          delay(10);
        }
        else {

          Serial.print("analogInPin_c_T00: ");
          Serial.println(analogInPin_c);

          /// digitalPotWrite(wiper0writeAddr, Vc);
          ///digitalPotWrite(wiper1writeAddr, Vc);

          digitalPotWrite(wiper0writeAddr, 100);
          digitalPotWrite(wiper1writeAddr, 220);

          count = 1;
          Serial.print("count_new= ");
          Serial.println(count);
        }
        delay(15000);
      }

      ////////////////////////////////////////////////////////////////////////////////////////////////////////////

      sensorValue_x = analogRead(analogInPin_x);
      sensorValue_y = analogRead(analogInPin_y);
      // map it to the range of the analog out:
      outputValue_x = map(sensorValue_x, 0, 1023, 70, 248);
      outputValue_y = map(sensorValue_y, 0, 1023, 70, 248);  // change the analog received to the value suite for PAD joystick

      //   print the results to the Serial Monitor:
      Serial.println("sensor_x =_T10 ");
      Serial.println(sensorValue_x);
      Serial.println("sensor_y = ");
      Serial.println(sensorValue_y);
      Serial.println("\t output = ");
      Serial.println(outputValue_x);
      Serial.println(outputValue_y);

      // wait 2 milliseconds before the next loop for the analog-to-digital
      // converter to settle after the last reading:
      delay(2);
    }

    void ArduinoDAC() {
      Serial.println("Starting loop");
      digitalWrite(shutdownPin, HIGH); //Turn off shutdown

      digitalPotWrite(wiper0writeAddr, outputValue_x); // Set wiper 0 to 200

      delay(5);

      digitalPotWrite(wiper1writeAddr, outputValue_y); // Set wiper 1 to 200

      delay(5);
    }

    // This function takes care of sending SPI data to the pot.
    void digitalPotWrite(int address, int value) {
      /// Serial.print("wiper0 position_t30: ");////
      /// Serial.println();////
      // take the SS pin low to select the chip:
      digitalWrite(slaveSelectPin, LOW);
      //  send in the address and value via SPI:
      SPI.transfer(address);
      SPI.transfer(value);
      delay(30);
      // take the SS pin high to de-select the chip:
    }

    int digitalPotRead(int address) {
      // take the SS pin low to select the chip:
      digitalWrite(slaveSelectPin, LOW);
      //  send in the address via SPI:
      SPI.transfer(address);
      // send zero to read data from the address
      delay(30);
    }

Please show us a small and working sketch. When I see those lines, then I think: "while what?". What is the condition? https://www.arduino.cc/reference/en/language/structure/control-structure/while/

yes, it can work, because you are allowed if in while

which delay(5000);? ... there are two .... also, how do you know that the command does not execute?

take a coding course

Thank you for reply, I attached the code.

Now I see no delay(5000) on attached code.

@jsotola and mico , Sorry, it was delay (15000) in the original code.

Did you notice this error in your code?  if (count = 0).

if (count = 0) is never true. = is assignment to count and the result of assignment is the assigned value. the value is 0

The code should read if (count == 0). With a single equals it is an assignment, and the if statement evaluates the value of the right-hand-side.

Basically it works.
Here you find a little sketch to see how it works. Try to transfere it to your solution.
#include <M5Stack.h>  // only necessary for my board (M5Stack)

bool condition_while = true;
bool condition_loop = true;
int condition_if = 0;

void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
}

void loop() {
   while (condition_while) {
       if (condition_if == 0) {
           Serial.println("testcase #1: if path reached");
           condition_if = 1;
       }
       else if (condition_if == 1 ) {
           Serial.println("testcase #2: if else path reached");
           condition_if = 2;
       }
       else {
           Serial.println("testcase #3: else path reached");
           condition_while = false;
       }
       Serial.println("testcase #4: path reached inside while");
   }
   if (condition_loop) {
       Serial.println("testcase #5: path reached outside while");
       condition_loop = false;
   }
}

This is the output on COM3

Thank you, I'll ref. this to my code.

I can't find the line with delay(5000), can you add the line number, I also don't find a while?

@laoadam and have a look at line 77:  'if (count = 0)  {', if you want to check if count is equal to Zero you have to write  'if (count == 0)  {'

Thank you RJPlog, I did it.

@laoadam Is it working now?

I would suggest you go through the coding tutorials on arduino website. It would be absolutely possible to have the above structure in an arduino code.
This link has a working and validated example showing while loop calling other function using if-else-if structure.
https://www.arduino.cc/en/Tutorial/WhileStatementConditional?from=Tutorial.WhileLoop
Please go through the tutorials and post specific problem if and when you encounter them.

If the code (not shown) within the if/else if/else structure doesn't affect the flow of control, then either delay() placement will work.  But the placement within the loop will delay at every cycle of the loop. The placement below the loop will only delay after the loop finishes executing.

I monitor the sketch execute，even that run through but delay() in this section didn't.


text:
Program crashes when I use Serial.println()?
I'm working with a fuzzy logic controller with Arduino, I'm trying to emulate an AC by entering inputs [temperature and humidity] using two potentiometers and the output is the AC power.
This is the basic part of the program, every thing is good, I can print the values of Temp and HU. But when I try to print the value of the Power, nothing happens, and the serial monitor displays nothing. By trial and error, I can see that Serial.println with power or any variable related to power crashes the program. What may be the reason?
    void loop()
{
    // Read Input: Temperature
    ttemp = analogRead(temp);

    Serial.println("the analoge Tempreture is ");
    Serial.println (ttemp);

    ttemp = map(ttemp, 0, 1023, 5, 65);
    ttemp = constrain(ttemp, 5, 65);

    Serial.println("the actual Tempreture is ");
    Serial.println (ttemp);
    Serial.println("-------------------------");
    delay(100);

    g_fisInput[0] = ttemp;

    // Read Input: Humidity
    hhu = analogRead(hu);
    Serial.println("the analoge Humidity is ");
    Serial.println (hhu);

    hhu = map(hhu, 0, 1023, 16, 100);
    hhu = constrain(hhu, 16, 100);

    Serial.println("the actual Humidity is ");
    Serial.println (hhu);
    Serial.println("-----------------------");
    delay(100);
    g_fisInput[1] = hhu;

    g_fisOutput[0] = 0;

    fis_evaluate();

    // Set output vlaue: Power
    int ppower1 = g_fisOutput[0];
   // Serial.println("the actual Power is ");
   // Serial.println (ppower1);
    ppower = map(ppower1,100,3000,0,255);
    ppower = constrain (ppower, 0,255);
    analogWrite(power , ppower);

   // Serial.println("the analoge Tempreture is ");
    //Serial.println (ppower);
   // Serial.println("--------------------------");

}

Too much RAM usage from all those strings in SRAM?

With the complete program we could try to compile it and possibly run it. But without the globals and setup() function, we can't really do much more than guess.

Try using the Serial.println(F("String")); instead of Serial.println("String") to utilize progmem rather than SRAM.

You should have provided your full Arduino code. Without setup() part of Arduino code, we can not exactly tell what might be wrong. Please provide it and I'll revise my answer as well.
Check if you have this code in your setup() function:
Serial.begin(9600);

9600 is baud rate and it could be any other supported baud rate(you can see those by opening a Serial monitor and clicking on 9600 baud rate on bottom right edge).
Related to to comments above, from experience and it can be easily "counted", RAM shouldn't be a problem in such short code.

source: Stack Exchange

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

sort: votes


text:
Arduino mega R17 led blink continuously
I have bought 10 Arduino Mega 2560 clones and all of them have the same problem. When I connect the to my PC I get a message that windows cannot recognize that device and the LED at the board in R17 blinks non stop. normally this led stops when the arduino is ready. Also in the Arduino IDE I don't see the port option enable.

Have you installed the drivers?

Yes because i have another arduino mega and a duemilanove and they work

Are they genuine Arduino?

No they are clones and the working one is also clone

You're on your own then. Who know what they might be doing... or even what they might be.

Do you know what the R17 led is for? so i can search for it?

I don't even know what an R17 LED is.

Let us continue this discussion in chat.

Nobody can help you. You have some unknown clone and we don't know what it is. Maybe start with editing your question to include exactly what it is you have bought. Only then can we begin to help you.

This is what i bought        https://www.hellasdigital.gr/electronics/boards/microcontrollers/atmega2560-16au-ch340g-mega-2560-r3-board-usb-cable-for-arduino/

You need to install CH340 drivers!

i have downloaded the drivers and also installed them but in the device manager i dont see it. Windows still sees the arduino as unrecognized

I think the LED you mean is the one marked L which is situated next to resistor R17 (if I can read it on that small image). That is connected to pin 13, and it blinks. It blinks when there is no sketch installed, and it blinks when the default Blink.ino sketch is installed. Either way it blinks until you tell it to do something else. The CH340 chips are next to useless. They kind of work sometimes if you're lucky. Then suddenly they will die out of the blue. They are not good.

The CH340 don't just die actually. Clones get bricked by the drivers. Plus Windows with it's drivers has always been bad. All my Nanos that have the same chips have been working just fine like two years already but under a linux distro always.

Majenko you are correct for the L i didnt see that and i thought it was the R17 resistor. So if i manage to make it work and upload a sketch to it and power it via DC power supply one day will it stop working or if i make a lot of sketch uploads? I want them in order to have 4-5 sensors on them and some push buttons in order to do basic functions

Once the sketch is uploaded the CH340 is not required. Therefore it should keep working. Making a lot of uploads is not a problem, unless you are talking about over 10,000 uploads.

The CH340 is very susceptible to static. They die. They are cheap, and many corners have been cut, including ESD protection and, most notably, drivers.

You need CH340G drivers. CH340G is a chip that basically replaces the usual ATMega 8U2/16U2 that is used for USB to serial interface. As CH340 cannot be reprogrammed it means that you can't emulate other USB devices with your arduino for example a keyboard.

You can download the drivers here.

i have downloaded them before and installed them. Also my concern is that the boot led is not stoping to flash even though  i power it from DC power supply and not USB.

Boot LED? There are three LEDs. The RX, the TX, power and the manual controlled one that blinks on reset and with certain code.
I am also 100% sure you have installed the drivers wrong if Device Manager can't detect the device.

i know the TX and RX leds also in the MEGA there are 2 more leds that blink when you boot it and when it boots the stay ON. In my version now i have one led flashing non stop.

also in the drivers installation process i got the message drivers installed correctly so i dont know why windows still not recognize it. I have Windows 10 64bit

The two more LEDs are power (ON) and LED (L). No boot LED; use the right terms that way people can understand you a bit better. Just a friendly reminder.
Have you rebooted your machine fully? Google how to do that as I don't have Windows, pressing restart won't do it.
Also what pops up if you disconnect and reconnect the Arduino to your PC, does a driver installation window pop up?

Sorry for wrong terms but i am new to the arduino world and i dont know a lot. yes i rebooted it now removed the battery for total reboot again nothing. Also what is that flashing led that blink non stop? next to it is another led that is on permanent. The TX and RX leds are not flasing at all and the are located above those leds that i told you

Usually unprogrammed Arduinos have a Blink sketch uploaded to them as default (just blinking a led). You have to upload something new to it for it to stop but Windows can't detect the CH340G chip, so I'd suggest you'd uninstall the drivers, unplug all Arduinos before and when the uninstall is completed, reboot the machine again. Now reinstall the drivers as it was told and reconnect the Arduino. Now open the "Searching for drivers" window and wait for it to complete, make sure you have internet connection.

Let us continue this discussion in chat.

also i checked my other working arduino mega which has also the CH340G chip so the drivers are in my PC. :S

In device manager when i connect one of the faulty boards i see device descriptor request failed but when i connect the working one i see USB CH340 SERIAL(COM3)

@AgisSoleas Do not connect a single new CH340 based board. It might be that the driver is bricking them. Download an Ubuntu Live ISO and try Arduino IDE there to see if it's actually the drivers.

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


text:
NRF24 and usb digispark
I want to connect NRf24 module with digispark and use USB capabilities at same time.
currently, i use this conexion diagram:
               NC      PB5  1|o   |8  Vcc --- nRF24L01  VCC, pin2 --- LED --- 5V
nRF24L01  CE, pin3 --- PB3  2|    |7  PB2 --- nRF24L01  SCK, pin5
nRF24L01 CSN, pin4 --- PB4  3|    |6  PB1 --- nRF24L01 MOSI, pin6
nRF24L01 GND, pin1 --- GND  4|    |5  PB0 --- nRF24L01 MISO, pin7

Bu my problem is that as you see in this diagram CE and CSN are in the USB + and - pins:

I just want that my module receive data so, i think that if i power up every time CE pin and i change CSN pin to PB5 this may work but, in fact this don't
I can't use 3 pin connexion because i don't have capacitor and my project is for Wednesday
Thanks in advance for your help

so, what is your question?

it is possible to use digispark with NRF24 and USB keyboard without use system that need capacitors as the tree cable solution? I just want to use the digispark as RX

As per https://digistump.com/wiki/digispark/tutorials/basics:
Pin 3 and Pin 4 (P3 and P4) are used for USB communication and programming, while you can use them in your circuit if you are not using USB communication, you may have to unplug your circuit during programming if the circuit would impede the pin states or dramatically affect the voltage levels on these pins.

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


text:
POST request not working
I'm following a guide on storing sensor data to MySQL:
Guide
My POST request isn't getting any results to my server. For now, I'm only storing temperature.
Here is my code for saving data:
void sendData(double input) {
  String data = "sensorid=3000000&temp=" + doubleToString(input, 2) + "&hum=1.2";

  if (client.connect("192.168.1.50", 80)) {
    client.println("POST /arduino/add.php HTTP/1.1");
    client.println("Host: 192.168.1.50");
    // client.println("User-Agent: Arduino/1.0");
    // client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.print(data.length());
    client.println();
    client.print(data);

    Serial.println("Sent data: " + data);
  }

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

  delay(300000);
}

I've commented out two headers since it did not give any other results. My Serial.println gives: Sent data: sensorid=3000000&temp=24.00&hum=1.2, which means that the Arduino is connected to the given IP-adress and that my request data is as I want. They are also working perfectly when I'm testing with Requestmaker, so I'm pretty sure my error comes from the way I'm doing the request here.
Do you have any idea how I can solve or debug this?

There needs to be an empty line between the headers and the body of the request. Therefore you have to println() (not print()) the end of the last header.

Try to use print() with '\n' at the end (only a newline, not carriage return.
xportSendTextNoLine("C192.168.200.136/80\n"); sprintf(request,"GET /debug.php?dat=%u HTTP/1.0\n\n",value); xportSendTextNoLine(request); <-- This worked for me. But you'll have to change it a bit to arduino code.

did you solve this problem. I am having exactly the same issue and came to the same conclusion: the error comes from the way I am doing the request from the arduino.

yes, the first comment was the solution to my problem. End with println instead of print. Could not mark it as answer since it was only a comment.

Answered by Edgar Bonet
There needs to be an empty line between the headers and the body of the request. Therefore you have to println() (not print()) the end of the last header.

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


text:
Arduino Nano and ESP32 Read Different Values over Serial
I am trying to use the Neato xv11 lidar with an ESP32. This should output packets of 22 bytes with the starting byte 0xFA. The communication is 8N1 and the baud rate is 115200.
When I connect the Lidar TX to the ESP32 RX2 pin, I get data that does not make sense as I get the start byte every 9 (and sometimes 8) bytes. However, when I run the same code on an Arduino Nano, I get the correct 22 byte packages. I even connected both at once and logged the results in Putty. This is the data I got.
// Arduino Nano Code
void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
}
void loop() {
  while (Serial1.available()) {
    Serial.println(Serial1.read(),HEX);
  }
}

// ESP32 Code
void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
}

void loop() {
  while (Serial2.available()) {
    Serial.println(Serial2.read(),HEX);
  }
}

ESP32
FA
A8
0
35
6D
11
17
71
3D
FA
A9
0
3D
12
97
12
10
D1
41
FA
AA
0
E1
E
14
12
E7
1F
FA
AB

Arduino Nano
FA
D8
74
35
6B
3
3D
1
7B
3
3B
1
8C
3
2B
1
9F
3
1C
1
A
1D
FA
D9
74
35
B2
3

try running Serial at a higher baud rate ... also try using if, instead of while

did you check the voltage of the communication?

I checked the voltage and tried voltage converters. The ESP32 still gets strange data. I also tried to use an if statement instead of while and that did not fix it. It is very strange behaviour.


text:
Converting three-axis magnetometer values to degrees
I have a 9-DOF sensor (MPU-9150) and I want to use its magnetometer to retrieve the rotation angle, from 0 to 359. However, its library returns three values: x, y and z.
I do not know how to transform this into a single value. Is there any way to do this?

It is giving you the vector that runs along the local magnetic field -- ideally it points to magnetic north. The rotation mapping between the measurement and magnetic north should give you your heading.

Reading the datasheet could be very enlightening. Have you tried it?

@Majenko Yes, but nothing really useful.

So, basically, is it even possible to compute a heading (with tilt compensation) with a magnetometer only (no gyrometer or accelerometer)?

The answer given by Dave X, namely
az=90-atan(y/x)*180/pi

is on the right track. However, it cannot work as is for two reasons:

The formula fails badly whenever x = 0,

It gives the same azimuth for x = y = 1 and for x = y = −1. In other
words, it cannot differentiate between north-east and south-west.

The formula could be fixed by replacing atan(y/x) by a function that
returns:

atan(y/x) if x > 0
π/2 if x = 0 and y > 0
−π/2 if x = 0 and y < 0
atan(y/x) + π if x < 0 and y ≥ 0
atan(y/x) − π if x < 0 and y < 0

That would be essentially a two-argument, “quadrant-aware” version of
the arctangent, yielding results in (-π, π] instead of
(−π/2, π/2).
Fortunately, such function already exists. It is a very standard
function of the C library and is called atan2(). Thus, the correct
formula is
az = 90 - atan2(y, x) * 180 / M_PI;

Now, since atan(y/x) = π/2 − atan(x/y), the formula above can be
simplified into
az = atan2(x, y) * 180 / M_PI;

This formula gives the direction of the (x, y) vector counted clockwise
from the y axis. It is likely that the OP wants instead to know the
heading of some kind of vehicle. The correct formula depends then on how
the magnetometer has been mounted relative to the vehicle. If we assume
that the x axis of the magnetometer points forward and the y axis points
to the left, then:

the vehicle is heading north (0° magnetic heading) when the horizontal
component of the magnetic field is along +x
the vehicle is heading east (90° magnetic heading) when the horizontal
component of the magnetic field is along +y

From here, it follows that the vehicle heading is
heading = atan2(y, x) * 180 / M_PI;

Obviously, the magnetic declination has to be added if one is
interested in the true (rather than magnetic) heading.

Edit: All this assumes the XY plane is horizontal. If it is not
(due to the vehicle's pitch and roll), see Tails86's answer for a
way to cope with that.

You first need calibration (either using the device calibration method, or, by rotating it in a complete circle to ascertain the full field strengths).
You can then use the X, Y, and Z readings to compute the location of "north" relative to whichever way you're pointing (keeping in mind that "north" changes as much as 30 degrees depending where on earth you are (called declination - see http://www.magnetic-declination.com/), and that it's not horizontal to the ground either (confusingly, called "inclination" - see https://physics.stackexchange.com/questions/283761/if-you-hold-a-compass-needle-vertical-does-it-point-down-or-up-differently-on-wh/283782 )
If you picture the X, Y, and Z readings as meaning "where on an imaginary circle is the direction of magnetism - where those 3 circles are on 3 different planes, you can compute the logical position of a vector pointing towards magnetic north in 3 dimensions.
The bad news - there's no simple way to do what you want accurately, and definitely not one that's going to work without trig math on all 3 readings (you can't just use X and/or Y alone).
The good news - you probably don't really need to know an actual "heading" - most applications just need some local relative direction as compared with something you already know.
Beware that strong magnets (such as ones in all modern motors) seriously mess with readings from a long way away (10 or more foot even) - grab an app from your phone store that shows your phone magnetometer readings, and wave a magnet around to see this easily!

I wanted to expand upon what Anon is getting at and provide some math as I've just gone through this process for a similar 9-axis device.
First, it's good to know what the magnetic field vector means. I like this source because it provides an image showing where magnetic vectors point as you move up and down earth. It points downward on the northern hemisphere and upward in the southern hemisphere. The text is otherwise not relevant as it more or less just explains how you can approximate laitudinal position from that data - the angle of the horizontal component is all that we need to be concerned with in order to obtain a heading.
The problem with Edgar's answer is that it assumes that your reference plane is flat against earth. As soon as you add any pitch or roll, that answer won't be right. To correct, you need to project the magnetic field vector onto your horizontal plane. Luckily, that sensor also provides you with an accelerometer which provides a way to tell you which way is down due to the force of gravity as long as you're not moving around too quickly.
What I did was project the magnetic field vector onto the acceleration vector then subtracted that from the magnetic field vector to get the horizontal component vector. Then I could retrieve the vector angle on the X/Y plane just as described by others.
First, a partial definition of a vector so I'm not depending on external libraries:
    class Vector3D
    {
    public:
        Vector3D() : mArr{} {}

        Vector3D(double x, double y, double z)
        {
            mArr[0] = x;
            mArr[1] = y;
            mArr[2] = z;
        }

        double dot(const Vector3D& rhs) const
        {
            double out = 0;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out = out + mArr[i] * rhs.mArr[i];
            }
            return out;
        }

        Vector3D operator* (double x) const
        {
            Vector3D out;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out.mArr[i] = mArr[i] * x;
            }
            return out;
        }

        Vector3D operator- (const Vector3D& x) const
        {
            Vector3D out;
            for (int i = 0; i < NUM_DIMENSIONS; ++i)
            {
                out.mArr[i] = mArr[i] - x.mArr[i];
            }
            return out;
        }

        double getX() const {return mArr[0];}
        double getY() const {return mArr[1];}
        double getZ() const {return mArr[2];}

    private:
        static const int NUM_DIMENSIONS = 3;
        double mArr[NUM_DIMENSIONS];
    };

    Vector3D operator* (double x, const Vector3D& y)
    {
        return (y * x);
    }

Here is how the compass angle can be computed:
    // mag: magnetic vector
    // accel: acceleration vector (due to gravity)
    double computeYaw(double mag_x, double mag_y, double mag_z, double accel_x, double accel_y, double accel_z)
    {
        const Vector3D vector_mag(mag_x, mag_y, mag_z);
        const Vector3D vector_down(accel_x, accel_y, accel_z);
        const Vector3D vector_north = vector_mag - ((vector_mag.dot(vector_down) / vector_down.dot(vector_down)) * vector_down);
        return atan2(vector_north.getX(), vector_north.getY()) * 180 / M_PI;
    }

EDIT: I changed the code so needed elements of a Vector are defined here so there is no confusion.
EDIT2: Here is a good resource on this subject if you need a more accurate solution. As stated in this resource, the above is only really useful if you're not moving around too much and your magnetic environment is clean.

tf2/LinearMath/Vector3.h: No such file or directory. Got a link to the library?

Very good point! Note that: 1. If the platform is moving, we can get a better estimate of the vertical by combining the accelerometer data with the gyro data. 2. For better accuracy, atan2() should be fed with the components of the magnetization in the horizontal plane, rather than the platform's XY plane.

Edgar - That is indeed a big issue with this implementation. Any small movements will skew the result. I found that averaging the result over 20 samples was enough to smooth that out for my own needs as I'm dealing with a slow moving device.

Is there any open source lib that implements all the math of the article linked in the second edit?

This is a basic math problem.
az=90-atan(y/x)*180/pi

"atan()" is arctangent and converts from coordinate variables to angle in radians, *180/pi converts from radians to degrees, and 90- converts from degrees math angles (degrees CCW from the x axis) to azimuth (degrees CW from north).
Calibrating the sensor is a trickier problem.


text:
HTTPS Client with MKR1000
I am making an IoT device with the MKR1000.
As a part of the process, I would like to set up an HTTPS connection to https://hit.tl8.co/api/ping (this is a website I have made and control).
The problem is that client.connect(url, 443) is returning false. I have tried normal HTTP and the URL works on a browser. I can also access https://www.google.com. The code is a small variation of the example HTTP client.
As such, I believe that the TLS certificate I am using is not accessible by the MKR1000. Running this report shows that it is a RSA 2048 bits (e 65537) with SHA256withRSA certificate.
Is there a way to get the MKR1000 to accept this certificate? Failing that, what changes do I need to make to this certificate for it to work?
Is there a software solution to get this certificate working?

You need to use connectSSL() instead of connect(), and possibly add your certificate to the MKR1000 as described on Hackster.


text:
About Wemos D1 WiFi
I bought the Wemos D1 WiFi and I am wondering how to operate this. So, inside the Arduino IDE, I downloaded ESP8266 boards, I see WeMos D1 mini, WeMos D1 R1, and WeMos mini Pro/Lite.
Why in the world don't I see Wemos D1?
How can I operate this board without the D1 board to select in the Arduino IDE?
Is there a way to add, or anyways to operate it?
I don't mind using other software besides the Arduino IDE if it's the only way to work with D1.
Board:

I get this Error when trying to upload D1 R1:
C:\...\ArduinoData\packages\esp8266\tools\esptool\2.5.0-3-20ed2b9/esptool.exe -vv -cd nodemcu -cb 115200 -cp COM6 -ca 0x00000 -cf
C:\...\Temp\arduino_build_179604/sketch_jan15a.ino.bin
esptool v0.4.13-1-gf80ae31 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
setting board to nodemcu
setting baudrate from 115200 to 115200
setting port from COM1 to COM6
setting address from 0x00000000 to 0x00000000
espcomm_upload_file
espcomm_upload_mem
setting serial port timeouts to 1000 ms
opening bootloader
resetting board
trying to connect
flush start
An error occurred while uploading the sketch
setting serial port timeouts to 1 ms
setting serial port timeouts to 1000 ms
flush complete
espcomm_send_command: sending command header
espcomm_send_command: sending command payload
read 0, requested 1
trying to connect
flush start
setting serial port timeouts to 1 ms
setting serial port timeouts to 1000 ms
flush complete
espcomm_send_command: sending command header
espcomm_send_command: sending command payload
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
espcomm_send_command: receiving 2 bytes of data
Uploading 287488 bytes from
C:\...\arduino_build_179604/sketch_jan15a.ino.bin to flash at 0x00000000
erasing flash
size: 046300 address: 000000
first_sector_index: 0
total_sector_count: 71
head_sector_count: 16
adjusted_sector_count: 55
erase_size: 037000
espcomm_send_command: sending command header
espcomm_send_command: sending command payload
setting serial port timeouts to 15000 ms
read 0, requested 1
setting serial port timeouts to 1000 ms
warning: espcomm_send_command: didn't receive command response
warning: espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed
closing bootloader
flush start
setting serial port timeouts to 1 ms
setting serial port timeouts to 1000 ms
flush complete
error: espcomm_upload_mem failed

this is D1 R1 .

Your board is a WeMos D1 R1. You need to select Tools > Board > WeMos D1 R1 in the Arduino IDE.
Here's a good comparison of the difference between the WeMos D1 R1 and the WeMos D1 R2:
https://github.com/arendst/Sonoff-Tasmota/wiki/Wemos-D1-R1-&-R2

I forgot to mention that I get an error when trying to upload WeMos D1 R1.


text:
Sensor/servo shield for Arduino Mega
Is there Arduino shields with blocks of 4 pins that you can plug your servos into and use the fourth pin as signal pin to the Arduino Mega board?

You could (probably) easily make this yourself (using an Arduino prototype board and some pin-headers) or buy an arduino "servo controller shield".
Also, Arduino.Stack Exchange isn't the place for shopping recommendations, you could ask suppliers/manufacturers if they have such a thing available.
It's also a little unclear, do you want the 3 servo's to receive the same signal? You could simply attach them to the same header and "short", solder or jumper the pins together.

Do you mean something like a sensor shield? They have three pins (Vcc, GND, signal), not four (because servos have three pins), but they are designed for connecting a large number of servos
These can be found easily and cheaply all over the internet.


text:
Arduino UNO only works with Monitor Serial opened
My Arduino Uno will not work without the Serial Monitor opened. I have a PHP script to send data to the board. When I send the data, the TX and L LEDs light up, but the action is not executed. It is only executed when the Serial Monitor is opened. Can you please help me?
Code in Arduino:
int const RED = 2;

int status = 0, temp =0;

void setup() {
  pinMode(RED, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  if(Serial.available() > 0) {
    temp = Serial.read();
    if(temp != -1)
      status = temp - '0';

    Serial.print("status: ");
    Serial.println(status);

    if(status == 1)
      digitalWrite(RED, HIGH);
    else
      digitalWrite(RED, LOW);

    delay(1000);
  }

}

PHP script:
<!DOCTYPE html>
<html>
    <head>
        <title>Alarme</title>
    </head>
    <body>
        <form action="#" method="post">
            <input type="submit" name="alarme" value="ON">
        </form>

        <form action="#" method="post">
            <input type="submit" name="alarme" value="OFF">
        </form>
    </body>
</html>

<?php

$port = fopen("/dev/ttyUSB0", "w");
fwrite($port, ($_POST['alarme'] == 'ON') ? 1 : 0);
fclose($port);

My circuit is simple, it only consists of one LED and a 220 ohm resistor.

Hello and welcome to Arduino SE! I'm going to close this question because it lacks a clear example of the problem (code and any applicable circuit) that we need to help you fix your issue. Once you have a clear, minimal example of the problem's code and wiring, feel free to edit your question and it may be reopened. Thanks!

@AnonymousPenguin I added details

On many (most ?) systems, you can't open the port and immediately write to it, as that will result in a time consuming auto-reset.  You need to hold the port open and configured in general, and write when you need something.

I fixed, see my answer

The problem was the auto-reset of the Arduino, I disabled it.
To disable, I connected a 10uf capacitor on the GND and RES. As in the image below:

Interesting!  I have a few sketches I remember have failed until I open the Serial Monitor.  I had a heck of a time with one writing between a rpi and a bluno nano, so Ill go check that out later.  But more recently, I have a sketch that writes data from the bluno nano to an iOS app and sometimes Ill plug in the bluno nano to a usb battery and open up the iOS app BlunoTerminal and Ill get (null) (null) (null)...I plug the bluno nano into the laptop and check BlunoTerminal and still (null) (null) (null)...but I open up the Serial Monitor and voila, values start pouring in!

Signed in to thank you very much. After tons of frustration this made my day! Had the same problem as described, and diagnosing it was incredibly hard.


text:
Pin Mapping of nRF2401L01+ using Adafruit's nRF24L01+ library
I have an Arduino Uno and one of these nRF24L01+ from china (see image)

To use the module i wanted to use the library provided by Adafruit (http://playground.arduino.cc/InterfacingWithHardware/Nrf2401). My problem is, that they're using different names for some pins, because the library is designed for a different module with the following pin outs.

I don't know which PIN from the China module corresponds to the DAT and DR1 Pin on the Adafruit module.
So my questions are:

Is it OK to use the library in conjunction with the china module?
What are the DAT and DR1 PIN on the module from China ?

What I know so far:
- took a look into the library and into the documentation at playground.arduino.cc/InterfacingWithHardware/Nrf2401 and found out that the DR1 pin is for the available() function to check if data is available to be read.

Compare these two schematics and you have the answer; http://cdn.sparkfun.com/datasheets/Wireless/Nordic/nRF2401A-Chip-v11.pdf and http://mcuoneclipse.files.wordpress.com/2013/07/nrf24l01-schematic.png?w=584&h=359

DR1 is MISO
DAT is MOSI

Though I'd advice using the RF24 library, as it's a lot more recent than the one from 2009 you linked to.

Plus it supports additional layers like RF24Mesh and RF24Network that allow you to create simple, multiple node networks.

Thanks for the pin mapping! I will take a look at the library you both mentioned.


text:
Read ISO/IEC 14443B (NFC Type B) with PN532
I bought a PN532 from Elechouse (documentation here) because I need to read IDs from Type B NFC cards.
My problem is that even if they say the hardware supports Type B, the official libraries an examples they provide are not made to.
I have not problem reading Type A cards, but nothing happends when I tap Type B cards.
After long searchs on internet I found that absolutely every PN532 sellers have chosen to support only Type A cards in their libraries because according to them, a librari supporting both types would have taken too much space in Arduino's memory.
So today my problem is as simple as that: how to read Type B NFC cards using PN532 on an Arduino UNO?
I'm a bit new in Arduino so after many hours of searching and trying I couldn't figure out how to do it.

Same problem even using libnfc
doesn´t work with that card, only recognizes it
i read that it could be an antenna problem, because of the elechouse pn532.
I´m going to try to made an external antenna

We eventually gave up after many attempts, even involving other developpers, turned out the protocol was quite specific, in the end we used smartphones with NFC capability that could read it.

I dont have an exact reply but
1) are you certain the other tags are type b?
2) hace you tried connecting the reader using a UART USB cable? You could use libnfc, to check if the reader works.
And going forward at commands FOR the reader are a good way to debbug.


text:
error ph meter cant show the data
im using ph meter DFROBOT v1.0 at i compiled the code from the DFROBOT web this is the code
*
 # This sample code is used to test the pH meter V1.0.
 # Editor : YouYou
 # Ver    : 1.0
 # Product: analog pH meter
 # SKU    : SEN0161
*/
#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;
void setup(void)
{
  pinMode(LED,OUTPUT);
  Serial.begin(9600);
  Serial.println("pH meter experiment!");    //Test the serial monitor
}
void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    Serial.print("Voltage:");
        Serial.print(voltage,2);
        Serial.print("    pH value: ");
    Serial.println(pHValue,2);
        digitalWrite(LED,digitalRead(LED)^1);
        printTime=millis();
  }
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}

and its work, untill i want to combine thats code to my code, the ph value = 0.00
im just copy paste the code from the website in to my code and its not working what should i do
void loop()
{
  //-------------Read Function sensor-----------
//  PPM----
    gravityTds.setTemperature(temperature);  // set the temperature and execute temperature compensation
    gravityTds.update();  //sample and calculate

    tdsValue = gravityTds.getTdsValue();
    tdsValue=(tdsValue *2)/1000;// then get EC the value
    Serial.print(tdsValue,5);
    Serial.println("ppm");

    hasilec = (ppmcensor - inputec );
    Serial.print("Eror EC : ");
    Serial.println(hasilec,6);

// ph-----
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  Serial.print("Nilai pH :");
  Serial.println(voltage,2);

//  ph = (phcensor - inputph);

//  hasilec = random(-200, 0) / 100.0;
//  ph = random(-200, 200) / 100.0;
  ph = 130/100.0;

  unsigned long now = millis();

  SerialMon.print("EROOR pH    ");
  SerialMon.print(ph);
  SerialMon.print("  ");
  SerialMon.print("ERORR EC ");
  SerialMon.print(hasilec);
  SerialMon.println("");
  SerialMon.print(ph);  Serial.print(" ");
  SerialMon.print(hasilec);   Serial.print(" ");
  SerialMon.println(" ");

  fuzzy->setInput(2, hasilec);
  fuzzy->setInput(1, ph);
  fuzzy->fuzzify();

  float pompa01 = fuzzy->defuzzify(1);//pHDOWN
  float pompa02 = fuzzy->defuzzify(2);//pHUP
  float pompa03 = fuzzy->defuzzify(3);//ABMIX

  SerialMon.println("Result= ");
  SerialMon.println("");
  SerialMon.print(" Pompa1 pHDOWN: ");
  SerialMon.println(pompa01);
  SerialMon.print(" pompa2 phUP  : ");
  SerialMon.println(pompa02);
  SerialMon.print(" pompa3 ABMIX : ");
  SerialMon.println(pompa03);
  SerialMon.println("");
  SerialMon.println("");
  SerialMon.println("");

  delay (2000);

  long int pompa1 = pompa01*1000;
  long int pompa2 = pompa02*1000;
  long int pompa3 = pompa03*1000;

  pump_periods[0] = pompa1; //PHdown
  pump_periods[1] = pompa2; //PHup
  pump_periods[2] = pompa3; //ABMIX

//  for (int i = 0; i < jml_pump; i++) {
//      if (now - pump_last_actuations[i] >= pump_periods[i]) {
//          pump_states[i] = (pump_states[i] == LOW) ? HIGH : LOW;

//          digitalWrite(pump_pins[i], pump_states[i]);
//          pump_last_actuations[i] = now;
//      }
//  }

  for (int i = 0; i < jml_pump; i++) {
  digitalWrite(pump_pins[i], LOW);     // Start pump i
  delay(pump_periods[i]);            // nyala waktu dalam pompa[i] ms
  digitalWrite(pump_pins[i], HIGH);     // Stop pump i
  }
  delay(100000);
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}

What exactly do you mean by copy&pasting the code into your code? You cannot simply do that, because you can only have 1 void loop() function and 1 void setup() function

the first code its from https://wiki.dfrobot.com/Gravity__Analog_pH_Sensor_Meter_Kit_V2_SKU_SEN0161-V2
and i add that code to my code

As I wrote, you cannot simply do that. Combining two codes is more complex than that

yep thx for helping me


text:
Else Statement Never Functions As Expected
I've been working on a rather simple Arduino-breadboard project, that is supposed to imitate a traffic light intersection. There are two sets of lights, one called the North-South lights, and then the East-West lights (quite similar to the traffic lights your would see at an intersection on the road). The goal is to get the traffic lights to turn their correct colors at the correct times; however, one of my yellow lights is not turning on at all, and the breadboard LEDs I'm using completely skip over the yellow light in question and go straight to the red-green configuratin that is supposed to happen after.
Here is the code I have:
void setup() {

  pinMode(2, OUTPUT); //R-ns
  pinMode(3, OUTPUT); //Y-ns
  pinMode(4, OUTPUT); //G-ns
  pinMode(5, OUTPUT); //R-ew
  pinMode(6, OUTPUT); //Y-ew
  pinMode(7, OUTPUT); //G-ew

}

void loop() {

  for(int count = 0; count<16; count++) {

    if (count<7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, HIGH);
      }

     else if (count==7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      }

     else if (7<count<15) {
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

     else {
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

    delay(1000);
    }

}

As you can see, the North-South traffic light is supposed to turn on at the 16th second, except I don't see it happen on the physical LED. I don't understand why this is happening; can anyone explain what is happening?

use serial.print() to debug your code

7<count<15 is interpreted as (7<count)<15.  7<count will result in a false or true, which will be interpreted as 0 and 1 when later involved in the < 15 part of the expression, which means 7<count<15 is always true.
What you're probably looking for is 7 < count && count < 15.


text:
What size diode should I use?
I'm building a project with an ESP8266 which requires multiple analog inputs - but the ESP8266 only has one. I know of ways to multiplex with dedicated modules, but since I have lots of diodes lying around I've decided to multiplex with them. I've found lots of tutorials on how to multiplex (e.g. this one) but none of them say what size diode to use.
So which size shall I use? Does it even matter? I have 1N4148s, 1N4007s, 1N5819s, 1N5399s, 1N5408s, 1N5822s, FR107s and FR207s.

By the time you finish mucking around powering different devices from I/O pins (which have a limit to how much current they can source) and then install different diodes for each one, you are probably better off (and more simply) to use a multiplexer like the 74HC4051 which I describe here.
As Gil mentioned in his reply, the 0.7V drop (or thereabouts) that the diodes will incur are going to affect the accuracy of the readings, plus you have the issue that the devices might take a few milliseconds to stablise if you keep turning them on and off.
To answer your question, though, any signal diode should do the trick as there will be very little current drawn, as the analog input is high impedance. For example the 1N4148.
You can connect 8 devices to the 74HC4051 with only 4 connections between it and the microprocessor. Three "selector" pins which therefore give you 8 possible combinations, and the signal pin which would go to your analog input.
You could even get a 74HC4067 and have 16 inputs, for the cost of only one more selector pin.

I do not think it is possible to truly multiplex analog signals with simply using diodes in an 'or' configuration. Your demo shows powering only one sensor at a time and isolating the sensors (pots) output with the diode "or". This demo works as long as only one sensor is powered and or the rest output voltage is below the one you are measuring. You also have a voltage drop across the diode and nothing to keep the signal stable, it will bounce around by the forward voltage of the diode or more. The diode will add about a 10% error and reduce your measurement range. To stabilize it you need to add some resistance between the analog input of the microprocessor and ground (load sensor output). This will introduce some error in your reading but you can compensate for that. Any diode will work, use one that you're comfortable with or you can check their characteristics and make a choice.


text:
Sending dynamic data to webserver
I am trying to send data to a php file via http GET method.
I am able to send static data but I am unable to send dynamic data.
#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(9, 10);

char inchar;
int ledPin = 13;
int sensorPin = A0;
int sensorValue = 0;

boolean gs = true;
boolean es = true;
boolean ss = false;

void setup()
{
  gprsSerial.begin(9600);
  gprsSerial.println("AT+CNMI = 2,2,0,0");
  Serial.begin(9600);
}
void loop()
{
   currentMillis = millis();
   if(gprsSerial.available()>0)
  {
    inchar = gprsSerial.read();
    if (inchar == '#')
    {
      delay(10);
      inchar = gprsSerial.read();
      if (inchar == '1')
      {
        Serial.println("System Enabled");
        ss = true;
        snd_msg(0);
      }
      else if (inchar == '0')
      {
        Serial.println("System Disabled");
        ss = false;
        snd_msg(1);
      }
      delay(10);
      inchar = gprsSerial.read();
      if (inchar == '1')
      {
        Serial.println("Geofence Enabled");
        gs = true;
        snd_msg(2);
      }
      else if (inchar == '0')
      {
        Serial.println("Geofence Disabled");
        gs = false;
        snd_msg(3);
      }
      delay(10);
    }
  }
    gprs();
    delay(10000);
}

void toSerial()
{
  while(gprsSerial.available()!=0)
  {
    Serial.write(gprsSerial.read());
  }
}
 void snd_msg(int a)
{
  gprsSerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  gprsSerial.println("AT+CMGS=\"+918148090646\"\r"); // Replace x with mobile number
  delay(1000);
  if ( a == 0)
  {
    gprsSerial.println("System Enabled");
  }
  else if ( a == 1)
  {
    gprsSerial.println("System Disabled");
  }
  else if ( a == 2)
  {
    gprsSerial.println("Geofence Enabled");
  }
  else if ( a == 3)
  {
    gprsSerial.println("Geofence Disabled");
  }
  delay(100);
   gprsSerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  gprsSerial.println("AT+CNMI = 2,2,0,0");
  delay(1000);
}
void vibra_sensor()
{
  sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue);
  for(int i = 0; i < 5; i++)
  {
  if (sensorValue > 500)
  {
    es = true;
    break;
  }
  else
    es = false;
  delay(500);
  }
  delay(1000);
}
void gprs()
{
  vibra_sensor();
  Serial.println("Config SIM900...");
  delay(2000);
  Serial.println("Done!...");
  gprsSerial.flush();
  Serial.flush();

  // attach or detach from GPRS service
  gprsSerial.println("AT+CGATT?");
  delay(100);
  toSerial();

  // bearer settings
  gprsSerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
  delay(2000);
  toSerial();

  // bearer settings
  gprsSerial.println("AT+SAPBR=3,1,\"APN\",\"www\"");
  delay(2000);
  toSerial();

  // bearer settings
  gprsSerial.println("AT+SAPBR=1,1");
  delay(2000);
  toSerial();
  // initialize http service
  gprsSerial.println("AT+HTTPINIT");
   delay(6000);
   toSerial();

   // set http param value
 **gprsSerial.println("AT+HTTPPARA=\"URL\",\"adnansait74.000webhostapp.com/operation.php?timestamp=02:50:00&latitude=11.374545&longitude=76.728986&gfence=OFF&estatus=OFF&sstatus=ON\"");**
   delay(5000);
   toSerial();

   // set http action type 0 = GET, 1 = POST, 2 = HEAD
   gprsSerial.println("AT+HTTPACTION=0");
   delay(6000);
   toSerial();

   // read server response
   gprsSerial.println("AT+HTTPREAD");
   delay(1000);
   toSerial();

   gprsSerial.println("");
   gprsSerial.println("AT+HTTPTERM");
   toSerial();
   delay(300);

   gprsSerial.println("");
   delay(10000);
   gprsSerial.println("AT+CNMI = 2,2,0,0");
  delay(1000);
}

What I've Tried
1.) Saving URL in a string
String URL = "adnansait74.000webhostapp.com/operation.php?timestamp=02:50:00&latitude=11.374545&longitude=76.728986&gfence=OFF&estatus=OFF&sstatus=";
    URL += ss;
    gprsSerial.println("AT+HTTPPARA=\"URL\",\"+URL\"");

Doesn't Work
2.)Attaching values using print statement
gprsSerial.println("AT+HTTPPARA=\"URL\",\"adnansait74.000webhostapp.com/operation.php?timestamp=02:50:00&latitude=11.374545&longitude=76.728986&gfence=OFF&estatus=OFF&sstatus=");
gprsSerial.println(ss+"\"");

3.)Entering value directly in URL
gprsSerial.println("AT+HTTPPARA=\"URL\",\"adnansait74.000webhostapp.com/operation.php?timestamp=02:50:00&latitude=11.374545&longitude=76.728986&gfence=OFF&estatus=OFF&sstatus="+ss+"\");

Error
invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+'

I'm using an arduino uno and a sim 900a GSM module.
QUESTION
How do I send dynamic values for gfence, sstatus, estatus?
I am also using a messaging service, the code is included. The help I need is in the gprs() function.
The data I need to send is,
gfence from gs
sstatus from ss
estatus from es

How does this not work? The GPS module returns an error? The HTTP server returns an error? Your PHP script returns an error?

it is unclear what you mean by static data and dynamic data.

boolean ss = false; ..... URL += ss; .... ..... binary 'operator+' ............... you cannot concatenate a boolean value True  .... you can concatenate a string value "abc123" or "True"

+URL is not a valid URL. The syntax highlighting should have given you a hint.

You should split it up:
gprsSerial.print(F("AT+HTTPPARA=\"URL\",\"adnansait74.000webhostapp.com/operation.php?timestamp=02:50:00&latitude=11.374545&longitude=76.728986&gfence=OFF&estatus=OFF&sstatus="));
gprsSerial.print(ss);
gprsSerial.println(F("\""));

Note the use of print on each part up until the last part which is the only one that uses println in order to terminate the line.
Also note the use of the F() macro to reduce the wastage of RAM that string constants cause.

F() for one character?

Sure. Frugality is key with 2k ram

ok, I eventually googled that it is has no overhead in code

@Juraj I could have switched to Serial.println('"'); (i.e., use a single char), but that would most likely have confused the OP. Best to keep things simple.


text:
EEPROM size limitation issue
I am creating a test program with Arduino Nano where I can save network and password. Here is my code to start with:
void SaveNetwork(String ssid, String pass){
  String com = ssid + "~" + pass;
  const char *array = com.c_str();
  for(int i = 0; i<sizeof(com); i++){
    EEPROM.write(i, array[i]);
  }
  Serial.println("Saved");
  char ar[255] = "";  //test read string.
  for(int i = 0; i<sizeof(com); i++){
    ar[i] = EEPROM.read(i);
  }
  Serial.println(ar);
}

SaveNetwork("Testing", "Network123......");

Now I print ar string which is suppose to return ssid, "~" and password.
BUT what I get is "Testin" instead of "Testing~Network123......".
Is there is a limitation for EEPROM size? If so, how can I expand the capacity, should I use a memory chip, or what is the code I should use to resolve this?

The problem is with sizeof(com) in your loops. sizeof() is for C arrays, not string objects. If you print it, it will report 6, which is not the length of the array. For string objects you should use com.length() instead. Then the output becomes

Saved
Testing~Network123......

P.S. The EEPROM can store 1024 bytes on ATmega328P-based boards (I believe that's what most Arduino Nanos use (clones included).


text:
Arduino ESP8266 Webserver SD
I connect Micro SD card adapter to my esp8266. I uploaded the SD webserver example sketch into the esp8266, everything works perfectly once I created index.htm, now I add LED to digital pin 4, now, how do I turn on and off LED with just a simple button inside the website?
Like anything I need to add inside the example sketch? Or using javascript inside the .htm file? I tried to figure out but it's just hard, I need some help. I'll be back in couple hours. Thank you.
ESP8266 Arduino IDE example sketch code:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>
#include <SD.h>

#define DBG_OUTPUT_PORT Serial

const char* ssid = "(hidden)";
const char* password = "(hidden)";
const char* host = "esp8266sd";

ESP8266WebServer server(80);

static bool hasSD = false;
File uploadFile;

void returnOK() {
  server.send(200, "text/plain", "");
}

void returnFail(String msg) {
  server.send(500, "text/plain", msg + "\r\n");
}

bool loadFromSdCard(String path){
  String dataType = "text/plain";
  if(path.endsWith("/")) path += "index.htm";

  if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
  else if(path.endsWith(".htm")) dataType = "text/html";
  else if(path.endsWith(".css")) dataType = "text/css";
  else if(path.endsWith(".js")) dataType = "application/javascript";
  else if(path.endsWith(".png")) dataType = "image/png";
  else if(path.endsWith(".gif")) dataType = "image/gif";
  else if(path.endsWith(".jpg")) dataType = "image/jpeg";
  else if(path.endsWith(".ico")) dataType = "image/x-icon";
  else if(path.endsWith(".xml")) dataType = "text/xml";
  else if(path.endsWith(".pdf")) dataType = "application/pdf";
  else if(path.endsWith(".zip")) dataType = "application/zip";

  File dataFile = SD.open(path.c_str());
  if(dataFile.isDirectory()){
    path += "/index.htm";
    dataType = "text/html";
    dataFile = SD.open(path.c_str());
  }

  if (!dataFile)
    return false;

  if (server.hasArg("download")) dataType = "application/octet-stream";

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    DBG_OUTPUT_PORT.println("Sent less data than expected!");
  }

  dataFile.close();
  return true;
}

void handleFileUpload(){
  if(server.uri() != "/edit") return;
  HTTPUpload& upload = server.upload();
  if(upload.status == UPLOAD_FILE_START){
    if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
    DBG_OUTPUT_PORT.print("Upload: START, filename: ");
    DBG_OUTPUT_PORT.println(upload.filename);
  } else if(upload.status == UPLOAD_FILE_WRITE){

    if(uploadFile) uploadFile.write(upload.buf, upload.currentSize);
    DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: ");
    DBG_OUTPUT_PORT.println(upload.currentSize);

  } else if(upload.status == UPLOAD_FILE_END){

    if(uploadFile) uploadFile.close();
    DBG_OUTPUT_PORT.print("Upload: END, Size: ");
    DBG_OUTPUT_PORT.println(upload.totalSize);
  }
}

void deleteRecursive(String path){
  File file = SD.open((char *)path.c_str());
  if(!file.isDirectory()){
    file.close();
    SD.remove((char *)path.c_str());
    return;
  }

  file.rewindDirectory();
  while(true) {
    File entry = file.openNextFile();
    if (!entry) break;
    String entryPath = path + "/" +entry.name();
    if(entry.isDirectory()){
      entry.close();
      deleteRecursive(entryPath);
    } else {
      entry.close();
      SD.remove((char *)entryPath.c_str());
    }
    yield();
  }

  SD.rmdir((char *)path.c_str());
  file.close();
}

void handleDelete(){
  if(server.args() == 0) return returnFail("BAD ARGS");
  String path = server.arg(0);
  if(path == "/" || !SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }
  deleteRecursive(path);
  returnOK();
}

void handleCreate(){
  if(server.args() == 0) return returnFail("BAD ARGS");
  String path = server.arg(0);
  if(path == "/" || SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }

  if(path.indexOf('.') > 0){
    File file = SD.open((char *)path.c_str(), FILE_WRITE);
    if(file){
      file.write((const char *)0);
      file.close();
    }
  } else {
    SD.mkdir((char *)path.c_str());
  }
  returnOK();
}

void printDirectory() {
  if(!server.hasArg("dir")) return returnFail("BAD ARGS");
  String path = server.arg("dir");
  if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
  File dir = SD.open((char *)path.c_str());
  path = String();
  if(!dir.isDirectory()){
    dir.close();
    return returnFail("NOT DIR");
  }
  dir.rewindDirectory();
  server.setContentLength(CONTENT_LENGTH_UNKNOWN);
  server.send(200, "text/json", "");
  WiFiClient client = server.client();

  server.sendContent("[");
  for (int cnt = 0; true; ++cnt) {
    File entry = dir.openNextFile();
    if (!entry)
    break;

    String output;
    if (cnt > 0)
      output = ',';

    output += "{\"type\":\"";
    output += (entry.isDirectory()) ? "dir" : "file";
    output += "\",\"name\":\"";
    output += entry.name();
    output += "\"";
    output += "}";
    server.sendContent(output);
    entry.close();
 }
 server.sendContent("]");
 dir.close();
}

void handleNotFound(){
  if(hasSD && loadFromSdCard(server.uri())) return;
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  DBG_OUTPUT_PORT.print(message);
}

void setup(void){
  DBG_OUTPUT_PORT.begin(115200);
  DBG_OUTPUT_PORT.setDebugOutput(true);
  DBG_OUTPUT_PORT.print("\n");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  DBG_OUTPUT_PORT.print("Connecting to ");
  DBG_OUTPUT_PORT.println(ssid);

  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
    delay(500);
  }
  if(i == 21){
    DBG_OUTPUT_PORT.print("Could not connect to");
    DBG_OUTPUT_PORT.println(ssid);
    while(1) delay(500);
  }
  DBG_OUTPUT_PORT.print("Connected! IP address: ");
  DBG_OUTPUT_PORT.println(WiFi.localIP());

  if (MDNS.begin(host)) {
    MDNS.addService("http", "tcp", 80);
    DBG_OUTPUT_PORT.println("MDNS responder started");
    DBG_OUTPUT_PORT.print("You can now connect to http://");
    DBG_OUTPUT_PORT.print(host);
    DBG_OUTPUT_PORT.println(".local");
  }

  server.on("/list", HTTP_GET, printDirectory);
  server.on("/edit", HTTP_DELETE, handleDelete);
  server.on("/edit", HTTP_PUT, handleCreate);
  server.on("/edit", HTTP_POST, [](){ returnOK(); }, handleFileUpload);
  server.onNotFound(handleNotFound);

  server.begin();
  DBG_OUTPUT_PORT.println("HTTP server started");

  if (SD.begin(SS)){
     DBG_OUTPUT_PORT.println("SD Card initialized.");
     hasSD = true;
  }
}

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

Now my html code:
<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <form>
            <input type="submit" name="TURNON" value="LED"/>
        </form>
    </body>
</html>

create a html form with action url directing to esp8266 and handle that url in the sketch. https://www.w3schools.com/html/html_forms.asp

https://babaawesam.com/2015/11/26/control-input-output-of-esp8266-with-ajax/

Tip: create a new server.on(...) for your new URL to react to the button press.

And which parameters should I set?

@SupBoy, the url parameter is yours, name it and set a value you want

you need to build a hardware-controlling micro API for your web page to hit using ajax or plain forms

Would you plz tell how to connect SD card module in node MCU pin.


text:
What am I missing? Send data from Matlab to Arduino to Micro SD
First off. This is not in any way a class assignment. This is my own personal work and research. I just want to get that out of the way.
I am learning how to use Matlab with various Arduino projects. I am a seasoned Matlab user but I am fairly new to the entire Arduino space.
I am trying to send some numerical data from Matlab (via a GUI) to my Arduino Uno and have the Arduino write it to my micro SC card. This is a temporary step to my larger project. However, there is no need to go into those specifics as they are outside of the scope of my issues.
I am fairly confident that the Matlab code works and the Arduino code is slightly modified from another project I did where I wrote and read random numbers from my micro SD card.
However, as I run the Matlab code, the Arduino blinks as if it is receiving the data but after I check the micro SD card it remains blank.
I am confident that my Arduino is wired correctly to my micro SD card adapter since this remains the same from my prior project.
Therefore, I am sure I am missing something trivial to get it to work.
I have researched several websites on the subject and their method and mine seem to align very well.
I am fairly certain the problem is in the conditional statement:
if (Serial.available() > 0) {

As you will see.
The Matlab code is below:
arduinoCom = serial('COM3', 'BaudRate', 115200);
sendData = 5;
fopen(arduinoCom);
fprintf(arduinoCom,'%i',sendData); %this will send 5 to the arduino
fclose(arduinoCom);
delete(arduinoCom);

The Arduino code is as follows:
#include <SD.h> // load SD library

int chipSelect = 4;  // Chip select pin for the MicroSD Card Adapter
int incomingByte = 0; // for incoming serial data.
File SDF; // Serial data received is saved here.

void setup() {
     Serial.begin(115200); // start serial connection to print out debug messages and data
     pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode
     if (!SD.begin(chipSelect)) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong.
     }
     while (!Serial) {
     }
}

void loop() {
        // Open file, Write data, Close file only when you receive data
        if (Serial.available() > 0) {
           incomingByte = Serial.read();
           SDF = SD.open("SerialDataFile.txt", FILE_WRITE); // open "SerialDataFile.txt" to write data
           SDF.println(incomingByte, DEC); // write ASCII-encoded decimal number to file
           SDF.close(); // close file
           }
}

The expected result would be a file "SerialDataFile.txt" stored on my micro SD card with the value 5.
Thank you for your help!

Comments are not for extended discussion; this conversation has been moved to chat.

Look, this is not a forum. Please refrain from answering the question, or making suggestions, in comments. Comments under the question are for clarifying any confusing parts of the question, and requesting further information.

I am not seeing a way to check this answer as complete. - there is some sort of time delay. Check back tomorrow.

The board resets on new USB connection with fopen. Wait 2 secs between fopen and fprintf in Mathlab code.


text:
How to code multiple conditions inside if statement?
I have a system that checks the value of a moisture sensor and will also check the time
if (t.hour == 7 && t.min == 00 && moistureOneSensorValue >= 700) {
  RelayOne();
  RelayTwo();
}

When moistureOneSensorValue is greater than or equal to 700 it means the soil is DRY, so when all conditions inside the if statement are true the relayOne and relayTwo functions will be called.
My problem is that when moistureOneSensorValue is still moist the above if statement will result in false and the relayOne and relayTwo functions will not be called. I want Arduino to execute and call the relayOne and relayTwo functions and disregard the time. I use time so that the system will only call the relayOne and relayTwo functions in the morning at exactly 7 AM every day, but it needs to check/make sure that the soil is DRY...
Example
First thing in the morning the system will check the time and sensor value; if the if statement results in false the system will keep monitoring and try the if statement until the soil is DRY. But I think when that happens it will be over 7 AM.
Sorry for the messy explanation.

I think where is says "s still moist" in your question you meant to say "s still dry".

yeah , when it still dry the if statement will result in true ..

You first have to sort out in your head what you want the Arduino to do. At this point it just seems you do not know what you want.

I'm not sure how quickly you soil could get dry, but I suspect what you want to do is to periodically check the dryness throughout the day. Say like every two hours:
// Check every 2 hrs (when hr is even)
if ( t.hour % 2 == 0 && moistureOneSensorValue >= 700 ) {...}

You could also bound it to only during the day time:
if ( t.hour >= 7 // after 7a
  && t.hour <= 19 // before 7p
  && t.hour % 2 == 1 // every 2 hrs (when hr is odd)
  && moistureOneSensorValue >= 700 // soil is dry
) {...}

If the event is to be time independent then it follows you can not check the time.  If the event is to be both time independent and dependent then you need to add the code to handle the logic.
Consider checking if it is between 7am and, say, 7pm.  If true then test if the moisture detector is dry.  If true then close (watering) relays.
(This is only a code example and has not been tested.)
if(t.hour >= 7 && t.hour <= 19)
{
  while(moistureOneSensorValue >= 700)
  {
   RelayOne();
   RelayTwo();
  }
}

Consider adding a state machine to mitigate possible problems by monitoring minimum times between events and maximum times of events.  For example, do not water more than once per 5 minutes.  Do not water more than 30 seconds at a time.  Do not water more then a total of 1 minute per hour.  Do not water more than 5 minutes per 24 hours.

So i just code like this , if (t.hour == 7 && t.min == 00 && ) {   while(moistureOneSensorValue >= 700) RelayOne();   RelayTwo(); }

An untested code example has been added to the answer.

what if the soil is quickly dry ? so it will water the plant more than the allowed watering a day

Those were examples times and constraints.  If I were to make an automated watering system I would be very very worried about water damage should something go wrong.  Maybe you will have a fix amount of water such as a watering jug as your water source so as to avoid the problem.  Maybe you will only do this out side where watering problems will do less damage.  Maybe you need to enhance your software such that it will mitigate over or under watering problems.  Maybe you are watering a 10 ounce potted plant & need to keep the times short.  Maybe you are watering a plot of tomato vines.

I'm just saying, there are a lot of open ended problems for such a project.  Software can offer the flexibility to solve most of them.  But you need to think each and every problem through.

I'm connecting/interfacing  my arduino with java .. and use solenoid valve and water flow sensor to control the water

As of now this is the last problem i'm facing if (t.hour == 7 && t.min == 00 && ) { while(moistureOneSensorValue >= 700) RelayOne(); RelayTwo(); }


text:
Syntax for declaring more than one serial pins of Arduino mega?
How can I declare multiple serial ports for Arduino Mega as it has been in the example below?
#include <SoftwareSerial.h>
SoftwareSerial mySerial(18,19); // RX, TX  //how this syntax can be modified for multiple Rx module?

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

void loop(){
   Serial.write(45);    // send a byte with the value 45

   int bytesSent = Serial.write(â€œhelloâ€); //send the string â€œhelloâ€ and return the length of the string.
}

The Mega has four UARTs. Why are you using SoftwareSerial?

@IgnacioVazquez-Abrams..... But how i can access four Softwareserial for Arduino mega?like syntax for single serial port is as,                 SoftwareSerial mySerial(18,19); // RX, TX

@Code Gorilla    But how i can access four Softwareserial for Arduino mega?like syntax for single serial port is as, SoftwareSerial mySerial(18,19); // RX, TX – Hafeez Ahmad Fii Zue 2 mins ago    edit

If you mean the built in serial ports then just user the other objects that are pre-declared as per:
https://www.arduino.cc/en/Serial/Begin

From the official docs on serial:

The Arduino Mega has three additional serial ports: Serial1 on pins 19 (RX) and 18 (TX), Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX).

Which means, you use Serial1 for serial on pins 19 and 18 instead of Serial:
void setup(){
   Serial1.begin(9600);
}

void loop(){
   Serial1.write(45);    // send a byte with the value 45

   int bytesSent = Serial1.write("hello"); //send the string "hello" and return the length of the string.
}

what will be the syntax for serial two and three if it is "SoftwareSerial mySerial(18,19)" for serial 1

Isn't is obvious? Did you read the quoted text?

how can we access more than two Softwareserial?

Why do you need software serials if you have 4 hardware serials?

can i share you the complete code so that you can amend it easily?  i need yours email id?


text:
Why sensor acts erratically?
I am trying to connect an ADXL355 digital sensor to an Arduino. The wiring and the code I think are OK because the system returns the correct values sometimes and partly correct answers mostly. The code checks the device register, and the correct data is printed to serial most of the time. The code also checks for temperature but only returns the correct value occasionally. The values are polled every few seconds. The values are correct all of the time if they are correct the first time after restart but never if they are incorrect on restart. I thought it might help to unplug the sensor when uploading the program or powering up the Arduino through USB to the computer but there is no clear pattern.
It is not a defective sensor because I have 2 that behave the same way. What could be the problem? Is this a problem with the Arduino?

I only wire VDD, VDDIO, ground,chip select, sclk, MOSI and MISO.
code:
#include <SPI.h>

    const int ID = 0x00;
    const int FIFO = 0x11;
    const int TEMP = 0x06;
    const int TEMP1 = 0x07;
    const byte FIFO_WATERMARK = 0x29;
    const int chipSelectPin = 7;

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

        SPI.begin();

        pinMode(dataReadyPin, INPUT);
        pinMode(chipSelectPin, OUTPUT);

        // writing 0 to to enable sensor
        writeRegister(0x2D, 0x00);

        delay(100);

        Serial.println(readRegister(ID));
        Serial.println(readRegister(FIFO_WATERMARK));
    }

    void loop() {
        int temp = (readRegister(TEMP)); // << 8) | (readRegister(TEMP1))) ;
        temp = (temp<<8)|(readRegister(TEMP1));
        Serial.println(((1852 - temp)/9.05) + 19.21);
        Serial.println(readRegister(ID));

        delay(1000);
    }

    byte readRegister (byte thisRegister){
        byte inByte = 0 ;
        SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // 500khz clock
        digitalWrite(chipSelectPin, LOW);
        SPI.transfer((thisRegister << 1) | 1);
        inByte = SPI.transfer(0x00);
        digitalWrite(chipSelectPin, HIGH);
        return inByte;
    }
    void writeRegister (byte thisRegister, byte value){
        SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // 500khz clock
        digitalWrite(chipSelectPin, LOW);
        SPI.transfer(thisRegister << 1);
        SPI.transfer(value);
        digitalWrite(chipSelectPin, HIGH);
    }

Some one suggested it might be signal bounce on the SPI and the clock rate was set to 500kHz but it didn't work.
Update:
Not long ago, the correct device ID would be read consistently (173 for 0xAD); now that returns 0. The temperature would either return 0 from the register or changing values between -1 and -5 that may have been wrongly calibrated temperature. But sometimes the correct temperature would return. Now it also only returns 0 from the registers.

Could you show some of the output you get?

@Gerben I updated the post with the outputs.

Try adding a bit of delay after setting the ChipSelect pin low.

@Gerben It didn't work, outputs are 0.

This is a poor product, look at this: that describes exactly the problems you (and me) are experiencing. Correct me if you've found any solutions so far.
edit
Try looking at description of regster 0x2f in datasheet and to this question.
I think that the first problem you describe can be solved this way, the second behaviour sounds like you fried the device.

While that link may provide an answer to the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.

Per your post looks like you have not wired any grounds. Consider wiring Analog and Digital grounds.

Here are excerpts from the datasheet

Thank you. I forgot to mention that I wired the ground. But I did not the VSSIO. Someone also suggested it was because the sensor runs on 3.3 V and the Arduino on 5.

Regardless of 3.3V or 5V GND is 0V. DGND and AGND are internally isolated. So erratic behavior can be explained due to poor grounding. Good luck. BTW don't cross post questions.

It could also be caused by insufficient or unregulated power supply.

@Mahendra Gunawardena 6 The VSSIO is tied to the VSS through the P1 6 pin header

Attaching a small ceramic or electrolytic capacitor to the power rail /might/ help to reduce the issue.


text:
Low-byte fuse programming of ATmega328 on Arduino Uno
I want to use the ATmega328 on my Arduino Uno board to clock a TDC1000 using the clkout bit of the ATmega328, but this requires fuse programming of the low byte. Can anyone tell me how to do this?

Get a programmer and use avrdude.

Do you have another Arduino? If so, check this video and you can set the fuses with AVRDUDESS.
Be careful: if you set the fuses the wrong way you kind of "brick" the chip, and depending on the mess, you can only recover with a high voltage programmer.
One advantage is that you can never ruin the chip with the fuses, just make it hard to reset to some defaults.


text:
Program ESP01 and keep it after reboot
I am bit of a noob when it comes to ESP programming. I have an ESP01 and a USB programmer for it, but every time I unplug it, it resets, which makes me wonder how can I make it battery-powered since every reboot resets the program.

What do you mean by 'reset the program'? The uploaded program should be retained on the esp01 and start running again after a reset/reboot.

Are you sure, that the program was correctly written to the ESP? How do you see, that the program is not working?

I wrote a simple blink program which made it blink when it was programmed.. But once i remove the usb programmer with the esp on, the turns off due to loosing power and when i then plug it in. I start as it was reset.. I flash it using arduino

It stops blinking in the intended frequency

if you have io 0 to ground it always goes into flashing mode. you have to pull-up io 0

The ESP-01 ... and all ESP8622 ... have two modes for operation.

Flash mode / Boot load mode - on bootup (at the time an electrical current is first applied, or after the reset pin is grounded), if the GPIO0 (GPIO Zero) pin {On the ESP-01 this is the 7th pin} is connected to ground, the chip goes into non-run, receive program mode.  This is where you load the compiled program.

Normal - on bootup (as above), but GPIO0 is NOT ground, then the ESP-01 goes into run mode.

I had it in flash mode all the time.


text:
Arduino I2C maximum number of writes per transmisson
Is there any limit on the number of Wire.write() commands consecutively in between the Wire.beginTransmission() command and the Wire.endTransmission() command for the Arduino Wire library?

@pascalm Don't worry, the answers would get migrated too.

There are five buffers used by the TWI and Wire library. They are defined as 32 bytes.
In wire.h:
#define BUFFER_LENGTH 32

In Wire.cpp:
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
...
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];

In twi.h:
  #define TWI_BUFFER_LENGTH 32

In twi.c:
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
...
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
...
static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];

So immediately you are using 5 x 32 bytes (160 bytes).

You could increase that to (say) 64 bytes, bearing in mind your 160 byte overhead is now 320 bytes, and you don't have a lot of RAM.
The comments about endTransmission() are correct. After a Wire.beginTransmission() nothing is actually transmitted until the endTransmission() call. This lets you fill up the buffer at your leisure, and then let the library do the writes in a fairly timing-specific way.

Reference

I2C
Wire Library

A quick look at the source code implies that there is a fixed length buffer of 32 bytes:
From the header file wire.h:
#define BUFFER_LENGTH 32

And from the implementation of the write function:
size_t TwoWire::write(uint8_t data)
{
  if(transmitting){
  // in master transmitter mode
    // don't bother if buffer is full
    if(txBufferLength >= BUFFER_LENGTH){
      setWriteError();
      return 0;
    }
    // put byte in tx buffer
    txBuffer[txBufferIndex] = data;
    ++txBufferIndex;
    // update amount in buffer
    txBufferLength = txBufferIndex;
  }else{
  // in slave send mode
    // reply to master
    twi_transmit(&data, 1);
  }
  return 1;
}

I'm fairly certain that buffer gets consumed via the interrupt during transmission, so you could transmit more than 32 bytes as long as you check that the buffer's not full before writing.

@NickJohnson Maybe, I didn't eyeball all the code, but according to the documentation, transmission doesn't begin until you call endTransmission so I assume multiple writes before then might overflow. The function's return code should be examined in any case.

ok, thanks, this corresponds exactly to what I am experiencing, a maximum of 32 bytes can be sent. Is this a hardware restriction or simply a buffer that is set up in ram, in other words, could i simply augment it? eg #define BUFFER_LENGTH 64?

@Roger You're right, it doesn't start transmitting until you call endTransmission. Hooray, a new Arduino library stupidity!

@pascalm It's definitely not a hardware issue. It'd be difficult to increase the buffer size without modifying the Arduino libs, but you could instead call the low-level functions endTransmission calls with your own buffer: https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/avr/libraries/Wire/utility/twi.c#L177

ok thanks, i'll dive into that code a bit then:)

The buffer size can be increased.
Should go to the twi.h fil, Wire.h file and set the desired length of the variable: BUFFER_LENGTH

authors: Александр Молодых


text:
ESP8266 and interrupts - not possible?
I'm planning to use an ESP8266 (Wemos D1 Mini) to use as a software SPI monitor to send over WiFi.
As a test, I've done a cut-down sketch that just counts the interrupts, a simple frequency counter. I've made it as simple as possible but it won't stay connected to WiFi and crashes after about 10 seconds.
The input signal to CLKPin is 6667 Hz.
Here's the sketch:
#include <ESP8266WiFi.h>

const char* ssid     = "SSID";
const char* password = "PASSWORD";

long nextPrint = 1000; // when to print the next message to serial

const int CLKPin = 5; // Pin connected to CLK
volatile long ClkCount = 0; // number of times clock interrupt has fired

void CLK_ISR() {
  ClkCount++;
}

void setup() {
  Serial.begin(115200);
  long startTime = millis();

  WiFi.begin(ssid, password);             // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");

  while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to wifi");

  attachInterrupt(CLKPin, CLK_ISR, RISING);

  //Set the CLK-pin to input
  pinMode(CLKPin, INPUT);
}

void loop() {
  if (millis() > nextPrint) {
    Serial.print("Freq is: ");
    Serial.println(ClkCount);
    ClkCount = 0;
    nextPrint += 1000;
  }
  yield();
}

It always gets in a reboot/crash loop (no idea why the first few counts are wrong - I guess the ESP isn't ready yet):
Connecting to SSID ...
.Connected to wifi
Freq is: 1
Freq is: 1
Freq is: 0
Freq is: 0
Freq is: 1
Freq is: 0
Freq is: 2313
Freq is: 6667
Freq is: 6666
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667

Exception (0):
epc1=0x40202034 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys
sp: 3ffffc40 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffde0:  401067da 00000026 00000000 00000001
3ffffdf0:  c0017025 3ffe8d04 3ffee188 00000001
3ffffe00:  00000003 00000008 3ffee99c 00000022
3ffffe10:  3fffc200 401067a0 3fffc258 4000050c
3ffffe20:  40004384 00000030 00000012 ffffffff
3ffffe30:  60000200 00000006 30043003 80000000
3ffffe40:  20000000 3fff0c38 80000000 203fc120
3ffffe50:  00000000 3fffc6fc 00000001 3fff0c3c
3ffffe60:  00000154 003fc120 60000600 00000030
3ffffe70:  40106845 00000080 00000022 3fffc200
3ffffe80:  c0017025 3fffc258 4000050c 00000022
3ffffe90:  3fffc200 401067a0 3fffc258 00000022
3ffffea0:  3fffc200 401067a0 3fffc258 4000050c
3ffffeb0:  40202b20 00000030 00000012 ffffffff
3ffffec0:  40000f49 3ffee9e8 00000000 3fffd9d0
3ffffed0:  00000000 00000000 00000000 fffffffe
3ffffee0:  ffffffff 3fffc6fc 00000001 3fffdab0
3ffffef0:  00000000 3fffdad0 3ffee9e8 00000030
3fffff00:  3ffee99c 0000000a 3ffe8bc8 402094cc
3fffff10:  00000000 400042db 3ffeff84 40104580
3fffff20:  40004b31 3fff0b84 000001f4 003fc080
3fffff30:  40105aac 000001f4 3ffed190 401004f4
3fffff40:  40106e4d 3fff0b84 00000000 00f8676f
3fffff50:  3ffe8bc8 3ffe8d04 3ffed190 40224d02
3fffff60:  40223d49 40223d52 3ffed004 3ffee1b0
3fffff70:  40228445 3ffed004 3ffee1b0 00f857fe
3fffff80:  4022848a 3fffdab0 00000000 3fffdcb0
3fffff90:  3ffee1c8 3fffdad0 3ffee9e8 40202b43
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(1,6)

 ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset

What am I doing wrong, or is it just not possible to stay connected to WiFi while using interrupts on an ESP8266?

Does it still crash if you reduce your CLKPin rate from 6667Hz to something lower?  The reason I ask is that I'm not sure what the maximum interrupt rate the ESP8266 but you may be exceeding it.  The error is a "wdt reset" which means that you have done something to prevent the watchdog timer from being cleared and so it generated a reset.

If you want to get the time difference of the last counter reset and the actual millis() value then  nextPrint += 1000; is nonsense. Use nextPrint = millis() + 1000; if you need to capture the ClkCount for an interval of a second. I'm pretty sure that's the reason for the low values at the beginning. In addition to what @jwh20 said: I'm not convinced that the Watchdog is the cause, I think another Error  (perhaps caused by the WIFI lib) crashed the ESP and then the Watchdog did it's job and performed a reset. But it's a guess, jwh20 might be right, so try what he/she wrote.

Just tested, and it did stay connected at 5kHz for 15 mins when I stopped testing. Unfortunately I'm not sure if that'll be fast enough for my application. I still would like to know if there's anything I can do to keep the WiFi connected. I don't really mind about missing data but I need the WiFi to stay connected. I hoped that yield() would work.

@PeterPaulKiefer I didn't put much thought into getting accurate data for this test, I was just testing if the interrupts would work and stay connected to WiFi, so that timer code is just the first thing that came to mind.

What I suspect is going on, but have never tried this myself on an ESP8266, is that you are interrupting so often that the WiFi can't work properly and it disconnects.  I'm not sure if you can do what you are trying to do with an 8266.  Have you looked at an ESP32?  These have a dual-core CPU so you can handle the WiFi on one processor and handle your interrupts on the other.

You can always try to run your CPU at 160MHz (it's there in the board options if you have the Wemos D1 Mini board).

@jwh20 I agree, but it is disappointing. I tested the ESP32 and it worked fine up to 10kHz which is all I tested to, but I was hoping to get use out of some of these ESP8266's that I have lying around!

@jwh20 I found the solution, see my answer.

I found the solution on another forum.
You need to add the ICACHE_RAM_ATTR attribute to the interrupt so it stays in cache.
void ICACHE_RAM_ATTR CLK_ISR() {
  ClkCount++;
}

Now:
Freq is: 332596 - connected for 680s, operating at 160MHz

That's all I tested to, but 330kHz is a bit better than crashing at 7kHz, lol!
edit: I've discovered that it now crashes after exactly 1200s (20mins), repetitively.
I'm still investigating why, but I believe that it's some kind of watchdog timer.

Yes possible, but the ESP8266 only has one core and one set of peripherals. WiFi uses time, interrupts, and even the ADC peripheral, and maybe more.
This is why anything timing-critical, or time-intensive, is a pain to get to work properly on an ESP8266. It depends one what you are trying to do, of course, and also on if you can unload what you want to a peripheral the WiFi doesn't use, or if switching off WiFi is an option during parts of your code.
Generally, for applications such as yours, I would get an ESP32 or an Arduino Nano 33 IoT or any other solution that has a core for handling WiFi, and a core for you to use without restrictions. It makes development a more pleasant experience.
If, for some reason, you are bound to using an ESP8266, you would have to be more specific about what your eventual goal is; maybe a workaround can be found.

could also use a 2nd ESP8266 w/ wifi disabled, they are cheap, and w/o wifi, very fast and responsive.

Honestly I think ESP8266 is a poor choice for most things except wifi. PWM is flaky, it has no waking from sleep on external interrupt, and relatively high power usage compared to, eg STM32 or AVR. The only thing it's really good for is WiFi and large flash storage. Yes it could be an option in some circumstances, but two won't fit in the application I'm planning for right now.

@localhost fair nuf, I most like the cost and cpu/ram. Tbf, those issues are better w/o wifi; stable pwm, lower power, quick reboots.


text:
EDB. Is it possible to create multiple tables with db.create()?
Good day! I seem to be having trouble creating multiple tables with EDB. I am using Arduino UNO and SD Card module to save my db.
Here is my Serial.

Here is my table declaration.
struct LogEvent {
  int id;
  String fname;
  float temperature;
}
logEvent;

struct SecondEvent {
  int id;
  String lastname;
}
secondEvent;

Here is my db.create() code.
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
db.create(0, TABLE_SIZE, (unsigned int)sizeof(secondEvent));

Now, when I try to retrieve, it is a whack. Here is my save and retrieve code.
void createRecords(int num_recs, float correctTemperature)
{
    Serial.print("Creating Records... ");
    for (int recno = 1; recno <= num_recs; recno++)
    {
      correctId++;
      logEvent.id = correctId;
      logEvent.fname = "Brix Nicholson";
      logEvent.temperature = correctTemperature;
      secondEvent.id = correctId;
      EDB_Status result = db.appendRec(EDB_REC logEvent);
      if (result != EDB_OK) printError(result);
    }
  Serial.println("DONE");
}

void createRecordSecondEvent()
 {
   correctId++;
   secondEvent.id = correctId;
   secondEvent.lastname = "Secretaria";
   EDB_Status result = db.appendRec(EDB_REC secondEvent);
   if (result != EDB_OK) printError(result);
 }

void selectLastRecord()
{
  int lastRecNum = db.count();
  EDB_Status result = db.readRec(lastRecNum, EDB_REC logEvent);
  if(result == EDB_OK)
   {
     Serial.print(" ID: ");
     Serial.print(logEvent.id);
     Serial.print(" Name: ");
     Serial.print(logEvent.fname);
     Serial.print(" Temp: ");
     Serial.println(logEvent.temperature);
   }
   else printError(result);
}

void selectLastSecondRecord()
{
 int lastRecNum = db.count();
 EDB_Status result = db.readRec(lastRecNum, EDB_REC secondEvent);
 if(result == EDB_OK)
  {
   Serial.print("Second Event ID: ");
   Serial.print(secondEvent.id);
   Serial.print("Last Name: ");
   Serial.print(secondEvent.lastname);
  }
  else printError(result);
}

I missed about the address, its all good now. Thank you!

I think I have found the answer to my problem. I forgot to increase the address of the EDB_header.
I wrote:
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
db.create(0, TABLE_SIZE, (unsigned int)sizeof(secondEvent));

Instead of:
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
db.create(1, TABLE_SIZE, (unsigned int)sizeof(secondEvent));

I think I have found the answer to my problem. I forgot to increase
  the address of the EDB_header.

you're right about increasing the address of EDB_header.
But the address is the position from where the library starting reading/writing.
if you have a look at
https://github.com/jwhiddon/EDB/blob/master/EDB.cpp#L66
and
https://github.com/jwhiddon/EDB/blob/master/EDB.cpp#L34
the library writes a fixed size of the header in the binary format
which includes

a magic byte to recognize the EDB header
the number of records currently present in the table which is 0 at of this time
size of your single record
the size of the table (max amount of memory that the table is allowed to consume)

and to write a new record
https://github.com/jwhiddon/EDB/blob/master/EDB.cpp#L93
so in
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
db.create(1, TABLE_SIZE, (unsigned int)sizeof(secondEvent));

the second statement will override the old header excluding the first byte (0'th position)
the solution to your problem will be
unsigned int FIRST_TABLE_HEADER_POSITION = 0;
db.create(FIRST_TABLE_HEADER_POSITION, FIRST_TABLE_SIZE, (unsigned int)sizeof(logEvent));

unsigned int SECOND_TABLE_HEADER_POSITION = FIRST_TABLE_HEADER_POSITION + (unsigned int)sizeof(EDB_Header) + FIRST_TABLE_SIZE;

db.create(SECOND_TABLE_HEADER_POSITION, SECOND_TABLE_SIZE, (unsigned int)sizeof(secondEvent));

now you can use
EDB_Status result = db.open(FIRST_TABLE_HEADER_POSITION );

and
db.close();
EDB_Status result = db.open(SECOND_TABLE_HEADER_POSITION );