Wednesday, September 19, 2012
Just received a W5100 Ethershield
Look what just arrived in the post.
Christmas last I got a ENC28J60 Ethernet socket and I've been playing with that a bit thinking that doing Ethernet with Arduino is just plain hard.
A few people recommended I get a W5100 based board so I could use the official Ethernet library. When I had a look at the difference between the code it was clear the W5100 based boards are so much easier to code for as the library is more robust and easier to use.
So, I bought one on Ebay from China for about £7.50-inc postage so a big difference to the £30 for the official shield. The ENC28J60 boards are still cheaper at about £5.00 but the difference is so small now that I have a felling the W5100 boards are now a good low cost option.
Now I have to modify my web server controlled Arduino code tonight to work with the shield. All the fun.
NOTE: Image links to UK Ebay listing I used. Delivered in about 3 weeks. Packed in a Jiffy Bag.
Tuesday, September 18, 2012
Controlling multiple Arduinos from a webserver with the details stored in a mySQL database using ENC28J60 network adaptor
See previous post for original details and code for the Arduino.
Following the last tinkering session I finally got a chance to look at the webserver side.
On my XAMPP install I enabled mySQL
Created a Database - arduinolist
Created 2 tables - alist (list of the Arduinos) and apin (pins used on each Arduino)
Used mySqlAdmin to enter some data to test it
Code to create the Arduino List Table
CREATE TABLE IF NOT EXISTS `alist` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Arduino` varchar(17) NOT NULL,
`Active` int(11) NOT NULL,
`aname` varchar(200) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Arduino` varchar(17) NOT NULL,
`Active` int(11) NOT NULL,
`aname` varchar(200) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
INSERT INTO `alist` (`ID`, `Arduino`, `Active`, `aname`) VALUES
(1, '192.168.1.205', 1, '1st Arduino'),
(2, '192.158.1.205', 1, '2nd Arduino');
(1, '192.168.1.205', 1, '1st Arduino'),
(2, '192.158.1.205', 1, '2nd Arduino');
Code to create the table for the pins used per Arduino
CREATE TABLE IF NOT EXISTS `apin` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`pinName` varchar(200) NOT NULL,
`alistID` int(11) NOT NULL,
`pin` int(11) NOT NULL,
`active` int(11) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
Code to enter the details for the 2 pins I am using
INSERT INTO `apin` (`ID`, `pinName`, `alistID`, `pin`, `active`) VALUES
(1, 'Pin 2', 1, 2, 1),
(2, 'Pin 4', 1, 4, 1)
(3, 'Pin 4 on Arduino 2', 2, 4, 1);
From above this structure means you can add as many Arduinos as you spare IP addresses
It also means you can add as many pins as there are available on your Arduino
Once I added all the data I now had he data in place for the Arduino and the pins I have LEDs on.
Then it was a matter of doing the PHP code. This is when I discovered my PHP is very rusty. So, it took a while to get this sorted.
In the end I got there and now the PHP code on the server will list all the Arduinos and then the pins on each Arduino. As I only have 1 Arduino/ENC28J60 I added a 2nd entry for the same Arduino with a different name and added one of the pins again.and gave it a different name.
Since the code references the Arduino by it's ID record in the database rather than the IP address this was a successful test of whether the code would support multiple Arduinos with multiple pins on each.
If you are interested then below is the revised PHP code for the real webserver.
This is real nasty ugly code so there will be a lot of places where it can be improved which is my next task.
Winlkeink
September 2012
For feedback, comments and questions go to winkleink.blogspot.com
This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pins on Arduinos
using a web server as the interface.
The web page is served from a database where you list your Arduinos and the pins used.
With the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not displayed on the webpage and also the
commands to control the Arduino is not shown publicly.
When compared to using the Arduino as the web server itself and using a GET REQUEST.
By doing it this way you have more control over the Arduino and the web interface.
This version is VERY rough with horrible colours.
NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.
-->
<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php
// START CONNECT TO DATABASE
$database = "ArduinoList";
$username = "root";
$password = "";
IF ($LinkID = mysql_connect('localhost', $username, $password))
{
//print ('mySQL Connected<BR>');
}
else
{
//print ("mySQL NOT Connected<BR>");
//echo mysql_error();
//echo "<P>";
}
//Select the Database
IF (mysql_select_db($database))
{
#print ('Selected Database<BR>');
}
else
{
# print ("Failed to Select Database<BR>");
# echo mysql_error();
echo "<P>";
}
// END CONNECT TO DATABASE
//
// Start check for button presses
//
// Get the list of Arduinos
$querya = "SELECT ID, Arduino, aname FROM alist WHERE Active=1 ORDER BY ID DESC";
IF ($resulta = mysql_query($querya))
{
# The Query was successful
$column_counta = mysql_num_rows($resulta);
// echo "column_counta is $column_counta";
IF ($column_counta != 0 )
{
for ($column_numa = 0;
$column_numa < $column_counta;
$column_numa++)
{
$result_arra = mysql_fetch_array($resulta);
$AID = $result_arra['ID'];
$Arduino = $result_arra['Arduino'];
?>
<?php
// Check if this Arduino is the one where a button was pressed. If it is use it
if (isset($_POST["AID"]) == $AID)
{
?>
<?php
//
// If Arduino is the correct one then check the pins to see which one was selected
//
// Get a list of all the pins being used on this Arduino
$queryb = "SELECT ID, alistID, pin FROM apin WHERE alistID=$AID AND Active=1 ORDER BY pin DESC";
IF ($resultb = mysql_query($queryb))
{
# The Query was successful
$column_countb = mysql_num_rows($resultb);
IF ($column_countb != 0 )
{
for ($column_numb = 0;
$column_numb < $column_countb;
$column_numb++)
{
$result_arrb = mysql_fetch_array($resultb);
$pinID = $result_arrb['ID'];
$pin = $result_arrb['pin'];
?>
<?php
// Check if a PIN has been actioned
if (isset($_POST["LED".$pin]) == "ON")
{
if ($_POST["LED".$pin] == "ON")
{
// Set ON by calling the Arduino using fopen
$h = @fopen("http://192.168.1.205/?LED".$pin."=ON", "rb");
}
else if ($_POST["LED".$pin] == "OFF")
{
// Set OFF by calling the Arduino using fopen
$h = @fopen("http://192.168.1.205/?LED".$pin."=OFF", "rb");
}
}
?>
<?php
}
}
}
?>
<?php
// END Check if an Arduino is Selected
}
?>
<?php
}
}
}
?>
<?php
?>
<!-- LED2 FORM -->
<!-- <table> -->
<?php
// Get the list of Arduinos
$querya = "SELECT ID, Arduino, aname FROM alist WHERE Active=1 ORDER BY ID DESC";
IF ($resulta = mysql_query($querya))
{
# The Query was successful
$column_counta = mysql_num_rows($resulta);
// echo "column_counta is $column_counta";
IF ($column_counta != 0 )
{
for ($column_numa = 0;
$column_numa < $column_counta;
$column_numa++)
{
$result_arra = mysql_fetch_array($resulta);
$AID = $result_arra['ID'];
$Arduino = $result_arra['Arduino'];
$aname = $result_arra['aname'];
?>
<table>
<tr><td colspan="2"><b>
<?php echo "$aname";?>
</b></td></tr>
<?php
$queryb = "SELECT ID, pinName, alistID, pin FROM apin WHERE alistID=$AID AND Active=1 ORDER BY ID DESC";
IF ($resultb = mysql_query($queryb))
{
# The Query was successful
$column_countb = mysql_num_rows($resultb);
IF ($column_countb != 0 )
{
for ($column_numb = 0;
$column_numb < $column_countb;
$column_numb++)
{
$result_arrb = mysql_fetch_array($resultb);
$pinID = $result_arrb['ID'];
$pinName = $result_arrb['pinName'];
$pin = $result_arrb['pin'];
?>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off <?php echo $pinName;?><!!!!/font></H4></td></tr>
<tr><td>
<form action="led2_sql.php" method="post">
<input type="hidden" name="AID" value="<?php echo$AID;?>">
<input type="hidden" name="LED<?php echo $pin;?>" value="ON">
<input type="submit" name="submit" value="ON!!">
</form>
</td><td>
<form action="led2_sql.php" method="post">
<input type="hidden" name="AID" value="<?php echo$AID;?>">
<input type="hidden" name="LED<?php echo $pin;?>" value="OFF">
<input type="submit" name="submit" value="OFF!!">
</form>
</td></tr>
<?php
}
}
}
?>
</table>
<?php
}
}
}
?>
</body>
</html>
Saturday, August 25, 2012
Arduino, Ethernet, Ethercard, XAMPP web server, PHP web page controlling 2 LEDs
[UPDATE 17 Sept 2012 - I have modified the XAMPP webserver code get the details for the Arduino(s) from a database. See the updated version here
I tinkered a while back with using a web server to control and Arduino over a serial connection and then I got an ENC28J60. A really cheap Ethernet socket that can work with the Arduino. It uses the Ethercard community provided library.
My goal was to find a way to turn on and off LEDs which can later become Servos once I've done the hard coding from a web server that then connects to the Arduino over Ethernet.
Using this method the web server and the Arduino don't have to be near each other and even more importantly they don't need to be physically connected.
After a bit of research and trial and error I have something working.
This example presents a simple PHP based web page on the web server with the options to turn on or off 2 LEDs. (sorry for the gaudy colours in the video I thought it would be good to match the LED colours with the menus.
When you click a button on the web page it calls itself with a POST variable set.
The PHP page then interprets this and does an fopen() to the Arduino to do the requested action.
By doing an fopen() the actual connection to the Arduino is not shown on the web page.
The fun with this is that it could be expanded to control more pins easily and also control more than 1 Arduino.
PHP Code on the Server
<!--
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com
This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pin2 and Pin4 on
the Arduino using a web server as the interface.
The web page is served with the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not needed and also the commands to control the Arduino is not
shown publicly when compared to using the Arduino as the web server itself and using a GET REQUEST.
By doing it this way you have more control over the Arduino and the web interface.
NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.
-->
<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php
// Check of LED2 is set. If it is use it
if (isset($_POST["LED2"]))
{
$LED2= $_POST["LED2"];
//echo "<b>$LED2</b>";
}
else
{
$LED2 ="";
}
if ($LED2 == "ON")
{
// Set led2 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED2=ON", "rb");
}
else if ($LED2 == "OFF")
{
// Set led2 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED2=OFF", "rb");
}
// Check of LED4 is set. If it is use it
if (isset($_POST["LED4"]))
{
$LED4= $_POST["LED4"];
//echo "<b>LED4 is $LED4</b>";
}
else
{
$LED4 ="";
}
if ($LED4 == "ON")
{
// Set led4 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED4=ON", "rb");
}
else if ($LED4 == "OFF")
{
// Set led4 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED4=OFF", "rb");
}
?>
<!-- LED2 FORM -->
<table>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off the LED2</font></H4></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>
<table>
<tr><td colspan="2"><font size="4" color="green">Turn on and off the LED4</font></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>
</body>
</html>
I tinkered a while back with using a web server to control and Arduino over a serial connection and then I got an ENC28J60. A really cheap Ethernet socket that can work with the Arduino. It uses the Ethercard community provided library.
My goal was to find a way to turn on and off LEDs which can later become Servos once I've done the hard coding from a web server that then connects to the Arduino over Ethernet.
Using this method the web server and the Arduino don't have to be near each other and even more importantly they don't need to be physically connected.
After a bit of research and trial and error I have something working.
This example presents a simple PHP based web page on the web server with the options to turn on or off 2 LEDs. (sorry for the gaudy colours in the video I thought it would be good to match the LED colours with the menus.
When you click a button on the web page it calls itself with a POST variable set.
The PHP page then interprets this and does an fopen() to the Arduino to do the requested action.
By doing an fopen() the actual connection to the Arduino is not shown on the web page.
The fun with this is that it could be expanded to control more pins easily and also control more than 1 Arduino.
PHP Code on the Server
<!--
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com
This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pin2 and Pin4 on
the Arduino using a web server as the interface.
The web page is served with the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not needed and also the commands to control the Arduino is not
shown publicly when compared to using the Arduino as the web server itself and using a GET REQUEST.
By doing it this way you have more control over the Arduino and the web interface.
NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.
-->
<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php
// Check of LED2 is set. If it is use it
if (isset($_POST["LED2"]))
{
$LED2= $_POST["LED2"];
//echo "<b>$LED2</b>";
}
else
{
$LED2 ="";
}
if ($LED2 == "ON")
{
// Set led2 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED2=ON", "rb");
}
else if ($LED2 == "OFF")
{
// Set led2 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED2=OFF", "rb");
}
// Check of LED4 is set. If it is use it
if (isset($_POST["LED4"]))
{
$LED4= $_POST["LED4"];
//echo "<b>LED4 is $LED4</b>";
}
else
{
$LED4 ="";
}
if ($LED4 == "ON")
{
// Set led4 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED4=ON", "rb");
}
else if ($LED4 == "OFF")
{
// Set led4 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED4=OFF", "rb");
}
?>
<!-- LED2 FORM -->
<table>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off the LED2</font></H4></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>
<table>
<tr><td colspan="2"><font size="4" color="green">Turn on and off the LED4</font></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>
</body>
</html>
Arduino code
/*
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com
Script to allow the controling on the Arduino over Ethernet using an ENC28J60 Ethernet socket and the Ethercard library
Assigning Static IP for the Arduino so I can know exactly which Arduino I am controlling
For this example the request is either http://192.168.1.5/?LED2=ON or http://192.168.1.5/?LED2=OFF
These can be called directly but then the Arduino would have to be the web server and present back the web page
with the option to turn the LED off or ON
For this example I am controlling the Arduino from a webserver on my PC (XAMP) using a PHP script.
*/
// I took took inspiration from the following 2 examples
// The BackSoon example provided with the EtherCard library
// Present a "Will be back soon web page", as stand-in webserver.
// 2011-01-30 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php
// Example from the Internet
// https://github.com/lucadentella/enc28j60_tutorial/blob/master/_5_BasicServer/_5_BasicServer.ino
#include <EtherCard.h>
// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = { 192,168,1,5 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };
byte Ethernet::buffer[500]; // tcp/ip send and receive buffer
// Using a Variable for the Pin, but it is not necessary
const int ledPin2 = 2;
const int ledPin4 = 4;
// Some stuff for responding to the request
char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;
// Small web page to return so the request is completed
char page[] PROGMEM =
"HTTP/1.0 503 Service Unavailable\r\n"
"Content-Type: text/html\r\n"
"Retry-After: 600\r\n"
"\r\n"
"<html>"
"<head><title>"
"Arduino 192.168.1.5"
"</title></head>"
"<body>"
"<h3>Arduino 192.168.1.5</h3>"
"</body>"
"</html>"
;
void setup(){
// Set Pin2 to be an Output
pinMode(ledPin2, OUTPUT);
// Set Pin4 to be an Output
pinMode(ledPin4, OUTPUT);
// Scary complex intializing of the EtherCard - I don't understand this stuff (yet0
ether.begin(sizeof Ethernet::buffer, mymac);
// Set IP using Static
ether.staticSetup(myip, gwip);
}
void loop(){
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
// IF LED2=ON turn it ON
if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=ON") != 0) {
Serial.println("Received ON command");
digitalWrite(ledPin2, HIGH);
}
// IF LED2=OFF turn it OFF
if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=OFF") != 0) {
Serial.println("Received OFF command");
digitalWrite(ledPin2, LOW);
}
// IF LED4=ON turn it ON
if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=ON") != 0) {
Serial.println("Received ON command");
digitalWrite(ledPin4, HIGH);
}
// IF LED4=OFF turn it OFF
if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=OFF") != 0) {
Serial.println("Received OFF command");
digitalWrite(ledPin4, LOW);
}
//Return a page so the request is completed.
memcpy_P(ether.tcpOffset(), page, sizeof page);
ether.httpServerReply(sizeof page - 1);
}
If you want more details on using the ENC28J60 check out my previous post on it. It gives details on wiring and various libraries for it.
Subscribe to:
Posts (Atom)
