Update (record) database table via ethernet is not happening

Hi there I am new to the Arduino forum and I have a question. My intention is to read data from a KWH meter and send those data with a certain interval to a (XAMPP) SQL database. I managed to read the data from a single phase KWH meter and store it in the database with phpMyAdmin. The hardware is an Arduino Uno with ethernet shield and a home made prototypeboard shield with a MAX485 IC, to convert the TTL to MODBUS the language of the KWH meter and to display data with some LED's. This data might not be relevant for the problem I have, but just to be sure.

The problem: From Arduino I made a call to a PHP file, data.php which updates my table correctly.
I used this link to get my stuff running, which was a great help.
https://create.arduino.cc/projecthub/muhammad-aqib/logging-data-to-database-using-arduino-ethernet-shield-3e9a0e
Next I wanted to update another table log_book of the same database arduino which contains 2 fields. I made the PHP file similar tot data.php called record_log.php and stored it on th same directory as data.php. In my case /opt/lampp/htdos/ethernet (ubuntu). I did run the following command in the Brave browser

http://localhost/ethernet/record_log.php?request=2&response=23 and this correctly updated the log_book table. So the script is ok was my conclusion. Then I made the following simple code, just to check whether update will be carried out from Arduino. There was no update??? I checked the following:

  • item Compared syntax's data.php & record_log.php
  • compared authorizations of both files (the same)
  • checked the php_error_log (no entry)
  • checked the access_log file only entries found of successful update of file data.php.

The question where what can I check to discover what is going on???

Arduino code

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

#define LED_ERROR              5  // Indicates an error

byte mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
byte ip[] = {XXX, XXX, X, X }; //Enter the IP of ethernet shield
byte serv[] = {XXX, XXX, X, X} ; //Enter the IPv4 address, of the PC where the PHP pages exists.

int request = 25;
int response = 27;

EthernetClient eth_client;

void setup() 
{
  Ethernet.begin(mac, ip);
  pinMode(LED_ERROR, OUTPUT);                // Flashes the number of bytes
  Serial.begin(9600);                        // set serial communication baudrate
  delay(100);  

}

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

// Start log
void save_log()
{
 if (eth_client.connect(serv, 80)) 
 { //Connecting at the IP address and port we saved before
  Serial.println("connected for save log");
  flash_times(LED_ERROR, 250, 10);
  eth_client.print("GET /ethernet/record_log.php?");
  eth_client.print("&request=");
  eth_client.print(request);
  eth_client.print("&response=");
  eth_client.print(response);

  eth_client.stop(); //Closing the connection
} // end if
// 
else 
 {
  // if you didn't get a connection to the server:
  Serial.println("connection failed");
 } // end else
  delay(1000);
}
// End log

void flash_times(int pinno, int pulse_wdth, int no_times)
  // pin number "pinno" will flash "no_times" times with a pulse width of "pulse_wdth" in msec
{
  int f;
    for (f=0; f<no_times; f++)
    {
      digitalWrite(pinno,HIGH);
      delay(pulse_wdth);
      digitalWrite(pinno,LOW);
      delay(pulse_wdth);
    }
}type or paste code here

I don't think you want an '&' directly following the '?'.
The entire querystring should look something like this preceded by the server name:

/ethernet/record_log.php?request=24&response=27

Hi there many thanks for the quick response. I did already noticed that, but it did not seem to solve the problem. In my other arduino code (call to data.php) I also started with the &, but you right it is not correct. I changed that in the code, uploaded to the UNO, but unfortunately no update yet. I checked the access_log file more careful and see that messages are logged, also before this change. I am not sure whether this might give a clue. In the first line my table log_book is mentioned, but I don't understand the rest. Kind Regards Kees

::1 - - [19/Apr/2022:12:03:37 +0200] "GET /phpmyadmin/index.php?route=/sql&server=1&db=arduino&table=log_book&pos=0 HTTP/1.1" 200 16573
::1 - - [19/Apr/2022:12:03:38 +0200] "GET /phpmyadmin/themes/pmahomme/css/theme.css?v=5.1.3&nocache=813331281ltr&server=1 HTTP/1.1" 200 216144
::1 - - [19/Apr/2022:12:03:38 +0200] "GET /phpmyadmin/js/messages.php?l=en&v=5.1.3 HTTP/1.1" 200 7921
::1 - - [19/Apr/2022:12:03:38 +0200] "POST /phpmyadmin/index.php?route=/navigation&ajax_request=1 HTTP/1.1" 200 2316
::1 - - [19/Apr/2022:12:03:38 +0200] "POST /phpmyadmin/index.php?route=/config/get HTTP/1.1" 200 1532
::1 - - [19/Apr/2022:12:03:38 +0200] "POST /phpmyadmin/index.php?route=/config/get HTTP/1.1" 200 1622
::1 - - [19/Apr/2022:12:03:38 +0200] "GET /phpmyadmin/index.php?route=/recent-table&ajax_request=1&recent_table=1&no_debug=true&_nocache=1650362618542752788&token=5f48253f564535596e5c304570425972 HTTP/1.1" 200 1600
::1 - - [19/Apr/2022:12:03:38 +0200] "POST /phpmyadmin/index.php?route=/navigation&ajax_request=1 HTTP/1.1" 200 2048
::1 - - [19/Apr/2022:12:03:38 +0200] "POST /phpmyadmin/index.php?route=/config/set HTTP/1.1" 200 1522
::1 - - [19/Apr/2022:12:03:40 +0200] "GET /phpmyadmin/index.php?route=/sql&server=1&db=arduino&table=log_book&pos=0 HTTP/1.1" 200 16573
::1 - - [19/Apr/2022:12:03:41 +0200] "GET /phpmyadmin/themes/pmahomme/css/theme.css?v=5.1.3&nocache=1213826340ltr&server=1 HTTP/1.1" 200 216144
::1 - - [19/Apr/2022:12:03:41 +0200] "POST /phpmyadmin/index.php?route=/navigation&ajax_request=1 HTTP/1.1" 200 2674
::1 - - [19/Apr/2022:12:03:41 +0200] "POST /phpmyadmin/index.php?route=/config/get HTTP/1.1" 200 1532
::1 - - [19/Apr/2022:12:03:41 +0200] "POST /phpmyadmin/index.php?route=/config/get HTTP/1.1" 200 1622
::1 - - [19/Apr/2022:12:03:41 +0200] "GET /phpmyadmin/index.php?route=/recent-table&ajax_request=1&recent_table=1&no_debug=true&_nocache=1650362621322787276&token=5f48253f564535596e5c304570425972 HTTP/1.1" 200 1600
::1 - - [19/Apr/2022:12:03:41 +0200] "POST /phpmyadmin/index.php?route=/config/set HTTP/1.1" 200 1522
::1 - - [19/Apr/2022:12:03:49 +0200] "OPTIONS * HTTP/1.0" 200 -
::1 - - [19/Apr/2022:12:03:50 +0200] "OPTIONS * HTTP/1.0" 200 -type or paste code here

Have you another PC or smartphone which can talk to the XAMPP server? If so, issue the http://XXX.XXX.X.X/ethernet/record_log.php?request=2&response=23 command on the server where XXX.XXX.X.X is the server's IP address. This should help rule out any firewall problems on the XAMPP server blocking your access.

If you succeed, can you show the log entry for it in the Apache log similar to the ones you have already shown.

Can you also show the code of record_log.php

Hi 6v6gt,

The code of record_log.php, see below. I have a laptop with multiboot windows 10 & Ubuntu. I started with windows 10 with data.php. Then I decided to store extra in in a new table log_book, which I am not able to update. So I tried ubuntu installed XAMPP and tested, unfort the same result, but now I was able to see more in log files. The tcp/ip of the server (which is my laptop) is for both systems the same. Actually I don't have a separate server. Do you think that a firewall is causing this problem? Both files data.php and record_log.php use the same syntax, user and user authorizations and are stored in the same directory. Also the database and table have the same definitions and privileges, the database for both is database arduino. The files php are under mine user account, no root. Also the Arduino files have the same user and authorizations.

Do you mean I need another laptop or desktop, install XAMPP also there and try to run the program?
`
2022-04-19_19-56

connection.php

<?php
$username = "root";
$pass = "";
$host = "localhost";
$db_name = "arduino";
$con = mysqli_connect ($host, $username, $pass);
$db = mysqli_select_db ( $con, $db_name );
?>

record_log.php

<?php
include ('connection.php');
$sql_insert = "INSERT INTO log_book (request, response) 
              VALUES 
                ('".$_GET["request"]."', '".$_GET["response"]."')";
if(mysqli_query($con,$sql_insert))
{
echo "Done";
mysqli_close($con);
}
else
{
echo "error is ".mysqli_error($con );
}
?>

No. Don't install XAMPP anywhere else. Useful is only that there is an independent browser somewhere to contact the server.

If your laptop is running the XAMPP server then using a browser on that same server is not a full test because that may avoid firewalls etc that other devices have to go through.

If your laptop is running the XAMPP server, is it in your local LAN/WLAN so it is visible to other devices in that LAN/WLAN. For example, does it get its IP address from your internet router and can you ping its address from other devices (say smartphone etc.) in the same network.

How did you allocate an IP address to the Ethernet shield? It must be an address in the same network as the XAMPP server.

Is the Ethernet cable from the arduino shield connected to the Laptop running the XAMPP server or is it connected to your internet router ?

What additional information could you see here: ?

It’s nearly impossible to find knowledgeable folks on this topic, nevertheless, you sound like you know what you’re discussing.
Thanks!

I missed this and it may be a better starting point if you have similar code which works. That would seem to eliminate network problems and point to an error in the code you have written or the way you have defined the new tables. Can you post the code which you say worked from the Arduino.

Did you enter real values here in the code you tried? :

Hi 6v6gt, I am glad you are willing to help me.

This arduino code of Read_KWh_1PH is more complicated than that of test_log_file. Below is the truncated arduino code. I moved the complicated part reading the KWH meter and defined the variables as constants. I tested this on the UNO and it runs and updates the power_delivery table correctly. The TCP/IP values are replaced for security reason but they are ok, so yes I entered real values.

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

#define WRITE_ENABLE           2  // connected to RS485 Enable pins, High = Request (Enable Send data) and Low = Response (Enable read Data)
#define LED_WRITE              7  // indicates request data
#define LED_READ               6  // indicates incoming response !!! do not use pins 13, 12 and 11 when using ethernet, the shield uses these pins as well 
#define LED_ERROR              5  // Indicates an error
#define WAIT_MSEC          60000  // Wait time between 2 different records to the database
#define VALUE_NO_BYTES         4  // the value part of the response
#define REQ_NO_BYTES           8  // Request message to a slave with ModBus, the slave in this case is the SDM120M power meter
#define RESP_NO_BYTES          9  // Response

/*
Hexadc 3FA374BC
Binary 00111111 10100011 01110100 10111100
Sign 0 so positive.
Exponent 0111111 1 = 127 and complemetary is also 127 so exp is 127 - 127 is zero.
Mantissa 1.0100011 01110100 10111100 = 1.2769999504089355
 */
//Voltage {0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB};
// CRC of 0x010400000002 is CB 71 In the register first LO and then HI 71 CB.
//Current {0x01, 0x04, 0x00, 0x06, 0x00, 0x02, 0x91, 0xCA};
// CRC of 0x010400060002 is CA 91 In the register first LO and then HI 91 CA.
//Active Power {0x01, 0x04, 0x00, 0x0C, 0x00, 0x02, 0xB1, 0xC8};
// CRC of 0x0104000C0002 is C8 B1 In the register first LO and then HI B1 C8.
// Frequency {0x01, 0x04, 0x00, 0x46, 0x00, 0x02, 0x90, 0x1E};
// CRC of 0x010400460002 is 1E 90 In the register first LO and then HI 90 1E.
// Total active ennergy {0x01, 0x04, 0x01, 0x56, 0x00, 0x02, 0x90, 0x27};
// CRC of 0x010401560002 is 27 90 In the register first LO and then HI 90 27.

// example request total active power & response Req 0104015600029027 Response 0104043FA374BC2103 1.27 KWh = 1.2769999504089355
// The value is the 4th till the 7th byte of the response 3F A3 74 BC.

byte mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
byte ip[] = {XXX, XXX, X, X }; //Enter the IP of ethernet shield
byte serv[] = {XXX, XXX, X, X} ; //Enter the IPv4 address, of the PC where the PHP pages exists.

float voltage = 240;
float current = 1;
float power = 2.5;
float frequency = 50;
float power_total = 10;
int   slave_id = 1;

EthernetClient eth_client;

void setup() {
  Ethernet.begin(mac, ip);
  pinMode(LED_ERROR, OUTPUT);                // Flashes the number of bytes received < 9.
  Serial.begin(9600);                        // set serial communication baudrate
  delay(100);                                // wait to get the serial port ready.  
//  Serial.setTimeout(2000);

} // end void setup

void loop() 
{
  save_record(slave_id, voltage, current, power, frequency, power_total);
} // end loop

  void save_record(int slave_id, float voltage, float current, float power, float frequency, float power_total)
  {
   if (eth_client.connect(serv, 80)) 
   { //Connecting at the IP address and port we saved before
    Serial.println("connected");
    eth_client.print("GET /ethernet/data_1ph.php?"); //Connecting and Sending values to database
    eth_client.print("slave_id=");
    eth_client.print(slave_id);
    eth_client.print("&voltage=");
    eth_client.print(voltage);
    eth_client.print("&current=");
    eth_client.print(current);
    eth_client.print("&power=");
    eth_client.print(power);
    eth_client.print("&frequency=");
    eth_client.print(frequency);
    eth_client.print("&power_total=");
    eth_client.println(power_total);

    eth_client.stop(); //Closing the connection
   }
   else 
   {
      // if you didn't get a connection to the server:
    Serial.println("connection failed");
    flash_times(LED_ERROR, 250, 15);
   } // end else
  delay(WAIT_MSEC);
}


void flash_times(int pinno, int pulse_wdth, int no_times)
  // pin number "pinno" will flash "no_times" times with a pulse width of "pulse_wdth" in msec
{
  int f;
    for (f=0; f<no_times; f++)
    {
      digitalWrite(pinno,HIGH);
      delay(pulse_wdth);
      digitalWrite(pinno,LOW);
      delay(pulse_wdth);
    }
}


This is one difference. The sketch which fails does not end the transmission with a println() statement.

Another is this flash code which takes several seconds. In the failing code it happens in the middle of a connection session.

Hi 6v6gt great, I changed the print to println and this is working. I assume that println gives the end of line of a string like /0 does.?

I am very happy with that and would never thought that such a difference might cause the error. The only thing what me wondered that there was no warning or error message, but I assume due to missing end of line it might overwrite memory or is there another reason why it went wrong?

Kind regards Kees

By the way in the file access_log I see all entries now updating the table. Unfortunately this wasn't helpful to find the problem.

xxx.xxx.x.x - - [20/Apr/2022:08:14:42 +0200] "GET /ethernet/record_log.php?request=25&response=27" 200 4

I mention this so when other people have similar problems.

It looks like it just needed the terminator which println() sends.
I was going to ask you to produce a log file extract when it all works but you've done so anyway and maybe it does help someone else.

Hi 6v6gt again thanks a lot. Now I can develop my programs further and hopefully I can finalize it soon. I have 2 KWH meters, one 1 phase and one 3 phase, the separate programs works well,now I need to combine them, install the meters in the meter cabinet etc. Kind regards Kees

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.