372 lines
9.9 KiB
C++
372 lines
9.9 KiB
C++
/* ******************************************** *
|
|
* Project: Web Controller *
|
|
* Platform: Arduino Mighty 1284p - Breadboard *
|
|
* ------------------------------------------- *
|
|
* Creation: 28.09.2015 - Paolo Iocco *
|
|
* ******************************************** *
|
|
*
|
|
* Circuit diagram
|
|
* ---------------
|
|
*
|
|
* +---\/---+
|
|
* LED (D 0) PB0 1| |40 PA0 (A 0 / D24)
|
|
* (D 1) PB1 2| |39 PA1 (A 1 / D25)
|
|
* INT2 (D 2) PB2 3| |38 PA2 (A 2 / D26)
|
|
* PWM (D 3) PB3 4| |37 PA3 (A 3 / D27)
|
|
* PWM /SS (D 4) PB4 5| |36 PA4 (A 4 / D28)
|
|
* MOSI (D 5) PB5 6| |35 PA5 (A 5 / D29)
|
|
* PWM MISO (D 6) PB6 7| |34 PA6 (A 6 / D30)
|
|
* PWM SCK (D 7) PB7 8| |33 PA7 (A 7 / D31)
|
|
* RST 9| |32 AREF
|
|
* VCC 10| |31 GND
|
|
* GND 11| |30 AVCC
|
|
* XTAL2 12| |29 PC7 (D 23)
|
|
* XTAL1 13| |28 PC6 (D 22)
|
|
* RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI
|
|
* TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO
|
|
*(RX1)/INT0 (D 10) PD2 16| |25 PC3 (D 19) TMS
|
|
*(TX1)/INT1 (D 11) PD3 17| |24 PC2 (D 18) TCK
|
|
* PWM (D 12) PD4 18| |23 PC1 (D 17) SDA
|
|
* PWM (D 13) PD5 19| |22 PC0 (D 16) SCL
|
|
* PWM (D 14) PD6 20| |21 PD7 (D 15) PWM
|
|
* +--------+
|
|
*
|
|
* ***************************************** *
|
|
|
|
/* TFT PIN Connections (using Arduino Mighty):
|
|
* JP1:
|
|
* SD0(MISO) - Mighty pin D6
|
|
* LED - 68 Ohm to VCC
|
|
* SCK - Mighty pin D7
|
|
* SDI(MOSI) - Mighty pin D5
|
|
* D/C - Mighty pin D12
|
|
* RESET - Mighty pin D14
|
|
* CS - Mighty pin D15
|
|
* GND - GND
|
|
* VCC - 3.3V
|
|
* JP2:
|
|
* SCK - Mighty pin D7
|
|
* MISO - Mighty pin D6
|
|
* MOSI - Mighty pin D5
|
|
* CS - Mighty pin D19
|
|
*
|
|
*
|
|
* Ethernet PIN Connections (using Arduino Mighty):
|
|
* JP1:
|
|
* VCC - 3.3V
|
|
* GND - GND
|
|
* RST - Pin D2
|
|
* SCK - Pin D7
|
|
* SO - Pin D6
|
|
* SI - Pin D5
|
|
* CS - Pin D18
|
|
* the Chip ist 5v Tolerant *
|
|
*
|
|
* RAM Connections
|
|
*
|
|
*/
|
|
|
|
#include <SPI.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <TFT_ILI9340.h>
|
|
#include <EtherCard.h>
|
|
#include <Servo.h>
|
|
#include <SD.h>
|
|
|
|
// HW-PIN definitions
|
|
#define ETH_CS 1
|
|
#define ETH_RES 2
|
|
#define TFT_DC 12
|
|
#define TFT_RST 14
|
|
#define TFT_CS 15
|
|
#define SD_CS 16
|
|
#define OUT_1 21
|
|
#define OUT_2 22
|
|
#define PWM_1 3
|
|
#define SERVO_1 23
|
|
|
|
// TFT Color definitions
|
|
#define BLACK 0x0000
|
|
#define BLUE 0x001F
|
|
#define RED 0xF800
|
|
#define GREEN 0x07E0
|
|
#define CYAN 0x07FF
|
|
#define MAGENTA 0xF81F
|
|
#define YELLOW 0xFFE0
|
|
#define WHITE 0xFFFF
|
|
#define GREY 0x7BEF
|
|
|
|
// TFT variables and parameters
|
|
TFT_ILI9340 tft = TFT_ILI9340(TFT_CS, TFT_DC, TFT_RST);
|
|
|
|
// I/O variables and parameters
|
|
Servo myservo;
|
|
|
|
// SD variables and parameters
|
|
// SD in SD.h
|
|
bool SD_OK;
|
|
File myFile;
|
|
|
|
// ETH variables and parameters
|
|
// EtherCard ether; // in EtherCard.h
|
|
#define STATIC 0 // 0: DHCP, 1: Static
|
|
#if STATIC
|
|
static byte myip[] = { 192,168,2,150 }; // ethernet interface ip address
|
|
static byte gwip[] = { 192,168,2,1 }; // gateway ip address
|
|
#endif
|
|
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // ethernet mac address - must be unique on your network
|
|
byte Ethernet::buffer[1500]; // tcp/ip send and receive buffer
|
|
BufferFiller bfill;
|
|
word len, pos;
|
|
|
|
|
|
/* ******************** *
|
|
* Function definitions *
|
|
* ******************** */
|
|
void Intro() {
|
|
tft.fillScreen();
|
|
tft.setCursor(0, 0);
|
|
tft.setTextColor(YELLOW);
|
|
tft.setTextSize(2);
|
|
tft.println("** Love Silvia **");
|
|
tft.setTextSize(1);
|
|
}
|
|
|
|
void PrintIP(const uint8_t *buf){
|
|
for (uint8_t i = 0; i < 4; ++i) {
|
|
tft.print( buf[i], DEC );
|
|
if (i < 3)
|
|
tft.print('.');
|
|
}
|
|
}
|
|
|
|
void TFT_Init(){
|
|
// init TFT
|
|
tft.begin();
|
|
tft.setRotation(3);
|
|
Intro();
|
|
}
|
|
|
|
void SD_Init(){
|
|
// init SD-Card
|
|
SD_OK=false;
|
|
tft.setTextColor(GREY);
|
|
tft.print("\nInitializing SD card... ");
|
|
if (!SD.begin(SD_CS)) {
|
|
tft.setTextColor(RED);
|
|
tft.println("[ERROR]");
|
|
return;
|
|
}
|
|
tft.setTextColor(GREEN);
|
|
tft.println("[OK]");
|
|
tft.setTextColor(GREY);
|
|
SD_OK=true;
|
|
}
|
|
|
|
void ETH_Reset(){
|
|
pinMode(ETH_RES, OUTPUT);
|
|
digitalWrite(ETH_RES,LOW);
|
|
delay(1);
|
|
digitalWrite(ETH_RES,HIGH);
|
|
}
|
|
|
|
void ETH_Init(){
|
|
// init Ethernet
|
|
ETH_Reset();
|
|
tft.setTextColor(GREY);
|
|
tft.print("Initializing Ethernet... ");
|
|
if (ether.begin(sizeof Ethernet::buffer, mymac, ETH_CS) == 0){
|
|
tft.setTextColor(RED);
|
|
tft.println( "[ERROR]");
|
|
return;
|
|
}
|
|
tft.setTextColor(GREEN);
|
|
tft.println( "[OK]");
|
|
#if STATIC
|
|
ether.staticSetup(myip, gwip);
|
|
#else
|
|
if (!ether.dhcpSetup()){
|
|
tft.setTextColor(RED);
|
|
tft.println(" DHCP failed");
|
|
}
|
|
#endif
|
|
tft.setTextColor(GREY);
|
|
tft.print(" IP: ");
|
|
tft.setTextColor(WHITE);
|
|
PrintIP(ether.myip);
|
|
tft.setTextColor(GREY);
|
|
tft.print("\n GW: ");
|
|
tft.setTextColor(WHITE);
|
|
PrintIP(ether.gwip);
|
|
tft.setTextColor(GREY);
|
|
tft.print("\n DNS: ");
|
|
tft.setTextColor(WHITE);
|
|
PrintIP(ether.dnsip);
|
|
tft.println("\n");
|
|
}
|
|
|
|
void Servo_Init(){
|
|
// init Servo
|
|
myservo.attach(SERVO_1);
|
|
myservo.write(90);
|
|
}
|
|
|
|
void IO_Init(){
|
|
// init I/O
|
|
pinMode(OUT_1, OUTPUT);
|
|
pinMode(OUT_2, OUTPUT);
|
|
pinMode(PWM_1, OUTPUT);
|
|
}
|
|
|
|
static int getIntArg(const char* data, const char* key, int value =-1) {
|
|
char temp[10];
|
|
if (ether.findKeyVal(data + 7, temp, sizeof temp, key) > 0)
|
|
value = atoi(temp);
|
|
return value;
|
|
}
|
|
|
|
static void homePage(const char* data, BufferFiller& buf) {
|
|
byte degree=90, check1=0, check2=0;
|
|
if (data[6] == '?') { // pick up submitted data, if present
|
|
check1 = getIntArg(data, "c1",0);
|
|
degree = getIntArg(data, "d");
|
|
check2 = getIntArg(data, "c2",0);
|
|
if (20 <= degree && degree <= 170) {
|
|
//servo set angle or/and led set luminosity
|
|
analogWrite(PWM_1,degree);
|
|
myservo.write(degree);
|
|
}
|
|
digitalWrite(OUT_1, check1);
|
|
digitalWrite(OUT_2, check2);
|
|
}
|
|
long t = millis() / 1000;
|
|
word h = t / 3600;
|
|
byte m = (t / 60) % 60;
|
|
byte s = t % 60;
|
|
buf.emit_p(PSTR(
|
|
"HTTP/1.0 200 OK\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Pragma: no-cache\r\n"
|
|
"\r\n"
|
|
"<meta http-equiv='refresh' content='100'/>"
|
|
"<html>"
|
|
"<head><title>"
|
|
"Pulce Web Server"
|
|
"</title></head>"
|
|
"<body>"
|
|
"<h2>Pulce Web Server</h2>"
|
|
"<p><em>"
|
|
"The main server is currently off-line.<br/>"
|
|
"Please try again later.</em></p>"
|
|
"<form>"
|
|
"<pre>"
|
|
" Out1: <input type=checkbox name=c1 value='1' $S> Input: <input type=text name=t size=20><br>"
|
|
" Out2: <input type=checkbox name=c2 value='1' $S> Degrees: <input type=text name=d value='$D' size=3><br>"
|
|
" <input type=submit value=Send>"
|
|
"</pre>"
|
|
"</form>"
|
|
"<h4>$D$D:$D$D:$D$D</h4>"
|
|
"</body>"
|
|
"</html>"),
|
|
check1 ? "CHECKED" : "",
|
|
check2 ? "CHECKED" : "",
|
|
degree,
|
|
h/10, h%10, m/10, m%10, s/10, s%10);
|
|
return;
|
|
/*
|
|
* uint16_t ddd = 123;
|
|
* double ttt = 1.23;
|
|
* uint16_t hhh = 0xa4;
|
|
* long lll = 123456789;
|
|
* char * sss;
|
|
* char fff[] PROGMEM = "MyMemory";
|
|
* sss[0] = 'G';
|
|
* sss[1] = 'P';
|
|
* sss[2] = 'L';
|
|
* sss[3] = 0;
|
|
* buf.emit_p( PSTR("ddd=$D\n"), ddd ); // "ddd=123\n"
|
|
* buf.emit_p( PSTR("ttt=$T\n"), ttt ); // "ttt=1.23\n" **TO CHECK**
|
|
* buf.emit_p( PSTR("hhh=$H\n"), hhh ); // "hhh=a4\n"
|
|
* buf.emit_p( PSTR("lll=$L\n"), lll ); // "lll=123456789\n"
|
|
* buf.emit_p( PSTR("sss=$S\n"), sss ); // "sss=GPL\n"
|
|
* buf.emit_p( PSTR("fff=$F\n"), fff ); // "fff=MyMemory\n"
|
|
*/
|
|
}
|
|
|
|
void SD_Read(){
|
|
if (SD_OK) {
|
|
myFile = SD.open("test.txt");
|
|
if (myFile) {
|
|
while (myFile.available()) {
|
|
tft.write(myFile.read());
|
|
}
|
|
myFile.close();
|
|
} else {
|
|
tft.println("error opening test.txt");
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************** *
|
|
* Arduino Setup *
|
|
* ******************** */
|
|
void setup(){
|
|
TFT_Init(); // init TFT
|
|
SD_Init(); // init SD-Card
|
|
ETH_Init(); // init Ethernet
|
|
Servo_Init(); // init Servo
|
|
IO_Init(); // init I/O
|
|
|
|
SD_Read(); // reads the firmware file and send the Output to TFT
|
|
}
|
|
|
|
/* ******************** *
|
|
* Arduino Loop *
|
|
* ******************** */
|
|
void loop () {
|
|
len = ether.packetReceive();
|
|
pos = ether.packetLoop(len);
|
|
// check if valid tcp data is received
|
|
if (pos) {
|
|
bfill = ether.tcpOffset();
|
|
char* data = (char *) Ethernet::buffer + pos -1;
|
|
tft.setTextColor(MAGENTA);
|
|
//tft.println(data); // prints the complete buffer
|
|
homePage(data, bfill); // send web page data
|
|
ether.httpServerReply(bfill.position()); // send web page data
|
|
}
|
|
}
|
|
/* Intel HEX Format
|
|
|
|
:llaaaatt[dd...]cc
|
|
|
|
|
|
Each group of letters corresponds to a different field, and each letter represents a single hexadecimal digit. Each field is composed of at least two hexadecimal digits-which make up a byte-as described below:
|
|
: is the colon that starts every Intel HEX record.
|
|
ll is the record-length field that represents the number of data bytes (dd) in the record.
|
|
aaaa is the address field that represents the starting address for subsequent data in the record.
|
|
tt is the field that represents the HEX record type, which may be one of the following:
|
|
00 - data record
|
|
01 - end-of-file record
|
|
02 - extended segment address record
|
|
04 - extended linear address record
|
|
05 - start linear address record (MDK-ARM only)
|
|
dd is a data field that represents one byte of data. A record may have multiple data bytes. The number of data bytes in the record must match the number specified by the ll field.
|
|
cc is the checksum field that represents the checksum of the record. The checksum is calculated by summing the values of all hexadecimal digit pairs in the record modulo 256 and taking the two's complement.
|
|
|
|
Data Records
|
|
|
|
The Intel HEX file is made up of any number of data records that are terminated with a carriage return and a linefeed. Data records appear as follows:
|
|
:10246200464C5549442050524F46494C4500464C33
|
|
|
|
|
|
This record is decoded as follows:
|
|
:10246200464C5549442050524F46494C4500464C33
|
|
||||||||||| CC->Checksum
|
|
|||||||||DD->Data
|
|
|||||||TT->Record Type
|
|
|||AAAA->Address
|
|
|LL->Record Length
|
|
:->Colon
|
|
*/
|