sensorNET - console code status on the 20th January 2012
I completed the network setup console code. The code posted below includes:
1. Ability to choose DHCP or static.
2. If static, ability to set IP, subnet and gateway addresses.
3. Saves settings to EEPROM so they are available even after power down.
4. DHCP selected out of the box
5. EEPROM space for MAC address and device serial number
6. Configuration done by Serial connection at 115200baud
7. Rock solid with 12V power supply (will reset randomly with USB power only).
Things that I would like to solve with this version:
1. Ability to auto reset to activate changes (currently the user needs to use the reset button).
Next steps:
0. Organize the code in several files, instead of one large one (main, i2c, serial_comms, webclient, webserver).
1. Box the prototype boards (both main console and sensor board prototype)
2. Add screw terminal connections
3. Code i2C implementation in the main console and, at the same time,
5. code i2C code implementation on the client sensor board
code after the break (compiles with Arduino IDE version 1):
#include SPI.h> //add smaller than signal
#include Ethernet.h> //add smaller than signal
#include EEPROM.h> //add smaller than signal
byte ip_static[] = { 0, 0, 0, 0 };
byte mac[] = { 0, 0, 0, 0, 0, 0 };
byte subnet[] = { 0, 0, 0, 0 };
byte gateway[] = { 0, 0, 0, 0 };
int state = 0;
int incomingByte;
int char_count;
char netstring[46];
EthernetServer server(80);
void setup() {
Serial.begin(115200);
//is this the first time running the program?
if (EEPROM.read(2) == 255){
//if so, we need to program the ROM with defaults (basically set DHCP):
EEPROM.write(3, 1);
//and also save the intended MAC address of the console:
EEPROM.write(4, 0x00);
EEPROM.write(5, 0xAA);
EEPROM.write(6, 0xBB);
EEPROM.write(7, 0xCC);
EEPROM.write(8, 0xDE);
EEPROM.write(9, 0x02);
//and also program the device serial number:
EEPROM.write(0, 0); //most significant byte of serial number
EEPROM.write(1, 1); //least significant byte of serial number
//and set address 2 to 0 to indicate this has run before
EEPROM.write(2, 0);
//after the line above there's no way to repeat the code above
//unless we run another program on the avr that initializes EEPROM
//address 2 to 255.
}
//now, load configuration values from EEPROM, and initialize console:
//load saved MAC address
get_mac();
//it's DHCP, ask for network config data:
if (is_dhcp()){
Serial.print("\nDHCP request...");
if (Ethernet.begin(mac) == 0) Serial.println("request failed");
else {
Serial.print("IP: ");
Serial.print(Ethernet.localIP());
Ethernet.begin(mac, Ethernet.localIP());
}
}
//ok, it's not DHCP, it's static:
else {
Serial.print("\nSTATIC ");
get_static_ip();
get_subnet();
get_gateway();
print_static_ip();
print_subnet();
print_gateway();
Ethernet.begin(mac, ip_static, subnet, gateway);
}
server.begin();
}
void loop() {
//listen for incoming Ethernet connections:
//jumps to web_functions.ino
listenForEthernetClients();
//listen for incoming serial connections:
//jumps to serial_functions.ino
if (Serial.available() > 0){
incomingByte = Serial.read();
if (incomingByte == 0x31 && state == 0){
//request network info
if (is_dhcp()){
Serial.print ("\nDHCP ");
Serial.print ("IP: ");
Serial.print (Ethernet.localIP());
}
else {
Serial.print ("\nSTATIC ");
print_static_ip();
print_subnet();
print_gateway();
}
}
else if (incomingByte == 0x32 && state == 0){
//this is a request to set network parameters
char_count = 0;
state = 1;
}
if (state == 1 && char_count <= 46){
//send a long string with format [A=DHCP,B=STATIC]000.000.000.000000.000.000.000
//with 46 chars
netstring[char_count] = incomingByte;
char_count++;
//on the last char received, organize stuff and write to EEPROM:
if (char_count == 47) {
if (netstring[1] == 0x42) EEPROM.write(3,0);//static chosen "B"
else EEPROM.write(3,1);//dhcp
EEPROM.write(10, convert_to_number(netstring[2],netstring[3],netstring[4]));
EEPROM.write(11, convert_to_number(netstring[6],netstring[7],netstring[8]));
EEPROM.write(12, convert_to_number(netstring[10],netstring[11],netstring[12]));
EEPROM.write(13, convert_to_number(netstring[14],netstring[15],netstring[16]));
EEPROM.write(14, convert_to_number(netstring[17],netstring[18],netstring[19]));
EEPROM.write(15, convert_to_number(netstring[21],netstring[22],netstring[23]));
EEPROM.write(16, convert_to_number(netstring[25],netstring[26],netstring[27]));
EEPROM.write(17, convert_to_number(netstring[29],netstring[30],netstring[31]));
EEPROM.write(18, convert_to_number(netstring[32],netstring[33],netstring[34]));
EEPROM.write(19, convert_to_number(netstring[36],netstring[37],netstring[38]));
EEPROM.write(20, convert_to_number(netstring[40],netstring[41],netstring[42]));
EEPROM.write(21, convert_to_number(netstring[44],netstring[45],netstring[46]));
state = 0;
}
}
}
//listen for new sensor connections:
//send sensor data out:
delay(1);
}
byte convert_to_number(byte char1, byte char2, byte char3){
byte value = (char1-0x30)*100 + (char2-0x30)*10 + (char3-0x30);
return value;
}
void get_mac(){
for (int i=0; i<6; i++) mac[i] = EEPROM.read(i+4);
}
void get_static_ip(){
for (int i=0; i<4; i++) ip_static[i] = EEPROM.read(i+10);
}
void print_static_ip(){
Serial.print (" IP: ");
for (int i = 0; i < 4; i++){
Serial.print (ip_static[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void print_subnet(){
Serial.print ("SN: ");
for (int i = 0; i < 4; i++){
Serial.print (subnet[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void print_gateway(){
Serial.print ("GW: ");
for (int i = 0; i < 4; i++){
Serial.print (gateway[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void get_subnet(){
for (int i=0; i<4; i++) subnet[i] = EEPROM.read(i+14);
}
void get_gateway(){
for (int i=0; i<4; i++) gateway[i] = EEPROM.read(i+18);
}
boolean is_dhcp(){
boolean dhcp = true;
if (EEPROM.read(3) == 0) dhcp = false;
return dhcp;
}
/********************************************************************/
//Related to Ethernet connections
/********************************************************************/
void listenForEthernetClients() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("Got a client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// print the current readings, in HTML format:
client.print("Test");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
1. Ability to choose DHCP or static.
2. If static, ability to set IP, subnet and gateway addresses.
3. Saves settings to EEPROM so they are available even after power down.
4. DHCP selected out of the box
5. EEPROM space for MAC address and device serial number
6. Configuration done by Serial connection at 115200baud
7. Rock solid with 12V power supply (will reset randomly with USB power only).
Things that I would like to solve with this version:
1. Ability to auto reset to activate changes (currently the user needs to use the reset button).
Next steps:
0. Organize the code in several files, instead of one large one (main, i2c, serial_comms, webclient, webserver).
1. Box the prototype boards (both main console and sensor board prototype)
2. Add screw terminal connections
3. Code i2C implementation in the main console and, at the same time,
5. code i2C code implementation on the client sensor board
code after the break (compiles with Arduino IDE version 1):
#include SPI.h> //add smaller than signal
#include Ethernet.h> //add smaller than signal
#include EEPROM.h> //add smaller than signal
byte ip_static[] = { 0, 0, 0, 0 };
byte mac[] = { 0, 0, 0, 0, 0, 0 };
byte subnet[] = { 0, 0, 0, 0 };
byte gateway[] = { 0, 0, 0, 0 };
int state = 0;
int incomingByte;
int char_count;
char netstring[46];
EthernetServer server(80);
void setup() {
Serial.begin(115200);
//is this the first time running the program?
if (EEPROM.read(2) == 255){
//if so, we need to program the ROM with defaults (basically set DHCP):
EEPROM.write(3, 1);
//and also save the intended MAC address of the console:
EEPROM.write(4, 0x00);
EEPROM.write(5, 0xAA);
EEPROM.write(6, 0xBB);
EEPROM.write(7, 0xCC);
EEPROM.write(8, 0xDE);
EEPROM.write(9, 0x02);
//and also program the device serial number:
EEPROM.write(0, 0); //most significant byte of serial number
EEPROM.write(1, 1); //least significant byte of serial number
//and set address 2 to 0 to indicate this has run before
EEPROM.write(2, 0);
//after the line above there's no way to repeat the code above
//unless we run another program on the avr that initializes EEPROM
//address 2 to 255.
}
//now, load configuration values from EEPROM, and initialize console:
//load saved MAC address
get_mac();
//it's DHCP, ask for network config data:
if (is_dhcp()){
Serial.print("\nDHCP request...");
if (Ethernet.begin(mac) == 0) Serial.println("request failed");
else {
Serial.print("IP: ");
Serial.print(Ethernet.localIP());
Ethernet.begin(mac, Ethernet.localIP());
}
}
//ok, it's not DHCP, it's static:
else {
Serial.print("\nSTATIC ");
get_static_ip();
get_subnet();
get_gateway();
print_static_ip();
print_subnet();
print_gateway();
Ethernet.begin(mac, ip_static, subnet, gateway);
}
server.begin();
}
void loop() {
//listen for incoming Ethernet connections:
//jumps to web_functions.ino
listenForEthernetClients();
//listen for incoming serial connections:
//jumps to serial_functions.ino
if (Serial.available() > 0){
incomingByte = Serial.read();
if (incomingByte == 0x31 && state == 0){
//request network info
if (is_dhcp()){
Serial.print ("\nDHCP ");
Serial.print ("IP: ");
Serial.print (Ethernet.localIP());
}
else {
Serial.print ("\nSTATIC ");
print_static_ip();
print_subnet();
print_gateway();
}
}
else if (incomingByte == 0x32 && state == 0){
//this is a request to set network parameters
char_count = 0;
state = 1;
}
if (state == 1 && char_count <= 46){
//send a long string with format [A=DHCP,B=STATIC]000.000.000.000000.000.000.000
//with 46 chars
netstring[char_count] = incomingByte;
char_count++;
//on the last char received, organize stuff and write to EEPROM:
if (char_count == 47) {
if (netstring[1] == 0x42) EEPROM.write(3,0);//static chosen "B"
else EEPROM.write(3,1);//dhcp
EEPROM.write(10, convert_to_number(netstring[2],netstring[3],netstring[4]));
EEPROM.write(11, convert_to_number(netstring[6],netstring[7],netstring[8]));
EEPROM.write(12, convert_to_number(netstring[10],netstring[11],netstring[12]));
EEPROM.write(13, convert_to_number(netstring[14],netstring[15],netstring[16]));
EEPROM.write(14, convert_to_number(netstring[17],netstring[18],netstring[19]));
EEPROM.write(15, convert_to_number(netstring[21],netstring[22],netstring[23]));
EEPROM.write(16, convert_to_number(netstring[25],netstring[26],netstring[27]));
EEPROM.write(17, convert_to_number(netstring[29],netstring[30],netstring[31]));
EEPROM.write(18, convert_to_number(netstring[32],netstring[33],netstring[34]));
EEPROM.write(19, convert_to_number(netstring[36],netstring[37],netstring[38]));
EEPROM.write(20, convert_to_number(netstring[40],netstring[41],netstring[42]));
EEPROM.write(21, convert_to_number(netstring[44],netstring[45],netstring[46]));
state = 0;
}
}
}
//listen for new sensor connections:
//send sensor data out:
delay(1);
}
byte convert_to_number(byte char1, byte char2, byte char3){
byte value = (char1-0x30)*100 + (char2-0x30)*10 + (char3-0x30);
return value;
}
void get_mac(){
for (int i=0; i<6; i++) mac[i] = EEPROM.read(i+4);
}
void get_static_ip(){
for (int i=0; i<4; i++) ip_static[i] = EEPROM.read(i+10);
}
void print_static_ip(){
Serial.print (" IP: ");
for (int i = 0; i < 4; i++){
Serial.print (ip_static[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void print_subnet(){
Serial.print ("SN: ");
for (int i = 0; i < 4; i++){
Serial.print (subnet[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void print_gateway(){
Serial.print ("GW: ");
for (int i = 0; i < 4; i++){
Serial.print (gateway[i]);
if (i != 3) Serial.print (".");
else Serial.print (" ");
}
}
void get_subnet(){
for (int i=0; i<4; i++) subnet[i] = EEPROM.read(i+14);
}
void get_gateway(){
for (int i=0; i<4; i++) gateway[i] = EEPROM.read(i+18);
}
boolean is_dhcp(){
boolean dhcp = true;
if (EEPROM.read(3) == 0) dhcp = false;
return dhcp;
}
/********************************************************************/
//Related to Ethernet connections
/********************************************************************/
void listenForEthernetClients() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("Got a client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// print the current readings, in HTML format:
client.print("Test");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
Comments