1

I'm new to Arduino and what I'm trying to do is change the variable by sending it from php to the Arduino.

I've added the delay as stated by other questions but it has not worked so far. The pin 13 LED so

Arduino Code

float val;
void setup() {

  Serial.begin(9600);
  
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
  val=29.1;

  Serial.println("Start!");
}

void loop() {

  if(Serial.available()){
    String temp = Serial.readStringUntil('\n'); //read string
    val = temp.toFloat(); //convert string to float
  }

  if(val==62.10){
    digitalWrite(13,HIGH);  
  }else{
    digitalWrite(13,LOW);  
  }

  Serial.println(val);
  delay(1000);
  
}

PHP Code

<?php
$port = fopen("COM3", "w");
sleep(2);
fwrite($port, "62.1");
fclose($port);
?>

Any tips would be much appreciated. Thank you for reading.

3
  • Comparing floats like that is never a good idea. There's no such thing as 62.1 as a floating point - the closest is 62.09999847412109375. Floats are only ever an approximation.
    – Majenko
    Mar 29, 2021 at 10:53
  • I see. Luckily for me, the comparison is only used for debugging. @Majenko
    – diggledoot
    Mar 29, 2021 at 10:55
  • 1
    You typically use abs(val - 62.1) < 0.05 where 0.05 is the 'accuracy you accept, so values between 62.05 and 62.15 are resulting in true Mar 29, 2021 at 11:00

1 Answer 1

1

You are writing "62.1" but you are trying to read up until a \n, which you never send.

You need to ensure that you send the end-of-line character that you subsequently check for,

fwrite($port, "62.1\n");

Also it's worth noting that floating point values are only ever an approximation. They're great for doing calculations, but very poor at doing comparisons. Your test value of 62.1 cannot be represented precisely as a floating point value, the closest being about 62.099. If you do need to do a comparison then you should check it's within a small range, not a precise value.


Your "problem" seems to stem from you opening the serial port with one program, sending a value, then closing the serial port and opening it again in something else and expecting to see that value being echoed back to you.

That can't happen on a stock Arduino UNO. Every time you open the serial port the DTR line toggles the RESET pin to enter the bootloader - which is why you need the 2 second delay after opening the serial port.

In doing so the sketch then runs fresh every time you open the serial port.

There are a number of ways of disabling that reset, from cutting a trace on the Arduino, to adding a large-ish (10µF +) capacitor between RESET and GND - both of which will interfere with your ability to program the board. The capacitor is the easier to reverse.

Ideally you'd use a different serial channel to communicate so it never interferes with the reset or programming. You could use SoftwareSerial and an external USB to UART adaptor instead of the Serial connection, or use a board with a native USB connection that doesn't reset when you open the serial port, such as a Leonardo.

2
  • I have added the \n to the fwrite and applied the changes. It seems that Arduino resets and is unable to read the previously sent value.
    – diggledoot
    Mar 29, 2021 at 11:18
  • 1
    Every time you open the serial port the Arduino resets, yes. That's what it does. There's plenty of writeups about that functionality and how to avoid it. Mostly they involve hardware changes.
    – Majenko
    Mar 29, 2021 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.