diff --git a/AAA b/AAA new file mode 100644 index 0000000..71d8711 --- /dev/null +++ b/AAA @@ -0,0 +1,21 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code code code codecodecodecodecodecodecodecodecodecodecodecode is in the public domain. + */ +int LEDPIN = 13; + +void setup() { + //Serial.begin(9600); + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(LEDPIN, OUTPUT); +} + +void loop() { + digitalWrite(LEDPIN, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(LEDPIN, LOW); // set the LED off + delay(1000); // wait for a second +} \ No newline at end of file diff --git a/AVR_Programmer/AVR_Programmer.pde b/AVR_Programmer/AVR_Programmer.pde new file mode 100644 index 0000000..7057781 --- /dev/null +++ b/AVR_Programmer/AVR_Programmer.pde @@ -0,0 +1,286 @@ +#define PAGESIZE 32 // in (2-byte) words + // set to 32 for atmega8 + // set to 64 for atmega168 + + +#define LED 13 + +#define RESET 2 +#define SCK 3 +#define MISO 4 +#define MOSI 5 + +#define CTS 6 + +typedef unsigned char byte; // 8 bit +typedef unsigned int word; // 16 bit +typedef unsigned long dword; // 32 bit + +dword spibits(int n, byte output); +dword spidword(dword output); +word spiword(word output); +byte spibyte(byte output); +void printhex(byte x); +void printbits(byte x); +void waitforinput(void); +char readchar(void); +byte readnibble(void); +byte readbyte(void); +word readword(void); +void skipline(void); + + +void setup() +{ + pinMode(RESET, OUTPUT); + pinMode(SCK, OUTPUT); + pinMode(MISO, INPUT); + pinMode(MOSI, OUTPUT); + pinMode(CTS, OUTPUT); + + digitalWrite(CTS, HIGH); // signal NOT clear to send to PC + Serial.begin(9600); + Serial.println(); + Serial.println(); + Serial.println("pesco's atmel-programming arduino, (c) 2009"); + Serial.flush(); +} + + +void loop() +{ + byte echo; + + // give RESET a high pulse + Serial.println(); + Serial.println("reset pulse."); + digitalWrite(RESET, HIGH); + delay(50); + digitalWrite(RESET, LOW); + + // give chip time to init + delay(50); + + // enter programming mode + Serial.print("initiate programming: "); + echo = (spidword(0xAC530000) & 0xFF00) >> 8; + + if(echo == 0x53) { + byte sig[3]; + byte lock; + word fuse; + + Serial.println("slave confirms."); + + // read signature byte + Serial.print("reading signature bytes: 0x"); + sig[0] = spidword(0x30000000) & 0xFF; + printhex(sig[0]); + sig[1] = spidword(0x30000100) & 0xFF; + printhex(sig[1]); + sig[2] = spidword(0x30000200) & 0xFF; + printhex(sig[2]); + Serial.println(); + + // read lock bits + Serial.print("reading lock bits: "); + lock = spidword(0x58000000) & 0x3F; + printbits(lock); + Serial.println(); + + // read fuse bits + Serial.print("reading fuse bits: "); + fuse = (spidword(0x58080000) & 0xFF) << 8; // high byte + printbits(fuse >> 8); + fuse |= spidword(0x50000000) & 0xFF; // low byte + printbits(fuse & 0xFF); + Serial.println(); + + // wait for firmware image on serial + Serial.print("awaiting hex file..."); + waitforinput(); + Serial.println(" incoming..."); + + // perform chip erase + Serial.println("chip erase."); + spidword(0xAC800000); + delay(10); // WD_ERASE + + // write anything that comes over serial into program mem + Serial.print("writing to flash memory: (pagesize "); + Serial.print(PAGESIZE); + Serial.println(" words)"); + word addr=0; + byte hi=0; + boolean done=false; + word count=0; + while(!done) { + byte n; // record length + byte t; // record type + + // read one line of the hex file + readchar(); // colon + n = readbyte(); // record length + readword(); // address + t = readbyte(); // type + if(t == 0) { + // data record + Serial.print(' '); + for(int i=0; i=0; i--) + { + digitalWrite(MOSI, (output >> i) & 1); + //delay(1); + digitalWrite(SCK, HIGH); + input |= digitalRead(MISO) << i; + //delay(1); + digitalWrite(SCK, LOW); + } + + return input; +} + +dword spidword(dword output) +{ + return spibits(32, output); +} + +word spiword(word output) +{ + return spibits(16, (dword)output); +} + +byte spibyte(byte output) +{ + return spibits(8, (dword)output); +} + +void printhex(byte x) +{ + const char digits[] = "0123456789ABCDEF"; + + Serial.print(digits[x>>4]); + Serial.print(digits[x&0x0F]); +} + +void printbits(byte x) +{ + for(int i=7; i>=0; i--) + Serial.print((char)('0' + ((x>>i) & 1))); +} + +void waitforinput(void) +{ + if(! Serial.available()) { + // cheap-ass flow control + digitalWrite(CTS, LOW); // clear to send + while(! Serial.available()) + ; + digitalWrite(CTS, HIGH); // not clear to send + } +} + +char readchar(void) +{ + waitforinput(); + return Serial.read(); +} + +byte readnibble(void) +{ + char c; + + c = readchar(); + if(c>='0' && c<='9') + return (c-'0'); + else if(c>='A' && c<='F') + return (c-'A' + 10); + else if(c>='a' && c<='f') + return (c-'a' + 10); + else + return 0; +} + +byte readbyte(void) +{ + byte x,y; + + x = readnibble(); + y = readnibble(); + + return ((x<<4) | y); +} + +word readword(void) +{ + word x,y; + + x = readbyte(); + y = readbyte(); + + return ((x<<8) | y); +} + +void skipline(void) +{ + while(readchar() != '\n'); +} diff --git a/Blink/Blink.pde b/Blink/Blink.pde new file mode 100644 index 0000000..1ff77a5 --- /dev/null +++ b/Blink/Blink.pde @@ -0,0 +1,66 @@ +void alle(int CMD) +{ + for(int i=0;i<8;i++) { + digitalWrite(i, CMD); + } +} + +void setup() +{ + pinMode(0, OUTPUT); + pinMode(1, OUTPUT); + pinMode(2, OUTPUT); + pinMode(3, OUTPUT); + pinMode(4, OUTPUT); + pinMode(5, OUTPUT); + pinMode(6, OUTPUT); + pinMode(7, OUTPUT); +} + +void loop() +{ + alle(HIGH); + delay(500); + alle(LOW); + delay(500); + /* + digitalWrite(0, HIGH); + delay(500); + digitalWrite(0, LOW); + delay(500); + + digitalWrite(1, HIGH); + delay(500); + digitalWrite(1, LOW); + delay(500); + + digitalWrite(2, HIGH); + delay(500); + digitalWrite(2, LOW); + delay(500); + + digitalWrite(3, HIGH); + delay(500); + digitalWrite(3, LOW); + delay(500); + + digitalWrite(4, HIGH); + delay(500); + digitalWrite(4, LOW); + delay(500); + + digitalWrite(5, HIGH); + delay(500); + digitalWrite(5, LOW); + delay(500); + + digitalWrite(6, HIGH); + delay(500); + digitalWrite(6, LOW); + delay(500); + + digitalWrite(7, HIGH); + delay(500); + digitalWrite(7, LOW); + delay(500); */ +} diff --git a/Blink/Foo.pde b/Blink/Foo.pde new file mode 100644 index 0000000..e69de29 diff --git a/Blink2015/Blink2015.ino/Blink2015.ino.ino b/Blink2015/Blink2015.ino/Blink2015.ino.ino new file mode 100644 index 0000000..3f42e4d --- /dev/null +++ b/Blink2015/Blink2015.ino/Blink2015.ino.ino @@ -0,0 +1,29 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + Most Arduinos have an on-board LED you can control. On the Uno and + Leonardo, it is attached to digital pin 13. If you're unsure what + pin the on-board LED is connected to on your Arduino model, check + the documentation at http://www.arduino.cc + + This example code is in the public domain. + + modified 8 May 2014 + by Scott Fitzgerald + */ + + +// the setup function runs once when you press reset or power the board +void setup() { + // initialize digital pin 13 as an output. + pinMode(13, OUTPUT); +} + +// the loop function runs over and over again forever +void loop() { + digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(13, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second +} diff --git a/BlinkNeu/BlinkNeu.pde b/BlinkNeu/BlinkNeu.pde new file mode 100644 index 0000000..849c990 --- /dev/null +++ b/BlinkNeu/BlinkNeu.pde @@ -0,0 +1,30 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { +Serial.begin(9600); + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(9, OUTPUT); +pinMode(10, OUTPUT); +pinMode(11, OUTPUT); +} + +void loop() { + digitalWrite(9, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(10, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(11, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(9, LOW); // set the LED on + delay(1000); // wait for a second + digitalWrite(10, LOW); // set the LED on + delay(1000); // wait for a second + digitalWrite(11, LOW); // set the LED off + delay(1000); // wait for a second +} diff --git a/Blink_GNO b/Blink_GNO new file mode 100644 index 0000000..ecb1112 --- /dev/null +++ b/Blink_GNO @@ -0,0 +1,14 @@ +void setup() +{ + Serial.begin(9600); // USB is always 12 Mbit/sec +} + +void loop() +{ + digitalWrite(13, HIGH); + Serial.println("Hello World..."); + delay(1000); + digitalWrite(13, LOW); + Serial.println("Hello World..."); + delay(1000); +} \ No newline at end of file diff --git a/Blink_test/Blink_test.pde b/Blink_test/Blink_test.pde new file mode 100644 index 0000000..8c7866b --- /dev/null +++ b/Blink_test/Blink_test.pde @@ -0,0 +1,19 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(13, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + //delay(20); // wait for a second + //digitalWrite(13, LOW); // set the LED off + //delay(20); // wait for a second +} diff --git a/DCF77/LCD4Bit.pde b/DCF77/LCD4Bit.pde new file mode 100644 index 0000000..5f1eabc --- /dev/null +++ b/DCF77/LCD4Bit.pde @@ -0,0 +1,327 @@ + +#include +#include + +//create object to control an LCD. +//number of lines in display=2 +LCD4Bit lcd = LCD4Bit(2); + +/** + * Where is the DCF receiver connected? + */ +#define DCF77PIN 6 +/** + * Where is the LED connected? + */ +#define BLINKPIN 13 +/** + * Turn debugging on or off + */ +//#define DCF_DEBUG 1 +/** + * Number of milliseconds to elapse before we assume a "1", + * if we receive a falling flank before - its a 0. + */ +#define DCF_split_millis 140 +/** + * There is no signal in second 59 - detect the beginning of + * a new minute. + */ +#define DCF_sync_millis 1200 +/** + * Definitions for the timer interrupt 2 handler: + * The Arduino runs at 16 Mhz, we use a prescaler of 64 -> We need to + * initialize the counter with 6. This way, we have 1000 interrupts per second. + * We use tick_counter to count the interrupts. + */ +#define INIT_TIMER_COUNT 6 +#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT +int tick_counter = 0; +/** + * DCF time format struct + */ +struct DCF77Buffer { + unsigned long long prefix :21; + unsigned long long Min :7; // minutes + unsigned long long P1 :1; // parity minutes + unsigned long long Hour :6; // hours + unsigned long long P2 :1; // parity hours + unsigned long long Day :6; // day + unsigned long long Weekday :3; // day of week + unsigned long long Month :5; // month + unsigned long long Year :8; // year (5 -> 2005) + unsigned long long P3 :1; // parity +}; +struct { + unsigned char parity_flag :1; + unsigned char parity_min :1; + unsigned char parity_hour :1; + unsigned char parity_date :1; +} flags; +/** + * Clock variables + */ +volatile unsigned char DCFSignalState = 0; +unsigned char previousSignalState; +int previousFlankTime; +int bufferPosition; +unsigned long long dcf_rx_buffer; +/** + * time vars: the time is stored here! + */ +volatile unsigned char ss; +volatile unsigned char mm; +volatile unsigned char hh; +volatile unsigned char day; +volatile unsigned char mon; +volatile unsigned int year; + + +/** + * used in main loop: detect a new second... + */ +unsigned char previousSecond; + +/** + * Initialize the DCF77 routines: initialize the variables, + * configure the interrupt behaviour. + */ +void DCF77Init() { + previousSignalState=0; + previousFlankTime=0; + bufferPosition=0; + dcf_rx_buffer=0; + ss=mm=hh=day=mon=year=0; +#ifdef DCF_DEBUG + Serial.println("Initializing DCF77 routines"); + Serial.print("Using DCF77 pin #"); + Serial.println(DCF77PIN); + pinMode(BLINKPIN, OUTPUT); + pinMode(DCF77PIN, INPUT); +#endif + pinMode(DCF77PIN, INPUT); +#ifdef DCF_DEBUG + Serial.println("Initializing timerinterrupt"); +#endif + //Timer2 Settings: Timer Prescaler /64, + TCCR2 |= (1< 59, + * a new minute begins -> time to call finalizeBuffer(). + */ +void appendSignal(unsigned char signal) { +#ifdef DCF_DEBUG + Serial.print(", appending value "); + Serial.print(signal, DEC); + Serial.print(" at position "); + Serial.println(bufferPosition); +#endif + dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) signal << bufferPosition); + // Update the parity bits. First: Reset when minute, hour or date starts. + if (bufferPosition == 21 || bufferPosition == 29 || bufferPosition == 36) { + flags.parity_flag = 0; + } + // save the parity when the corresponding segment ends + if (bufferPosition == 28) {flags.parity_min = flags.parity_flag;}; + if (bufferPosition == 35) {flags.parity_hour = flags.parity_flag;}; + if (bufferPosition == 58) {flags.parity_date = flags.parity_flag;}; + // When we received a 1, toggle the parity flag + if (signal == 1) { + flags.parity_flag = flags.parity_flag ^ 1; + } + bufferPosition++; + if (bufferPosition > 59) { + finalizeBuffer(); + } +} + +/** + * Evaluates the information stored in the buffer. This is where the DCF77 + * signal is decoded and the internal clock is updated. + */ +void finalizeBuffer(void) { + if (bufferPosition == 59) { +#ifdef DCF_DEBUG + Serial.println("Finalizing Buffer"); +#endif + struct DCF77Buffer *rx_buffer; + rx_buffer = (struct DCF77Buffer *)(unsigned long long)&dcf_rx_buffer; + if (flags.parity_min == rx_buffer->P1 && + flags.parity_hour == rx_buffer->P2 && + flags.parity_date == rx_buffer->P3) + { +#ifdef DCF_DEBUG + Serial.println("Parity check OK - updating time."); +#endif + //convert the received bits from BCD + mm = rx_buffer->Min-((rx_buffer->Min/16)*6); + hh = rx_buffer->Hour-((rx_buffer->Hour/16)*6); + day= rx_buffer->Day-((rx_buffer->Day/16)*6); + mon= rx_buffer->Month-((rx_buffer->Month/16)*6); + year= 2000 + rx_buffer->Year-((rx_buffer->Year/16)*6); + } +#ifdef DCF_DEBUG + else { + Serial.println("Parity check NOK - running on internal clock."); + } +#endif + } + // reset stuff + ss = 0; + bufferPosition = 0; + dcf_rx_buffer=0; +} + +/** + * Dump the time to the serial line. + */ +void serialDumpTime(void){ + Serial.print("Time: "); + Serial.print(hh, DEC); + Serial.print(":"); + Serial.print(mm, DEC); + Serial.print(":"); + Serial.print(ss, DEC); + Serial.print(" Date: "); + Serial.print(day, DEC); + Serial.print("."); + Serial.print(mon, DEC); + Serial.print("."); + Serial.println(year, DEC); +} + + +/** + * Evaluates the signal as it is received. Decides whether we received + * a "1" or a "0" based on the + */ +void scanSignal(void){ + if (DCFSignalState == 1) { + int thisFlankTime=millis(); + if (thisFlankTime - previousFlankTime > DCF_sync_millis) { +#ifdef DCF_DEBUG + Serial.println("####"); + Serial.println("#### Begin of new Minute!!!"); + Serial.println("####"); +#endif + finalizeBuffer(); + } + previousFlankTime=thisFlankTime; +#ifdef DCF_DEBUG + Serial.print(previousFlankTime); + Serial.print(": DCF77 Signal detected, "); +#endif + } + else { + /* or a falling flank */ + int difference=millis() - previousFlankTime; +#ifdef DCF_DEBUG + Serial.print("duration: "); + Serial.print(difference); +#endif + if (difference < DCF_split_millis) { + appendSignal(0); + } + else { + appendSignal(1); + } + } +} + +/** + * The interrupt routine for counting seconds - increment hh:mm:ss. + */ +ISR(TIMER2_OVF_vect) { + RESET_TIMER2; + tick_counter += 1; + if (tick_counter == 1000) { + ss++; + if (ss==60) { + ss=0; + mm++; + if (mm==60) { + mm=0; + hh++; + if (hh==24) + hh=0; + } + } + tick_counter = 0; + } +}; + +/** + * Interrupthandler for INT0 - called when the signal on Pin 2 changes. + */ +void int0handler() { + // check the value again - since it takes some time to + // activate the interrupt routine, we get a clear signal. + DCFSignalState = digitalRead(DCF77PIN); +} + + +/** + * Standard Arduino methods below. + */ + +void setup(void) { + + //pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat + //lcd.init(); + + // We need to start serial here again, + // for Arduino 007 (new serial code) + Serial.begin(9600); + DCF77Init(); +} + +void loop(void) { + if (ss != previousSecond) { + serialDumpTime(); + previousSecond = ss; + } + if (DCFSignalState != previousSignalState) { + scanSignal(); + if (DCFSignalState) { + digitalWrite(BLINKPIN, HIGH); + } else { + digitalWrite(BLINKPIN, LOW); + } + previousSignalState = DCFSignalState; + } + //delay(20); +} + +void loop22() { + + lcd.clear(); // Clear display + + lcd.printIn("hallo welt!"); // Dislay text on first line + lcd.leftScroll(32, 200); + //lcd.cursorTo(2,0); // Move cursor to second line, position 0 + + //lcd.printIn("fuck off!"); // Display text on second line + /* + while(1) // Endless loop flashing the LED + { + digitalWrite(13, HIGH); + delay(1000); + digitalWrite(13, LOW); + delay(1000); + } + */ +} diff --git a/DS1626/DS1626.ino b/DS1626/DS1626.ino new file mode 100644 index 0000000..e495316 --- /dev/null +++ b/DS1626/DS1626.ino @@ -0,0 +1,143 @@ + +//#include + +//LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +#include + + +#define rxPin 0 +#define txPin 1 +#define ledPin 13 + +#define rstPin 6 +#define clkPin 7 +#define dqPin 8 + +#define tempPin 0 + +// set up a new serial port +SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin); +byte pinState = 0; + +void setup() { + // define pin modes for tx, rx, led pins: + pinMode(rxPin, INPUT); + pinMode(txPin, OUTPUT); + + pinMode(ledPin, OUTPUT); + pinMode(rstPin, OUTPUT); + pinMode(clkPin, OUTPUT); + pinMode(dqPin, OUTPUT); + + // set the data rate for the SoftwareSerial port + mySerial.begin(9600); + + //lcd.begin(16, 2); + //lcd.print("Temperature:"); +} + + +void loop() { + float temp; + + rst_low(); + + clk_high(); + rst_high(); //all data transfer are initiated by driving RST high + write_command(0x0c); // write config command + write_command(0x02); // cpu mode + rst_low(); + delay(200); //wait until the configuration register is written + + clk_high(); + rst_high(); + write_command(0x51); //start conversion + rst_low(); + delay(200); + + clk_high(); + rst_high(); + write_command(0xAA); + int raw_data = read_raw_data(); + rst_low(); + + mySerial.print("temperature:"); + mySerial.print(raw_data/20); + mySerial.println(" C"); + + /* + temp = analogRead(tempPin); + //temp = temp * 0.48828125; + temp = (5.0 * temp * 100.0)/1024.0; + lcd.setCursor(0, 1); + lcd.print(temp); + //lcd.print(" "); + //lcd.print("wsew"); + + + delay(1000); + */ + delay(1000); + +} + +void write_command(int command) +/* sends 8 bit command on DQ output, least sig bit first */ +{ + int n, bit; + + for(n=0;n<8;n++) + { + bit = ((command >> n) & (0x01)); + out_bit(bit); + } +} + +int read_raw_data(void) +{ + int bit,n; + int raw_data=0; + + pinMode(dqPin,INPUT); + + /* jam the dq lead high to use as input */ + for(n=0;n<9;n++) + { + clk_low(); + bit=(digitalRead(dqPin)); + clk_high(); + raw_data = raw_data | (bit << n); + } + pinMode(dqPin, OUTPUT); + return(raw_data); +} + +void out_bit(int bit) +{ + digitalWrite(dqPin, bit); /* set up the data */ + clk_low(); /* and then provide a clock pulse */ + clk_high(); +} + +void clk_high(void) +{ + digitalWrite(clkPin,HIGH); +} + +void clk_low(void) +{ + digitalWrite(clkPin,LOW); +} + +void rst_high(void) +{ + digitalWrite(rstPin,HIGH); +} + +void rst_low(void) +{ + digitalWrite(rstPin,LOW); +} + + diff --git a/Dimmer/Dimmer.ino b/Dimmer/Dimmer.ino new file mode 100644 index 0000000..bda256c --- /dev/null +++ b/Dimmer/Dimmer.ino @@ -0,0 +1,36 @@ +/* + * Dimmer + * by David A. Mellis + * + * Demonstrates the sending data from the computer to the Arduino board, + * in this case to control the brightness of an LED. The data is sent + * in individual bytes, each of which ranges from 0 to 255. Arduino + * reads these bytes and uses them to set the brightness of the LED. + * + * http://www.arduino.cc/en/Tutorial/Dimmer + */ + +int ledPin = 13; + +void setup() +{ + // begin the serial communication + Serial.begin(9600); + pinMode(ledPin, OUTPUT); +} + +void loop() +{ + byte val; + + // check if data has been sent from the computer + if (Serial.available()) { + // read the most recent byte (which will be from 0 to 255) + val = Serial.read(); + // set the brightness of the LED + analogWrite(ledPin, val); + //Serial.write(255); + Serial.write(val/2); + } + +} diff --git a/Display_01/Display_01.pde b/Display_01/Display_01.pde new file mode 100644 index 0000000..1e1c839 --- /dev/null +++ b/Display_01/Display_01.pde @@ -0,0 +1,61 @@ +/* + LiquidCrystal Library - display() and noDisplay() + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and uses the + display() and noDisplay() functions to turn on and off + the display. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); + delay(5000); +} + +void loop() { + // Turn off the display: + lcd.noDisplay(); + delay(500); + // Turn on the display: + lcd.display(); + delay(500); +} + diff --git a/Display_02/Display_02.pde b/Display_02/Display_02.pde new file mode 100644 index 0000000..1a4ebbe --- /dev/null +++ b/Display_02/Display_02.pde @@ -0,0 +1,79 @@ + +#include + +// Connections: +// rs (LCD pin 4) to Arduino pin 12 +// rw (LCD pin 5) to Arduino pin 11 +// enable (LCD pin 6) to Arduino pin 10 +// LCD pin 15 to Arduino pin 13 +// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2 +LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); + +#define OUTPIN 7 +#define INPIN 8 + +void setup() +{ + + pinMode(OUTPIN, OUTPUT); + digitalWrite(OUTPIN, LOW); + pinMode(INPIN, INPUT); + pinMode(13, OUTPUT); + digitalWrite(13, LOW); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off. + + + + + lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc. + lcd.clear(); // start with a blank screen + lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row) + lcd.print("Hej Katrin..."); // change this text to whatever you like. keep it clean. + lcd.setCursor(0,1); // set cursor to column 0, row 1 + lcd.print("Jeg elsker dig!"); + + // if you have a 4 row LCD, uncomment these lines to write to the bottom rows + // and change the lcd.begin() statement above. + //lcd.setCursor(0,2); // set cursor to column 0, row 2 + //lcd.print("Row 3"); + //lcd.setCursor(0,3); // set cursor to column 0, row 3 + //lcd.print("Row 4"); +} + +void loop() +{ + /* + boolean val = digitalRead(INPIN); + + if(val == LOW) { + digitalWrite(OUTPIN, LOW); + digitalWrite(13, LOW); + + } + + if(val == HIGH) { + for(int i = 15; i >= 0; i--) { + lcd.clear(); + lcd.setCursor(i,1); + lcd.print("<"); + delay(200); + } + for(int i = 0; i <= 15; i++) { + lcd.clear(); + lcd.setCursor(i,0); + lcd.print(">"); + delay(200); + if(i == 15) { + lcd.clear(); + } + + } + digitalWrite(OUTPIN, HIGH); + digitalWrite(13, HIGH); + // delay(200); + } + */ + // + ///} + delay(333); + +} diff --git a/Fade/Fade.ino b/Fade/Fade.ino new file mode 100644 index 0000000..6f4d53b --- /dev/null +++ b/Fade/Fade.ino @@ -0,0 +1,35 @@ +/* + Fade + + This example shows how to fade an LED on pin 9 + using the analogWrite() function. + + This example code is in the public domain. + */ + +int led = 11; // the pin that the LED is attached to +int brightness = 0; // how bright the LED is +int fadeAmount = 5; // how many points to fade the LED by + +// the setup routine runs once when you press reset: +void setup() { + // declare pin 9 to be an output: + pinMode(led, OUTPUT); +} + +// the loop routine runs over and over again forever: +void loop() { + // set the brightness of pin 9: + analogWrite(led, brightness); + + // change the brightness for next time through the loop: + brightness = brightness + fadeAmount; + + // reverse the direction of the fading at the ends of the fade: + if (brightness == 0 || brightness == 255) { + fadeAmount = -fadeAmount ; + } + // wait for 30 milliseconds to see the dimming effect + delay(30); +} + diff --git a/FadeNeu/FadeNeu.pde b/FadeNeu/FadeNeu.pde new file mode 100644 index 0000000..6595ec7 --- /dev/null +++ b/FadeNeu/FadeNeu.pde @@ -0,0 +1,43 @@ +/* + Fade + + This example shows how to fade an LED on pin 9 + using the analogWrite() function. + + This example code is in the public domain. + + */ +int brightness1 = 0; // how bright the LED is +int brightness2 = 85; // how bright the LED is +int brightness3 = 170; // how bright the LED is +int fadeAmount1 = 5; // how many points to fade the LED by +int fadeAmount2 = 5; // how many points to fade the LED by +int fadeAmount3 = 5; // how many points to fade the LED by + +void setup() { + pinMode(9, OUTPUT); + pinMode(10, OUTPUT); + pinMode(11, OUTPUT); +} + +void loop() { + analogWrite(9, brightness1); + analogWrite(10, brightness2); + analogWrite(11, brightness3); + + brightness1 = brightness1 + fadeAmount1; + brightness2 = brightness2 + fadeAmount2; + brightness3 = brightness3 + fadeAmount3; + + if (brightness1 == 0 || brightness1 == 255) { + fadeAmount1 = -fadeAmount1 ; + } + if (brightness2 == 0 || brightness2 == 255) { + fadeAmount2 = -fadeAmount2 ; + } + if (brightness3 == 0 || brightness3 == 255) { + fadeAmount3 = -fadeAmount3 ; + } + + delay(250); +} diff --git a/Fade_test/Fade_test.pde b/Fade_test/Fade_test.pde new file mode 100644 index 0000000..d89a3db --- /dev/null +++ b/Fade_test/Fade_test.pde @@ -0,0 +1,33 @@ +/* + Fade + + This example shows how to fade an LED on pin 9 + using the analogWrite() function. + + This example code is in the public domain. + + */ +int brightness = 0; // how bright the LED is +int fadeAmount = 5; // how many points to fade the LED by + +void setup() { + // declare pin 9 to be an output: + pinMode(1, OUTPUT); + pinMode(11, OUTPUT); +} + +void loop() { + // set the brightness of pin 9: + analogWrite(1, brightness); + analogWrite(11, brightness); + + // change the brightness for next time through the loop: + brightness = brightness + fadeAmount; + + // reverse the direction of the fading at the ends of the fade: + if (brightness == 0 || brightness == 255) { + fadeAmount = -fadeAmount ; + } + // wait for 30 milliseconds to see the dimming effect + delay(30); +} diff --git a/LCD2015/LCD2015.ino/LCD2015.ino.ino b/LCD2015/LCD2015.ino/LCD2015.ino.ino new file mode 100644 index 0000000..d640341 --- /dev/null +++ b/LCD2015/LCD2015.ino/LCD2015.ino.ino @@ -0,0 +1,29 @@ +#include + +LiquidCrystal lcd(7, 6, 5, 4, 3, 2); + +float tempRaw; +float tempC; +float tempF; +int tempPin = 0; + +void setup() { + pinMode(13, OUTPUT); + lcd.begin(16, 2); + lcd.print("Temperature:"); +} + +void loop() { + tempRaw = analogRead(tempPin); + tempC = tempRaw/2; + tempF = (tempC*9)/5 + 32; + lcd.setCursor(0, 1); + lcd.print(tempC); + lcd.print("C / "); + lcd.print(tempF); + lcd.print("F"); + digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(13, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second +} diff --git a/LCD4Bit/LCD4Bit.pde b/LCD4Bit/LCD4Bit.pde new file mode 100644 index 0000000..276ede5 --- /dev/null +++ b/LCD4Bit/LCD4Bit.pde @@ -0,0 +1,51 @@ + + +#include + +//create object to control an LCD. +//number of lines in display=2 +LCD4Bit lcd = LCD4Bit(2); + + + + +void setup(void) { + pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat + lcd.init(); +} + +void loop() { + + lcd.clear(); // Clear display + + //lcd.printIn("fuck the world guys... ?"); // Dislay text on first line + //lcd.leftScroll(32, 600); + // lcd.cursorTo(2,0); // Move cursor to second line, position 0 + + //lcd.printIn("<<<>>>"); // Display text on second line + + +lcd.printIn("Hey guys..."); +lcd.cursorTo(2,0); +delay(5000); +lcd.printIn("what's up?"); +delay(5000); +lcd.cursorTo(1,0); +lcd.printIn("Hehehehehhe...."); +lcd.cursorTo(2,0); +lcd.printIn("................."); +delay(10000); +//lcd.printIn(""); +//lcd.printIn(""); + +delay(5000); +/* + while(1) // Endless loop flashing the LED + { + digitalWrite(13, HIGH); + delay(1000); + digitalWrite(13, LOW); + delay(1000); + } + */ +} diff --git a/LCD4BitExample_01/LCD4BitExample_01.pde b/LCD4BitExample_01/LCD4BitExample_01.pde new file mode 100644 index 0000000..4f4f8e4 --- /dev/null +++ b/LCD4BitExample_01/LCD4BitExample_01.pde @@ -0,0 +1,47 @@ +//example use of LCD4Bit library + +#include +//create object to control an LCD. +//number of lines in display=1 +LCD4Bit lcd = LCD4Bit(2); + +//some messages to display on the LCD +char msgs[6][15] = {"apple", "banana", "pineapple", "mango", "watermelon", "pear"}; +int NUM_MSGS = 6; + +void setup() { + pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat + + lcd.init(); + //optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init() + //lcd.commandWrite(0x0F);//cursor on, display on, blink on. (nasty!) +} + +void loop() { + digitalWrite(13, HIGH); //light the debug LED + + //pick a random message from the array + int pick = random(NUM_MSGS); + char* msg = msgs[pick]; + + lcd.clear(); + lcd.printIn(msg); + delay(1000); + digitalWrite(13, LOW); + + //print some dots individually + for (int i=0; i<3; i++){ + lcd.print('.'); + delay(100); + } + //print something on the display's second line. + //uncomment this if your display HAS two lines! + /* + lcd.cursorTo(2, 0); //line=2, x=0. + lcd.printIn("Score: 6/7"); + delay(1000); + */ + + //scroll entire display 20 chars to left, delaying 50ms each inc + lcd.leftScroll(20, 50); +} diff --git a/Motion_Sensor/Motion_Sensor.pde b/Motion_Sensor/Motion_Sensor.pde new file mode 100644 index 0000000..b1528b4 --- /dev/null +++ b/Motion_Sensor/Motion_Sensor.pde @@ -0,0 +1,29 @@ + + + +int buttonState = 0; + +void setup() { + + Serial.begin(9600); + + + pinMode(7, INPUT); + pinMode(13, OUTPUT); +} + +void loop() { + + + + buttonState = digitalRead(7); + + if (buttonState == HIGH) { + digitalWrite(13, HIGH); + } + else { + digitalWrite(13, LOW); + } + Serial.println(buttonState, DEC); + delay(1000); // wait for a second +} diff --git a/README.md b/README.md index 961a785..b065fc3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ -# arduino -All my Arduino stuff. +arduino +======= + +All my Arduino stuff. Most files are many years old because I didn't hacked on +Arduino for long time. Many files are just garbage and will be deleted at some +time. I will try to make this repository clean ASAP. Currently I only need it +for sharing my Arduino code between my devices. I recommend not to use this +code actually.... ;) diff --git a/Relais/Relais.pde b/Relais/Relais.pde new file mode 100644 index 0000000..18459e0 --- /dev/null +++ b/Relais/Relais.pde @@ -0,0 +1,15 @@ + +int ledPin = 13; // LED connected to digital pin 13 + +void setup() // run once, when the sketch starts +{ + pinMode(ledPin, OUTPUT); // sets the digital pin as output +} + +void loop() // run over and over again +{ + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, LOW); // sets the LED off + delay(1000); // waits for a second +} diff --git a/ShiftRegister_1/ShiftRegister_1.pde b/ShiftRegister_1/ShiftRegister_1.pde new file mode 100644 index 0000000..06c822e --- /dev/null +++ b/ShiftRegister_1/ShiftRegister_1.pde @@ -0,0 +1,32 @@ + +int pin_led_clock=2; +int pin_led_latch=3; +int pin_led_data=4; + +void setup() { + Serial.begin(9600); //start serial + pinMode(pin_led_data, OUTPUT); + pinMode(pin_led_latch, OUTPUT); + pinMode(pin_led_clock, OUTPUT); +} + +void loop() { + set_led_states(LOW); + delay(500); + set_led_states(HIGH); + delay(500); +} + +void set_led_states(int CMD){ + for (int n=0; n<8; n++) { + digitalWrite(pin_led_data, CMD); // turn the 'current' led on + pulse_pin(pin_led_clock); // address the next bit slot + } + pulse_pin(pin_led_latch); // when the latch goes from low to high, the data that's been stored to the register's memory gets sent to its output pins +} + +// Set a pin to low, then high +void pulse_pin(int pin_number){ + digitalWrite(pin_number,LOW); + digitalWrite(pin_number,HIGH); +} diff --git a/Shift_Register_01/Shift_Register_01.pde b/Shift_Register_01/Shift_Register_01.pde new file mode 100644 index 0000000..eacefb6 --- /dev/null +++ b/Shift_Register_01/Shift_Register_01.pde @@ -0,0 +1,44 @@ +//**************************************************************// +// Name : shiftOutCode, Hello World +// Author : Carlyn Maw,Tom Igoe, David A. Mellis +// Date : 25 Oct, 2006 +// Modified: 23 Mar 2010 +// Version : 2.0 +// Notes : Code for using a 74HC595 Shift Register // +// : to count from 0 to 255 +//**************************************************************** + +//Pin connected to ST_CP of 74HC595 +int latchPin = 8; +//Pin connected to SH_CP of 74HC595 +int clockPin = 12; +////Pin connected to DS of 74HC595 +int dataPin = 11; + + + +void setup() { + //set pins to output so you can control the shift register + pinMode(latchPin, OUTPUT); + pinMode(clockPin, OUTPUT); + pinMode(dataPin, OUTPUT); +} + +void loop() { + + for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) { + digitalWrite(latchPin, LOW); + shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); + digitalWrite(latchPin, HIGH); + delay(300); + } + + for (int numberToDisplay = 255; numberToDisplay >= 0; numberToDisplay--) { + digitalWrite(latchPin, LOW); + shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); + digitalWrite(latchPin, HIGH); + delay(300); + } +} + + diff --git a/Shift_Register_02/Shift_Register_02.pde b/Shift_Register_02/Shift_Register_02.pde new file mode 100644 index 0000000..a8aba3c --- /dev/null +++ b/Shift_Register_02/Shift_Register_02.pde @@ -0,0 +1,68 @@ +/* + Shift Register Example + for 74HC595 shift register + + This sketch turns reads serial input and uses it to set the pins + of a 74HC595 shift register. + + Hardware: + * 74HC595 shift register attached to pins 2, 3, and 4 of the Arduino, + as detailed below. + * LEDs attached to each of the outputs of the shift register + + Created 22 May 2009 + Created 23 Mar 2010 + by Tom Igoe + + */ + +//Pin connected to latch pin (ST_CP) of 74HC595 +const int latchPin = 8; +//Pin connected to clock pin (SH_CP) of 74HC595 +const int clockPin = 12; +////Pin connected to Data in (DS) of 74HC595 +const int dataPin = 11; + +void setup() { + //set pins to output because they are addressed in the main loop + pinMode(latchPin, OUTPUT); + pinMode(dataPin, OUTPUT); + pinMode(clockPin, OUTPUT); + Serial.begin(9600); + Serial.println("reset"); +} + +void loop() { + if (Serial.available() > 0) { + // ASCII '0' through '9' characters are + // represented by the values 48 through 57. + // so if the user types a number from 0 through 9 in ASCII, + // you can subtract 48 to get the actual value: + int bitToSet = Serial.read() - 48; + + // write to the shift register with the correct bit set high: + registerWrite(bitToSet, HIGH); + } +} + +// This method sends bits to the shift register: + +void registerWrite(int whichPin, int whichState) { +// the bits you want to send + byte bitsToSend = 0; + + // turn off the output so the pins don't light up + // while you're shifting bits: + digitalWrite(latchPin, LOW); + + // turn on the next highest bit in bitsToSend: + bitWrite(bitsToSend, whichPin, whichState); + + // shift the bits out: + shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend); + + // turn on the output so the LEDs can light up: + digitalWrite(latchPin, HIGH); + +} + diff --git a/Temp/Temp.pde b/Temp/Temp.pde new file mode 100644 index 0000000..1e73dc2 --- /dev/null +++ b/Temp/Temp.pde @@ -0,0 +1,113 @@ + + +#include + +#define BUTTON1 2 +#define BUTTON2 3 + +// ds1621 has 0x9(b1001) A0 A1 A2 +#define DS1621_ADDR ((0x9 << 3) | 0x00) + +// start up ds1621 +void ds1621_init() +{ + + Serial.print(DS1621_ADDR, HEX); + // write 0x2 to config register 0xac + Wire.beginTransmission(DS1621_ADDR); + Wire.send(0xac); + Wire.send(0x02); + Wire.endTransmission(); + delay(20); + + // tell the ds1621 to start measuring temperature + Wire.beginTransmission(DS1621_ADDR); + Wire.send(0xEE); + Wire.endTransmission(); +} + +// read temperature +unsigned int ds161_read_temp() +{ + unsigned int data; + + // tell ds1621 that we want to read register 0xaa (the temperature is in there) + Wire.beginTransmission(DS1621_ADDR); + Wire.send(0xaa); + Wire.endTransmission(); + + // start reading the 2 bytes of temp data + Wire.beginTransmission(DS1621_ADDR); + Wire.requestFrom(DS1621_ADDR, 2); + if(Wire.available()) + data = Wire.receive() << 8; + if(Wire.available()) + data |= Wire.receive(); + return data; +} + +// format and output the temperature read from a ds1621 +void ds1621_print_temp(int temp) +{ + if(temp & 0x8000) + Serial.print("-"); + else + Serial.print(""); + temp &= 0x7fff; + Serial.print(temp >> 8); + if(temp & 0xff) + Serial.print(",5"); + else + Serial.print(",0"); + Serial.print("\n"); + delay(1000); +} +int a = 0; +// this function is called everytime button1 is pressed +void button1_isr(void) +{ +// Serial.print("button1\n"); + a= 1; +} + +// this function is called everytime button2 is pressed +void button2_isr(void) +{ + //Serial.print("button2\n"); + a=2; +} + +void setup() +{ + + pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat + + // start serial + Serial.begin(9600); + + // start i2c + Wire.begin(); + + // start thermometer + ds1621_init(); + + // setup button gpio + // gpio is input and internal pullup enabled + pinMode(BUTTON1, INPUT); + pinMode(BUTTON2, INPUT); + digitalWrite(BUTTON1, HIGH); + digitalWrite(BUTTON2, HIGH); + + // give both buttons an interrupt handler + attachInterrupt(0, button1_isr, FALLING); + attachInterrupt(1, button2_isr, FALLING); + interrupts(); +} + +void loop() +{ + + int temp = ds161_read_temp(); + ds1621_print_temp(temp); + delay(1000); +} diff --git a/Temp2/Temp2.pde b/Temp2/Temp2.pde new file mode 100644 index 0000000..b4a0aec --- /dev/null +++ b/Temp2/Temp2.pde @@ -0,0 +1,48 @@ +#include + +// ds1621 has 0x9(b1001) A0 A1 A2 +//#define DS1621_ADDR 72 +#define DS1621_ADDR ((0x9 << 3) | 0x00) + +void setup() +{ + // start serial + Serial.begin(9600); + + // write 0x2 to config register 0xac + Wire.begin(DS1621_ADDR); + Wire.send(0xac); + Wire.send(0x02); + + delay(20); + + // tell the ds1621 to start measuring temperature + Wire.send(0xee); + + // tell ds1621 that we want to read register + // 0xaa (the temperature is in there) + Wire.send(0xaa); +} + +void loop() +{ + unsigned int data; + + // start reading the 2 bytes of temp data + Wire.requestFrom(DS1621_ADDR, 2); + + if(Wire.available()) + data = Wire.receive() << 8; + if(Wire.available()) + data |= Wire.receive(); + + Serial.print(data >> 8); + + if(data & 0xff) + Serial.print(",5"); + else + Serial.print(",0"); + + Serial.println(""); + delay(1000); +} diff --git a/Temp_03/Temp_03.pde b/Temp_03/Temp_03.pde new file mode 100644 index 0000000..87c6f07 --- /dev/null +++ b/Temp_03/Temp_03.pde @@ -0,0 +1,15 @@ +float temp; +int tempPin = 0; + +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + temp = analogRead(tempPin); + temp = temp * 0.48828125; + Serial.println(temp); + delay(1000); +} diff --git a/WebClient/WebClient.pde b/WebClient/WebClient.pde new file mode 100644 index 0000000..b1ecca7 --- /dev/null +++ b/WebClient/WebClient.pde @@ -0,0 +1,71 @@ +/* + Web client + + This sketch connects to a website (http://www.google.com) + using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 18 Dec 2009 + by David A. Mellis + + */ + +#include +#include + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network: +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; +byte ip[] = { 192,168,1,23 }; +byte server[] = { 87,230,87,117 }; + +// Initialize the Ethernet client library +// with the IP address and port of the server +// that you want to connect to (port 80 is default for HTTP): +Client client(server, 80); + +void setup() { + // start the Ethernet connection: + Ethernet.begin(mac, ip); + // start the serial library: + Serial.begin(9600); + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.println("connecting..."); + + // if you get a connection, report back via serial: + if (client.connect()) { + Serial.println("connected"); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.0"); + client.println(); + } + else { + // kf you didn't get a connection to the server: + Serial.println("connection failed"); + } +} + +void loop() +{ + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) { + char c = client.read(); + Serial.print(c); + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + + // do nothing forevermore: + for(;;) + ; + } +} + diff --git a/WebServer/WebServer.pde b/WebServer/WebServer.pde new file mode 100644 index 0000000..14c2e9e --- /dev/null +++ b/WebServer/WebServer.pde @@ -0,0 +1,82 @@ +/* + Web Server + + A simple web server that shows the value of the analog input pins. + using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + * Analog inputs attached to pins A0 through A5 (optional) + + created 18 Dec 2009 + by David A. Mellis + modified 4 Sep 2010 + by Tom Igoe + + */ + +#include +#include + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network: +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; +byte ip[] = { 192,168,1, 20 }; + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +Server server(80); + +void setup() +{ + // start the Ethernet connection and the server: + Ethernet.begin(mac, ip); + server.begin(); +} + +void loop() +{ + // listen for incoming clients + Client client = server.available(); + if (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(); + + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(analogRead(analogChannel)); + client.println("
"); + } + 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(); + } +} diff --git a/_0001_delay/_0001_delay.ino b/_0001_delay/_0001_delay.ino new file mode 100644 index 0000000..81eb85a --- /dev/null +++ b/_0001_delay/_0001_delay.ino @@ -0,0 +1,14 @@ +void setup() +{ + Serial.begin(9600); // USB is always 12 Mbit/sec +} + +void loop() +{ + digitalWrite(13, HIGH); + Serial.println("Hello World..."); + delay(1000); + digitalWrite(13, LOW); + //Serial.println("Hello World..."); + delay(1000); +} diff --git a/_0002_delay/_0002_delay.pde b/_0002_delay/_0002_delay.pde new file mode 100644 index 0000000..003566f --- /dev/null +++ b/_0002_delay/_0002_delay.pde @@ -0,0 +1,18 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + Serial.begin(9600); + pinMode(13, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(13, LOW); // set the LED off + delay(1000); // wait for a second +} diff --git a/_74HC238/_74HC238.pde b/_74HC238/_74HC238.pde new file mode 100644 index 0000000..e7db891 --- /dev/null +++ b/_74HC238/_74HC238.pde @@ -0,0 +1,27 @@ + +void setup() { + Serial.begin(9600); + pinMode(11, OUTPUT); + pinMode(12, OUTPUT); + pinMode(13, OUTPUT); +} + +void loop() { + digitalWrite(11, LOW); + digitalWrite(12, LOW); + digitalWrite(13, LOW); + + delay(100); + + digitalWrite(11, HIGH); + digitalWrite(12, LOW); + digitalWrite(13, LOW); + + delay(100); + + digitalWrite(11, LOW); + digitalWrite(12, HIGH); + digitalWrite(13, LOW); + + delay(100); +} diff --git a/_7segment/_7segment.ino b/_7segment/_7segment.ino new file mode 100644 index 0000000..f957297 --- /dev/null +++ b/_7segment/_7segment.ino @@ -0,0 +1,33 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + Serial.begin(9600); + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(13, OUTPUT); + pinMode(12, OUTPUT); + pinMode(11, OUTPUT); + pinMode(10, OUTPUT); + pinMode(9, OUTPUT); + pinMode(8, OUTPUT); + pinMode(7, OUTPUT); + pinMode(6, OUTPUT); +} + +void loop() { + digitalWrite(13, LOW); // set the LED on + digitalWrite(12, HIGH); // set the LED on + digitalWrite(11, LOW); // set the LED on + digitalWrite(10, HIGH); // set the LED on + digitalWrite(9, LOW); // set the LED on + digitalWrite(8, LOW); // set the LED on + digitalWrite(7, LOW); // set the LED on + digitalWrite(6, LOW); // set the LED on + + +} diff --git a/_LT1025_temp_sensor/_LT1025_temp_sensor.ino b/_LT1025_temp_sensor/_LT1025_temp_sensor.ino new file mode 100644 index 0000000..471607c --- /dev/null +++ b/_LT1025_temp_sensor/_LT1025_temp_sensor.ino @@ -0,0 +1,21 @@ +int sensorPin = A0; +int ledPin = 13; +int sensorValue = 0; +float printValue = 0; + +void setup() { + Serial.begin(9600); + pinMode(ledPin, OUTPUT); +} + +void loop() { + sensorValue = analogRead(sensorPin); + + printValue = (sensorValue * 0.48828125); + + Serial.print(printValue); + Serial.print("\n"); + digitalWrite(ledPin, HIGH); + delay(1000); + digitalWrite(ledPin, LOW); +} diff --git a/etherShield_ping/etherShield_ping.pde b/etherShield_ping/etherShield_ping.pde new file mode 100644 index 0000000..4fa27ee --- /dev/null +++ b/etherShield_ping/etherShield_ping.pde @@ -0,0 +1,87 @@ +#include "etherShield.h" + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = { + 0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = { + 192,168,1,20}; +// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX + +#define BUFFER_SIZE 250 +unsigned char buf[BUFFER_SIZE+1]; + +uint16_t plen; + +EtherShield es=EtherShield(); + + +void setup(){ + + + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=green LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + +} + +void loop(){ + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will be unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + } + // check if ip packets (icmp or udp) are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)!=0){ + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + // a ping packet, let's send pong + + es.ES_make_echo_reply_from_request(buf,plen); + } + } + + } +} diff --git a/etherShield_web_temperature/etherShield_web_temperature.pde b/etherShield_web_temperature/etherShield_web_temperature.pde new file mode 100644 index 0000000..6f138ca --- /dev/null +++ b/etherShield_web_temperature/etherShield_web_temperature.pde @@ -0,0 +1,221 @@ +#include "etherShield.h" + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = {192,168,1,20}; +static char baseurl[]="http://192.168.1.15/"; +static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254) +// or on a different port: +//static char baseurl[]="http://10.0.0.24:88/"; +//static uint16_t mywwwport =88; // listen port for tcp/www (max range 1-254) +// + +int buttonState = 0; + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; +#define STR_BUFFER_SIZE 22 +static char strbuf[STR_BUFFER_SIZE+1]; + +EtherShield es=EtherShield(); + +// prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf); +int8_t analyse_cmd(char *str); +// get current temperature +#define TEMP_PIN 3 +void getCurrentTemp( int *sign, int *whole, int *fract); + +void setup(){ + + pinMode(7, INPUT); + pinMode(2, OUTPUT); + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + // initialize DS18B20 datapin + digitalWrite(TEMP_PIN, LOW); + pinMode(TEMP_PIN, INPUT); // sets the digital pin as input (logic 1) + + +} + +void loop(){ + uint16_t plen, dat_p; + int8_t cmd; + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will ne unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + + // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address. + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + return; + } + + // check if ip packets are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){ + return; + } + + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + es.ES_make_echo_reply_from_request(buf,plen); + return; + } + + // tcp port www start, compare only the lower byte + if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport){ + if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){ + es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack + return; + } + if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){ + es.ES_init_len_info(buf); // init some data structures + dat_p=es.ES_get_tcp_data_pointer(); + if (dat_p==0){ // we can possibly have no data, just ack: + if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){ + es.ES_make_tcp_ack_from_any(buf); + } + return; + } + if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ + // head, post and other methods for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); + goto SENDTCP; + } + if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ + plen=print_webpage(buf); + goto SENDTCP; + } + cmd=analyse_cmd((char *)&(buf[dat_p+5])); + if (cmd==1){ + plen=print_webpage(buf); + } +SENDTCP: es.ES_make_tcp_ack_from_any(buf); // send ack for http get + es.ES_make_tcp_ack_with_data(buf,plen); // send data + } + } + + } + +} +// The returned value is stored in the global var strbuf +uint8_t find_key_val(char *str,char *key) +{ + uint8_t found=0; + uint8_t i=0; + char *kp; + kp=key; + while(*str && *str!=' ' && found==0){ + if (*str == *kp){ + kp++; + if (*kp == '\0'){ + str++; + kp=key; + if (*str == '='){ + found=1; + } + } + }else{ + kp=key; + } + str++; + } + if (found==1){ + // copy the value to a buffer and terminate it with '\0' + while(*str && *str!=' ' && *str!='&' && i 0x2f){ + // is a ASCII number, return it + r=(*strbuf-0x30); + } + } + return r; +} + + +uint16_t print_webpage(uint8_t *buf) +{ + //char temp_string[1]; + int i=0; + char *temp_string; + + uint16_t plen; + + buttonState = digitalRead(7); + + if (buttonState == HIGH) { + temp_string = "1"; + digitalWrite(2, HIGH); + } + else { + temp_string = "0"; + digitalWrite(2, LOW); + } + Serial.println(buttonState, DEC); + + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); + + while (temp_string[i]) { + buf[TCP_CHECKSUM_L_P+3+plen]=temp_string[i++]; + plen++; + } + + return(plen); +} + + + + diff --git a/libraries/FrequencyTimer2/FrequencyTimer2.cpp b/libraries/FrequencyTimer2/FrequencyTimer2.cpp new file mode 100644 index 0000000..db22427 --- /dev/null +++ b/libraries/FrequencyTimer2/FrequencyTimer2.cpp @@ -0,0 +1,162 @@ +/* + FrequencyTimer2.h - A frequency generator and interrupt generator library + Author: Jim Studt, jim@federated.com + Copyright (c) 2007 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include + +#include + +void (*FrequencyTimer2::onOverflow)() = 0; +uint8_t FrequencyTimer2::enabled = 0; + +#if defined(__AVR_ATmega168__) +SIGNAL(SIG_OUTPUT_COMPARE2A) +#else +SIGNAL(SIG_OUTPUT_COMPARE2) +#endif +{ + static uint8_t inHandler = 0; // protect us from recursion if our handler enables interrupts + + if ( !inHandler && FrequencyTimer2::onOverflow) { + inHandler = 1; + (*FrequencyTimer2::onOverflow)(); + inHandler = 0; + } +} + +void FrequencyTimer2::setOnOverflow( void (*func)() ) +{ + FrequencyTimer2::onOverflow = func; +#if defined(__AVR_ATmega168__) + if ( func) TIMSK2 |= _BV(OCIE2A); + else TIMSK2 &= ~_BV(OCIE2A); +#else + if ( func) TIMSK |= _BV(OCIE2); + else TIMSK &= ~_BV(OCIE2); +#endif +} + +void FrequencyTimer2::setPeriod(unsigned long period) +{ + uint8_t pre, top; + + if ( period == 0) period = 1; + period *= clockCyclesPerMicrosecond(); + + period /= 2; // we work with half-cycles before the toggle + if ( period <= 256) { + pre = 1; + top = period-1; + } else if ( period <= 256L*8) { + pre = 2; + top = period/8-1; + } else if ( period <= 256L*32) { + pre = 3; + top = period/32-1; + } else if ( period <= 256L*64) { + pre = 4; + top = period/64-1; + } else if ( period <= 256L*128) { + pre = 5; + top = period/128-1; + } else if ( period <= 256L*256) { + pre = 6; + top = period/256-1; + } else if ( period <= 256L*1024) { + pre = 7; + top = period/1024-1; + } else { + pre = 7; + top = 255; + } + +#if defined(__AVR_ATmega168__) + TCCR2B = 0; + TCCR2A = 0; + TCNT2 = 0; + ASSR &= ~_BV(AS2); // use clock, not T2 pin + OCR2A = top; + TCCR2A = (_BV(WGM21) | ( FrequencyTimer2::enabled ? _BV(COM2A0) : 0)); + TCCR2B = pre; +#else + TCCR2 = 0; + TCNT2 = 0; + ASSR &= ~_BV(AS2); // use clock, not T2 pin + OCR2 = top; + TCCR2 = (_BV(WGM21) | ( FrequencyTimer2::enabled ? _BV(COM20) : 0) | pre); +#endif +} + +unsigned long FrequencyTimer2::getPeriod() +{ +#if defined(__AVR_ATmega168__) + uint8_t p = (TCCR2B & 7); + unsigned long v = OCR2A; +#else + uint8_t p = (TCCR2 & 7); + unsigned long v = OCR2; +#endif + uint8_t shift; + + switch(p) { + case 0 ... 1: + shift = 0; + break; + case 2: + shift = 3; + break; + case 3: + shift = 5; + break; + case 4: + shift = 6; + break; + case 5: + shift = 7; + break; + case 6: + shift = 8; + break; + case 7: + shift = 10; + break; + } + return (((v+1) << (shift+1)) + 1) / clockCyclesPerMicrosecond(); // shift+1 converts from half-period to period +} + +void FrequencyTimer2::enable() +{ + FrequencyTimer2::enabled = 1; +#if defined(__AVR_ATmega168__) + TCCR2A |= _BV(COM2A0); +#else + TCCR2 |= _BV(COM20); +#endif +} + +void FrequencyTimer2::disable() +{ + FrequencyTimer2::enabled = 0; +#if defined(__AVR_ATmega168__) + TCCR2A &= ~_BV(COM2A0); +#else + TCCR2 &= ~_BV(COM20); +#endif +} diff --git a/libraries/FrequencyTimer2/FrequencyTimer2.h b/libraries/FrequencyTimer2/FrequencyTimer2.h new file mode 100644 index 0000000..7fd7faa --- /dev/null +++ b/libraries/FrequencyTimer2/FrequencyTimer2.h @@ -0,0 +1,42 @@ +#ifndef FREQUENCYTIMER2_IS_IN +#define FREQUENCYTIMER2_IS_IN + +/* + FrequencyTimer2.h - A frequency generator and interrupt generator library + Author: Jim Studt, jim@federated.com + Copyright (c) 2007 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include + +class FrequencyTimer2 +{ + private: + static uint8_t enabled; + public: + static void (*onOverflow)(); // not really public, but I can't work out the 'friend' for the SIGNAL + + public: + static void setPeriod(unsigned long); + static unsigned long getPeriod(); + static void setOnOverflow( void (*)() ); + static void enable(); + static void disable(); +}; + +#endif diff --git a/libraries/FrequencyTimer2/keywords.txt b/libraries/FrequencyTimer2/keywords.txt new file mode 100644 index 0000000..480e1fc --- /dev/null +++ b/libraries/FrequencyTimer2/keywords.txt @@ -0,0 +1,22 @@ +####################################### +# Syntax Coloring Map FrequencyTimer2 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +FrequencyTimer2 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +setPeriod KEYWORD2 +getPeriod KEYWORD2 +enable KEYWORD2 +disable KEYWORD2 +setOnOverflow KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/LCD4Bit/LCD4Bit.cpp b/libraries/LCD4Bit/LCD4Bit.cpp new file mode 100644 index 0000000..e285d60 --- /dev/null +++ b/libraries/LCD4Bit/LCD4Bit.cpp @@ -0,0 +1,232 @@ +/* +LCD4Bit v0.1 16/Oct/2006 neillzero http://abstractplain.net + +What is this? +An arduino library for comms with HD44780-compatible LCD, in 4-bit mode (saves pins) + +Sources: +- The original "LiquidCrystal" 8-bit library and tutorial + http://www.arduino.cc/en/uploads/Tutorial/LiquidCrystal.zip + http://www.arduino.cc/en/Tutorial/LCDLibrary +- DEM 16216 datasheet http://www.maplin.co.uk/Media/PDFs/N27AZ.pdf +- Massimo's suggested 4-bit code (I took initialization from here) http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1144924220/8 +See also: +- glasspusher's code (probably more correct): http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1160586800/0#0 + +Tested only with a DEM 16216 (maplin "N27AZ" - http://www.maplin.co.uk/Search.aspx?criteria=N27AZ) +If you use this successfully, consider feeding back to the arduino wiki with a note of which LCD it worked on. + +Usage: +see the examples folder of this library distribution. + +*/ + +#include "LCD4Bit.h" +extern "C" { + #include //not needed yet + #include //needed for strlen() + #include + #include "WConstants.h" //all things wiring / arduino +} + +//command bytes for LCD +#define CMD_CLR 0x01 +#define CMD_RIGHT 0x1C +#define CMD_LEFT 0x18 +#define CMD_HOME 0x02 + +// --------- PINS ------------------------------------- +//is the RW pin of the LCD under our control? If we're only ever going to write to the LCD, we can use one less microcontroller pin, and just tie the LCD pin to the necessary signal, high or low. +//this stops us sending signals to the RW pin if it isn't being used. +int USING_RW = false; + +//RS, RW and Enable can be set to whatever you like +int RS = 12; +int RW = 11; +int Enable = 2; +//DB should be an unseparated group of pins - because of lazy coding in pushNibble() +int DB[] = {7, 8, 9, 10}; //wire these to DB4~7 on LCD. + +//-------------------------------------------------------- + +//how many lines has the LCD? (don't change here - specify on calling constructor) +int g_num_lines = 2; + +//pulse the Enable pin high (for a microsecond). +//This clocks whatever command or data is in DB4~7 into the LCD controller. +void LCD4Bit::pulseEnablePin(){ + digitalWrite(Enable,LOW); + delayMicroseconds(1); + // send a pulse to enable + digitalWrite(Enable,HIGH); + delayMicroseconds(1); + digitalWrite(Enable,LOW); + delay(1); // pause 1 ms. TODO: what delay, if any, is necessary here? +} + +//push a nibble of data through the the LCD's DB4~7 pins, clocking with the Enable pin. +//We don't care what RS and RW are, here. +void LCD4Bit::pushNibble(int value){ + int val_nibble= value & 0x0F; //clean the value. (unnecessary) + + for (int i=DB[0]; i <= DB[3]; i++) { + digitalWrite(i,val_nibble & 01); + val_nibble >>= 1; + } + pulseEnablePin(); +} + +//push a byte of data through the LCD's DB4~7 pins, in two steps, clocking each with the enable pin. +void LCD4Bit::pushByte(int value){ + int val_lower = value & 0x0F; + int val_upper = value >> 4; + pushNibble(val_upper); + pushNibble(val_lower); +} + + +//stuff the library user might call--------------------------------- +//constructor. num_lines must be 1 or 2, currently. +LCD4Bit::LCD4Bit (int num_lines) { + g_num_lines = num_lines; + if (g_num_lines < 1 || g_num_lines > 2) + { + g_num_lines = 1; + } +} + +void LCD4Bit::commandWriteNibble(int nibble) { + digitalWrite(RS, LOW); + if (USING_RW) { digitalWrite(RW, LOW); } + pushNibble(nibble); +} + + +void LCD4Bit::commandWrite(int value) { + digitalWrite(RS, LOW); + if (USING_RW) { digitalWrite(RW, LOW); } + pushByte(value); + //TODO: perhaps better to add a delay after EVERY command, here. many need a delay, apparently. +} + + + + +//print the given character at the current cursor position. overwrites, doesn't insert. +void LCD4Bit::print(int value) { + //set the RS and RW pins to show we're writing data + digitalWrite(RS, HIGH); + if (USING_RW) { digitalWrite(RW, LOW); } + + //let pushByte worry about the intricacies of Enable, nibble order. + pushByte(value); +} + + +//print the given string to the LCD at the current cursor position. overwrites, doesn't insert. +//While I don't understand why this was named printIn (PRINT IN?) in the original LiquidCrystal library, I've preserved it here to maintain the interchangeability of the two libraries. +void LCD4Bit::printIn(char msg[]) { + uint8_t i; //fancy int. avoids compiler warning when comparing i with strlen()'s uint8_t + for (i=0;i < strlen(msg);i++){ + print(msg[i]); + } +} + + +//send the clear screen command to the LCD +void LCD4Bit::clear(){ + commandWrite(CMD_CLR); + delay(1); +} + + +// initiatize lcd after a short pause +//while there are hard-coded details here of lines, cursor and blink settings, you can override these original settings after calling .init() +void LCD4Bit::init () { + pinMode(Enable,OUTPUT); + pinMode(RS,OUTPUT); + if (USING_RW) { pinMode(RW,OUTPUT); } + pinMode(DB[0],OUTPUT); + pinMode(DB[1],OUTPUT); + pinMode(DB[2],OUTPUT); + pinMode(DB[3],OUTPUT); + + delay(50); + + //The first 4 nibbles and timings are not in my DEM16217 SYH datasheet, but apparently are HD44780 standard... + commandWriteNibble(0x03); + delay(5); + commandWriteNibble(0x03); + delayMicroseconds(100); + commandWriteNibble(0x03); + delay(5); + + // needed by the LCDs controller + //this being 2 sets up 4-bit mode. + commandWriteNibble(0x02); + commandWriteNibble(0x02); + //todo: make configurable by the user of this library. + //NFXX where + //N = num lines (0=1 line or 1=2 lines). + //F= format (number of dots (0=5x7 or 1=5x10)). + //X=don't care + + int num_lines_ptn = g_num_lines - 1 << 3; + int dot_format_ptn = 0x00; //5x7 dots. 0x04 is 5x10 + + commandWriteNibble(num_lines_ptn | dot_format_ptn); + delayMicroseconds(60); + + //The rest of the init is not specific to 4-bit mode. + //NOTE: we're writing full bytes now, not nibbles. + + // display control: + // turn display on, cursor off, no blinking + commandWrite(0x0C); + delayMicroseconds(60); + + //clear display + commandWrite(0x01); + delay(3); + + // entry mode set: 06 + // increment automatically, display shift, entire shift off + commandWrite(0x06); + + delay(1);//TODO: remove unnecessary delays +} + + +//non-core stuff -------------------------------------- +//move the cursor to the given absolute position. line numbers start at 1. +//if this is not a 2-line LCD4Bit instance, will always position on first line. +void LCD4Bit::cursorTo(int line_num, int x){ + //first, put cursor home + commandWrite(CMD_HOME); + + //if we are on a 1-line display, set line_num to 1st line, regardless of given + if (g_num_lines==1){ + line_num = 1; + } + //offset 40 chars in if second line requested + if (line_num == 2){ + x += 40; + } + //advance the cursor to the right according to position. (second line starts at position 40). + for (int i=0; i + +class LCD4Bit { +public: + LCD4Bit(int num_lines); + void commandWrite(int value); + void init(); + void print(int value); + void printIn(char value[]); + void clear(); + //non-core--------------- + void cursorTo(int line_num, int x); + void leftScroll(int chars, int delay_time); + //end of non-core-------- + + //4bit only, therefore ideally private but may be needed by user + void commandWriteNibble(int nibble); +private: + void pulseEnablePin(); + void pushNibble(int nibble); + void pushByte(int value); +}; + +#endif diff --git a/libraries/LCD4Bit/examples/LCD4BitExample/LCD4BitExample.pde b/libraries/LCD4Bit/examples/LCD4BitExample/LCD4BitExample.pde new file mode 100644 index 0000000..e50c011 --- /dev/null +++ b/libraries/LCD4Bit/examples/LCD4BitExample/LCD4BitExample.pde @@ -0,0 +1,47 @@ +//example use of LCD4Bit library + +#include +//create object to control an LCD. +//number of lines in display=1 +LCD4Bit lcd = LCD4Bit(1); + +//some messages to display on the LCD +char msgs[6][15] = {"apple", "banana", "pineapple", "mango", "watermelon", "pear"}; +int NUM_MSGS = 6; + +void setup() { + pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat + + lcd.init(); + //optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init() + //lcd.commandWrite(0x0F);//cursor on, display on, blink on. (nasty!) +} + +void loop() { + digitalWrite(13, HIGH); //light the debug LED + + //pick a random message from the array + int pick = random(NUM_MSGS); + char* msg = msgs[pick]; + + lcd.clear(); + lcd.printIn(msg); + delay(1000); + digitalWrite(13, LOW); + + //print some dots individually + for (int i=0; i<3; i++){ + lcd.print('.'); + delay(100); + } + //print something on the display's second line. + //uncomment this if your display HAS two lines! + /* + lcd.cursorTo(2, 0); //line=2, x=0. + lcd.printIn("Score: 6/7"); + delay(1000); + */ + + //scroll entire display 20 chars to left, delaying 50ms each inc + lcd.leftScroll(20, 50); +} diff --git a/libraries/LCD4Bit/keywords.txt b/libraries/LCD4Bit/keywords.txt new file mode 100644 index 0000000..74b2d7c --- /dev/null +++ b/libraries/LCD4Bit/keywords.txt @@ -0,0 +1,27 @@ +####################################### +# Syntax Coloring Map For Matrix +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LCD4Bit KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +clear KEYWORD2 +commandWrite KEYWORD2 +cursorTo KEYWORD2 +init KEYWORD2 +leftScroll KEYWORD2 +print KEYWORD2 +printIn KEYWORD2 +commandWriteNibble KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/LCD4Bit/readme.txt b/libraries/LCD4Bit/readme.txt new file mode 100644 index 0000000..be63d33 --- /dev/null +++ b/libraries/LCD4Bit/readme.txt @@ -0,0 +1,38 @@ +This is a C++ library for Arduino for controlling an HD74800-compatible LCD in 4-bit mode. +Tested on Arduino 0005 Alpha. + +Installation +-------------------------------------------------------------------------------- + +To install this library, just place this entire folder as a subfolder in your +Arduino/lib/targets/libraries folder. + +When installed, this library should look like: + +Arduino/lib/targets/libraries/LCD4Bit (this library's folder) +Arduino/lib/targets/libraries/LCD4Bit/LCD4Bit.cpp (the library implementation file) +Arduino/lib/targets/libraries/LCD4Bit/LCD4Bit.h (the library description file) +Arduino/lib/targets/libraries/LCD4Bit/keywords.txt (the syntax coloring file) +Arduino/lib/targets/libraries/LCD4Bit/examples (the examples in the "open" menu) +Arduino/lib/targets/libraries/LCD4Bit/readme.txt (this file) + +Building +-------------------------------------------------------------------------------- + +After this library is installed, you just have to start the Arduino application. +You may see a few warning messages as it's built. + +To use this library in a sketch, go to the Sketch | Import Library menu and +select LCD4Bit. This will add a corresponding line to the top of your sketch: +#include + +To stop using this library, delete that line from your sketch. + +Geeky information: +After a successful build of this library, a new file named "LCD4Bit.o" will appear +in "Arduino/lib/targets/libraries/LCD4Bit". This file is the built/compiled library +code. + +If you choose to modify the code for this library (i.e. "LCD4Bit.cpp" or "LCD4Bit.h"), +then you must first 'unbuild' this library by deleting the "LCD4Bit.o" file. The +new "LCD4Bit.o" with your code will appear after the next press of "verify" diff --git a/libraries/MatrixFonts3x5/MatrixFonts3x5.h b/libraries/MatrixFonts3x5/MatrixFonts3x5.h new file mode 100644 index 0000000..5eebe99 --- /dev/null +++ b/libraries/MatrixFonts3x5/MatrixFonts3x5.h @@ -0,0 +1,233 @@ + +#define A { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,0,0}, \ + {0,0,0,1,0,1,0}, \ + {0,1,1,1,1,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define B { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,1,0,1,0}, \ + {0,0,1,0,1,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define C { \ + {0,0,0,0,0,0,0}, \ + {0,0,1,1,1,0,0}, \ + {0,1,0,0,0,1,0}, \ + {0,0,1,0,1,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define D { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,0,0,1,0}, \ + {0,0,1,1,1,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define E { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,1,0,1,0}, \ + {0,1,0,0,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define F { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,1,0,1,0}, \ + {0,0,0,0,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define G { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,1,0,1,0}, \ + {0,1,1,1,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define H { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,1,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define I { \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define J { \ + {0,0,0,0,0,0,0}, \ + {0,0,1,1,0,0,0}, \ + {0,1,0,0,0,0,0}, \ + {0,0,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define K { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,1,0,0,0}, \ + {0,1,1,0,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define L { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,0,0,0,0}, \ + {0,1,0,0,0,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define M { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,1,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define N { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,1,1,1,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define O { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,0,0,1,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define P { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,1,0,1,0}, \ + {0,0,0,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define Q { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,0,0,1,0}, \ + {0,0,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define R { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,1,1,0,1,0}, \ + {0,1,0,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define S { \ + {0,0,0,0,0,0,0}, \ + {0,1,0,0,1,0,0}, \ + {0,1,0,1,0,1,0}, \ + {0,0,1,0,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define T { \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,1,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define U { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,1,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define V { \ + {0,0,0,0,0,0,0}, \ + {0,0,1,1,1,1,0}, \ + {0,1,0,0,0,0,0}, \ + {0,0,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define W { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,1,0,0,0,0}, \ + {0,1,1,1,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define X { \ + {0,0,0,0,0,0,0}, \ + {0,1,1,0,1,1,0}, \ + {0,0,0,1,0,0,0}, \ + {0,1,1,0,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define Y { \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,1,1,0}, \ + {0,1,1,1,0,0,0}, \ + {0,0,0,0,1,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define Z { \ + {0,0,0,0,0,0,0}, \ + {0,1,0,0,1,1,0}, \ + {0,1,0,1,0,1,0}, \ + {0,1,1,0,0,1,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define DASH { \ + {0,0,0,0,0,0,0}, \ + {0,0,0,1,0,0,0}, \ + {0,0,0,1,0,0,0}, \ + {0,0,0,1,0,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define SPACE { \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0} \ +} + +#define DOT { \ + {0,0,0,0,0,0,0}, \ + {0,1,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0}, \ + {0,0,0,0,0,0,0} \ +} + diff --git a/libraries/TimerOne/TimerOne.cpp b/libraries/TimerOne/TimerOne.cpp new file mode 100755 index 0000000..7a52ae0 --- /dev/null +++ b/libraries/TimerOne/TimerOne.cpp @@ -0,0 +1,101 @@ +/* + * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 + * Original code by Jesse Tane for http://labs.ideo.com August 2008 + * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support + * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop + * + * This is free software. You can redistribute it and/or modify it under + * the terms of Creative Commons Attribution 3.0 United States License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ + * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + * + */ + +#include "TimerOne.h" + +TimerOne Timer1; // preinstatiate + +ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt +{ + Timer1.isrCallback(); +} + +void TimerOne::initialize(long microseconds) +{ + TCCR1A = 0; // clear control register A + TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer + setPeriod(microseconds); +} + +void TimerOne::setPeriod(long microseconds) +{ + long cycles = (F_CPU * microseconds) / 2000000; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2 + if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8 + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024 + else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum + ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); + TCCR1B |= clockSelectBits; // reset clock select register +} + +void TimerOne::setPwmDuty(char pin, int duty) +{ + unsigned long dutyCycle = pwmPeriod; + dutyCycle *= duty; + dutyCycle >>= 10; + if(pin == 1 || pin == 9) OCR1A = dutyCycle; + else if(pin == 2 || pin == 10) OCR1B = dutyCycle; +} + +void TimerOne::pwm(char pin, int duty, long microseconds) // expects duty cycle to be 10 bit (1024) +{ + if(microseconds > 0) setPeriod(microseconds); + if(pin == 1 || pin == 9) { + DDRB |= _BV(PORTB1); // sets data direction register for pwm output pin + TCCR1A |= _BV(COM1A1); // activates the output pin + } + else if(pin == 2 || pin == 10) { + DDRB |= _BV(PORTB2); + TCCR1A |= _BV(COM1B1); + } + setPwmDuty(pin, duty); + start(); +} + +void TimerOne::disablePwm(char pin) +{ + if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1); // clear the bit that enables pwm on PB1 + else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1); // clear the bit that enables pwm on PB2 +} + +void TimerOne::attachInterrupt(void (*isr)(), long microseconds) +{ + if(microseconds > 0) setPeriod(microseconds); + isrCallback = isr; // register the user's callback with the real ISR + TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit + sei(); // ensures that interrupts are globally enabled + start(); +} + +void TimerOne::detachInterrupt() +{ + TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit +} + +void TimerOne::start() +{ + TCCR1B |= clockSelectBits; +} + +void TimerOne::stop() +{ + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); // clears all clock selects bits +} + +void TimerOne::restart() +{ + TCNT1 = 0; +} diff --git a/libraries/TimerOne/TimerOne.h b/libraries/TimerOne/TimerOne.h new file mode 100755 index 0000000..385b5c6 --- /dev/null +++ b/libraries/TimerOne/TimerOne.h @@ -0,0 +1,41 @@ +/* + * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 + * Original code by Jesse Tane for http://labs.ideo.com August 2008 + * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support + * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop + * + * This is free software. You can redistribute it and/or modify it under + * the terms of Creative Commons Attribution 3.0 United States License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ + * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + * + */ + +#include +#include + +#define RESOLUTION 65536 // Timer1 is 16 bit + +class TimerOne +{ + public: + + // properties + unsigned int pwmPeriod; + unsigned char clockSelectBits; + + // methods + void initialize(long microseconds=1000000); + void start(); + void stop(); + void restart(); + void pwm(char pin, int duty, long microseconds=-1); + void disablePwm(char pin); + void attachInterrupt(void (*isr)(), long microseconds=-1); + void detachInterrupt(); + void setPeriod(long microseconds); + void setPwmDuty(char pin, int duty); + void (*isrCallback)(); +}; + +extern TimerOne Timer1; diff --git a/libraries/etherShield/enc28j60.c b/libraries/etherShield/enc28j60.c new file mode 100644 index 0000000..d0ee9c5 --- /dev/null +++ b/libraries/etherShield/enc28j60.c @@ -0,0 +1,343 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * http://www.gnu.org/licenses/gpl.html + * + * Based on the enc28j60.c file from the AVRlib library by Pascal Stang. + * For AVRlib See http://www.procyonengineering.com/ + * Used with explicit permission of Pascal Stang. + * + * Title: Microchip ENC28J60 Ethernet Interface Driver + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ +#include +//#include "avr_compat.h" +#include "enc28j60.h" +#include "WConstants.h" //all things wiring / arduino +//#include "timeout.h" +// +//#define F_CPU 10000000UL // 12.5 MHz +/* +#ifndef ALIBC_OLD +#include +#else +#include +#endif +*/ + +static uint8_t Enc28j60Bank; +static uint16_t NextPacketPtr; + +#define ENC28J60_CONTROL_CS 10 +#define SPI_MOSI 11 +#define SPI_MISO 12 +#define SPI_SCK 13 +// set CS to 0 = active +#define CSACTIVE digitalWrite(ENC28J60_CONTROL_CS, LOW) +// set CS to 1 = passive +#define CSPASSIVE digitalWrite(ENC28J60_CONTROL_CS, HIGH) +// +#define waitspi() while(!(SPSR&(1<>5); + Enc28j60Bank = (address & BANK_MASK); + } +} + +uint8_t enc28j60Read(uint8_t address) +{ + // set the bank + enc28j60SetBank(address); + // do the read + return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); +} + +void enc28j60Write(uint8_t address, uint8_t data) +{ + // set the bank + enc28j60SetBank(address); + // do the write + enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); +} + +void enc28j60PhyWrite(uint8_t address, uint16_t data) +{ + // set the PHY register address + enc28j60Write(MIREGADR, address); + // write the PHY data + enc28j60Write(MIWRL, data); + enc28j60Write(MIWRH, data>>8); + // wait until the PHY write completes + while(enc28j60Read(MISTAT) & MISTAT_BUSY){ + delayMicroseconds(15); + } +} + +void enc28j60clkout(uint8_t clk) +{ + //setup clkout: 2 is 12.5MHz: + enc28j60Write(ECOCON, clk & 0x7); +} + +void enc28j60Init(uint8_t* macaddr) +{ + // initialize I/O + // ss as output: + pinMode(ENC28J60_CONTROL_CS, OUTPUT); + CSPASSIVE; // ss=0 + // + pinMode(SPI_MOSI, OUTPUT); + + pinMode(SPI_SCK, OUTPUT); + + pinMode(SPI_MISO, INPUT); + + + digitalWrite(SPI_MOSI, LOW); + + digitalWrite(SPI_SCK, LOW); + + /*DDRB |= 1<>8); + // set receive pointer address + enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); + enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); + // RX end + enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); + enc28j60Write(ERXNDH, RXSTOP_INIT>>8); + // TX start + enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); + enc28j60Write(ETXSTH, TXSTART_INIT>>8); + // TX end + enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF); + enc28j60Write(ETXNDH, TXSTOP_INIT>>8); + // do bank 1 stuff, packet filter: + // For broadcast packets we allow only ARP packtets + // All other packets should be unicast only for our mac (MAADR) + // + // The pattern to match on is therefore + // Type ETH.DST + // ARP BROADCAST + // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 + // in binary these poitions are:11 0000 0011 1111 + // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 + enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); + enc28j60Write(EPMM0, 0x3f); + enc28j60Write(EPMM1, 0x30); + enc28j60Write(EPMCSL, 0xf9); + enc28j60Write(EPMCSH, 0xf7); + // + // + // do bank 2 stuff + // enable MAC receive + enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); + // bring MAC out of reset + enc28j60Write(MACON2, 0x00); + // enable automatic padding to 60bytes and CRC operations + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); + // set inter-frame gap (non-back-to-back) + enc28j60Write(MAIPGL, 0x12); + enc28j60Write(MAIPGH, 0x0C); + // set inter-frame gap (back-to-back) + enc28j60Write(MABBIPG, 0x12); + // Set the maximum packet size which the controller will accept + // Do not send packets longer than MAX_FRAMELEN: + enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); + enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); + // do bank 3 stuff + // write MAC address + // NOTE: MAC address in ENC28J60 is byte-backward + enc28j60Write(MAADR5, macaddr[0]); + enc28j60Write(MAADR4, macaddr[1]); + enc28j60Write(MAADR3, macaddr[2]); + enc28j60Write(MAADR2, macaddr[3]); + enc28j60Write(MAADR1, macaddr[4]); + enc28j60Write(MAADR0, macaddr[5]); + // no loopback of transmitted frames + enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); + // switch to bank 0 + enc28j60SetBank(ECON1); + // enable interrutps + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); + // enable packet reception + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); +} + +// read the revision of the chip: +uint8_t enc28j60getrev(void) +{ + return(enc28j60Read(EREVID)); +} + +void enc28j60PacketSend(uint16_t len, uint8_t* packet) +{ + // Set the write pointer to start of transmit buffer area + enc28j60Write(EWRPTL, TXSTART_INIT&0xFF); + enc28j60Write(EWRPTH, TXSTART_INIT>>8); + // Set the TXND pointer to correspond to the packet size given + enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF); + enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); + // write per-packet control byte (0x00 means use macon3 settings) + enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); + // copy the packet into the transmit buffer + enc28j60WriteBuffer(len, packet); + // send the contents of the transmit buffer onto the network + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); + // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. + if( (enc28j60Read(EIR) & EIR_TXERIF) ){ + enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); + } +} + +// Gets a packet from the network receive buffer, if one is available. +// The packet will by headed by an ethernet header. +// maxlen The maximum acceptable length of a retrieved packet. +// packet Pointer where packet data should be stored. +// Returns: Packet length in bytes if a packet was retrieved, zero otherwise. +uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet) +{ + uint16_t rxstat; + uint16_t len; + // check if a packet has been received and buffered + //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ + // The above does not work. See Rev. B4 Silicon Errata point 6. + if( enc28j60Read(EPKTCNT) ==0 ){ + return(0); + } + + // Set the read pointer to the start of the received packet + enc28j60Write(ERDPTL, (NextPacketPtr)); + enc28j60Write(ERDPTH, (NextPacketPtr)>>8); + // read the next packet pointer + NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // read the packet length (see datasheet page 43) + len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + len-=4; //remove the CRC count + // read the receive status (see datasheet page 43) + rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); + rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; + // limit retrieve length + if (len>maxlen-1){ + len=maxlen-1; + } + // check CRC and symbol errors (see datasheet page 44, table 7-3): + // The ERXFCON.CRCEN is set by default. Normally we should not + // need to check this. + if ((rxstat & 0x80)==0){ + // invalid + len=0; + }else{ + // copy the packet from the receive buffer + enc28j60ReadBuffer(len, packet); + } + // Move the RX read pointer to the start of the next received packet + // This frees the memory we just read out + enc28j60Write(ERXRDPTL, (NextPacketPtr)); + enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8); + // decrement the packet counter indicate we are done with this packet + enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + return(len); +} + diff --git a/libraries/etherShield/enc28j60.h b/libraries/etherShield/enc28j60.h new file mode 100644 index 0000000..4573478 --- /dev/null +++ b/libraries/etherShield/enc28j60.h @@ -0,0 +1,280 @@ +/***************************************************************************** +* vim:sw=8:ts=8:si:et +* +* Title : Microchip ENC28J60 Ethernet Interface Driver +* Author : Pascal Stang (c)2005 +* Modified by Guido Socher +* Copyright: GPL V2 +* +*This driver provides initialization and transmit/receive +*functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. +*This chip is novel in that it is a full MAC+PHY interface all in a 28-pin +*chip, using an SPI interface to the host processor. +* +* +*****************************************************************************/ +/********************************************* + * Modified: nuelectronics.com -- Ethershield for Arduino + *********************************************/ +//@{ + + +#ifndef ENC28J60_H +#define ENC28J60_H +#include + +// ENC28J60 Control Registers +// Control register definitions are a combination of address, +// bank number, and Ethernet/MAC/PHY indicator bits. +// - Register address (bits 0-4) +// - Bank number (bits 5-6) +// - MAC/PHY indicator (bit 7) +#define ADDR_MASK 0x1F +#define BANK_MASK 0x60 +#define SPRD_MASK 0x80 +// All-bank registers +#define EIE 0x1B +#define EIR 0x1C +#define ESTAT 0x1D +#define ECON2 0x1E +#define ECON1 0x1F +// Bank 0 registers +#define ERDPTL (0x00|0x00) +#define ERDPTH (0x01|0x00) +#define EWRPTL (0x02|0x00) +#define EWRPTH (0x03|0x00) +#define ETXSTL (0x04|0x00) +#define ETXSTH (0x05|0x00) +#define ETXNDL (0x06|0x00) +#define ETXNDH (0x07|0x00) +#define ERXSTL (0x08|0x00) +#define ERXSTH (0x09|0x00) +#define ERXNDL (0x0A|0x00) +#define ERXNDH (0x0B|0x00) +#define ERXRDPTL (0x0C|0x00) +#define ERXRDPTH (0x0D|0x00) +#define ERXWRPTL (0x0E|0x00) +#define ERXWRPTH (0x0F|0x00) +#define EDMASTL (0x10|0x00) +#define EDMASTH (0x11|0x00) +#define EDMANDL (0x12|0x00) +#define EDMANDH (0x13|0x00) +#define EDMADSTL (0x14|0x00) +#define EDMADSTH (0x15|0x00) +#define EDMACSL (0x16|0x00) +#define EDMACSH (0x17|0x00) +// Bank 1 registers +#define EHT0 (0x00|0x20) +#define EHT1 (0x01|0x20) +#define EHT2 (0x02|0x20) +#define EHT3 (0x03|0x20) +#define EHT4 (0x04|0x20) +#define EHT5 (0x05|0x20) +#define EHT6 (0x06|0x20) +#define EHT7 (0x07|0x20) +#define EPMM0 (0x08|0x20) +#define EPMM1 (0x09|0x20) +#define EPMM2 (0x0A|0x20) +#define EPMM3 (0x0B|0x20) +#define EPMM4 (0x0C|0x20) +#define EPMM5 (0x0D|0x20) +#define EPMM6 (0x0E|0x20) +#define EPMM7 (0x0F|0x20) +#define EPMCSL (0x10|0x20) +#define EPMCSH (0x11|0x20) +#define EPMOL (0x14|0x20) +#define EPMOH (0x15|0x20) +#define EWOLIE (0x16|0x20) +#define EWOLIR (0x17|0x20) +#define ERXFCON (0x18|0x20) +#define EPKTCNT (0x19|0x20) +// Bank 2 registers +#define MACON1 (0x00|0x40|0x80) +#define MACON2 (0x01|0x40|0x80) +#define MACON3 (0x02|0x40|0x80) +#define MACON4 (0x03|0x40|0x80) +#define MABBIPG (0x04|0x40|0x80) +#define MAIPGL (0x06|0x40|0x80) +#define MAIPGH (0x07|0x40|0x80) +#define MACLCON1 (0x08|0x40|0x80) +#define MACLCON2 (0x09|0x40|0x80) +#define MAMXFLL (0x0A|0x40|0x80) +#define MAMXFLH (0x0B|0x40|0x80) +#define MAPHSUP (0x0D|0x40|0x80) +#define MICON (0x11|0x40|0x80) +#define MICMD (0x12|0x40|0x80) +#define MIREGADR (0x14|0x40|0x80) +#define MIWRL (0x16|0x40|0x80) +#define MIWRH (0x17|0x40|0x80) +#define MIRDL (0x18|0x40|0x80) +#define MIRDH (0x19|0x40|0x80) +// Bank 3 registers +#define MAADR1 (0x00|0x60|0x80) +#define MAADR0 (0x01|0x60|0x80) +#define MAADR3 (0x02|0x60|0x80) +#define MAADR2 (0x03|0x60|0x80) +#define MAADR5 (0x04|0x60|0x80) +#define MAADR4 (0x05|0x60|0x80) +#define EBSTSD (0x06|0x60) +#define EBSTCON (0x07|0x60) +#define EBSTCSL (0x08|0x60) +#define EBSTCSH (0x09|0x60) +#define MISTAT (0x0A|0x60|0x80) +#define EREVID (0x12|0x60) +#define ECOCON (0x15|0x60) +#define EFLOCON (0x17|0x60) +#define EPAUSL (0x18|0x60) +#define EPAUSH (0x19|0x60) +// PHY registers +#define PHCON1 0x00 +#define PHSTAT1 0x01 +#define PHHID1 0x02 +#define PHHID2 0x03 +#define PHCON2 0x10 +#define PHSTAT2 0x11 +#define PHIE 0x12 +#define PHIR 0x13 +#define PHLCON 0x14 + +// ENC28J60 ERXFCON Register Bit Definitions +#define ERXFCON_UCEN 0x80 +#define ERXFCON_ANDOR 0x40 +#define ERXFCON_CRCEN 0x20 +#define ERXFCON_PMEN 0x10 +#define ERXFCON_MPEN 0x08 +#define ERXFCON_HTEN 0x04 +#define ERXFCON_MCEN 0x02 +#define ERXFCON_BCEN 0x01 +// ENC28J60 EIE Register Bit Definitions +#define EIE_INTIE 0x80 +#define EIE_PKTIE 0x40 +#define EIE_DMAIE 0x20 +#define EIE_LINKIE 0x10 +#define EIE_TXIE 0x08 +#define EIE_WOLIE 0x04 +#define EIE_TXERIE 0x02 +#define EIE_RXERIE 0x01 +// ENC28J60 EIR Register Bit Definitions +#define EIR_PKTIF 0x40 +#define EIR_DMAIF 0x20 +#define EIR_LINKIF 0x10 +#define EIR_TXIF 0x08 +#define EIR_WOLIF 0x04 +#define EIR_TXERIF 0x02 +#define EIR_RXERIF 0x01 +// ENC28J60 ESTAT Register Bit Definitions +#define ESTAT_INT 0x80 +#define ESTAT_LATECOL 0x10 +#define ESTAT_RXBUSY 0x04 +#define ESTAT_TXABRT 0x02 +#define ESTAT_CLKRDY 0x01 +// ENC28J60 ECON2 Register Bit Definitions +#define ECON2_AUTOINC 0x80 +#define ECON2_PKTDEC 0x40 +#define ECON2_PWRSV 0x20 +#define ECON2_VRPS 0x08 +// ENC28J60 ECON1 Register Bit Definitions +#define ECON1_TXRST 0x80 +#define ECON1_RXRST 0x40 +#define ECON1_DMAST 0x20 +#define ECON1_CSUMEN 0x10 +#define ECON1_TXRTS 0x08 +#define ECON1_RXEN 0x04 +#define ECON1_BSEL1 0x02 +#define ECON1_BSEL0 0x01 +// ENC28J60 MACON1 Register Bit Definitions +#define MACON1_LOOPBK 0x10 +#define MACON1_TXPAUS 0x08 +#define MACON1_RXPAUS 0x04 +#define MACON1_PASSALL 0x02 +#define MACON1_MARXEN 0x01 +// ENC28J60 MACON2 Register Bit Definitions +#define MACON2_MARST 0x80 +#define MACON2_RNDRST 0x40 +#define MACON2_MARXRST 0x08 +#define MACON2_RFUNRST 0x04 +#define MACON2_MATXRST 0x02 +#define MACON2_TFUNRST 0x01 +// ENC28J60 MACON3 Register Bit Definitions +#define MACON3_PADCFG2 0x80 +#define MACON3_PADCFG1 0x40 +#define MACON3_PADCFG0 0x20 +#define MACON3_TXCRCEN 0x10 +#define MACON3_PHDRLEN 0x08 +#define MACON3_HFRMLEN 0x04 +#define MACON3_FRMLNEN 0x02 +#define MACON3_FULDPX 0x01 +// ENC28J60 MICMD Register Bit Definitions +#define MICMD_MIISCAN 0x02 +#define MICMD_MIIRD 0x01 +// ENC28J60 MISTAT Register Bit Definitions +#define MISTAT_NVALID 0x04 +#define MISTAT_SCAN 0x02 +#define MISTAT_BUSY 0x01 +// ENC28J60 PHY PHCON1 Register Bit Definitions +#define PHCON1_PRST 0x8000 +#define PHCON1_PLOOPBK 0x4000 +#define PHCON1_PPWRSV 0x0800 +#define PHCON1_PDPXMD 0x0100 +// ENC28J60 PHY PHSTAT1 Register Bit Definitions +#define PHSTAT1_PFDPX 0x1000 +#define PHSTAT1_PHDPX 0x0800 +#define PHSTAT1_LLSTAT 0x0004 +#define PHSTAT1_JBSTAT 0x0002 +// ENC28J60 PHY PHCON2 Register Bit Definitions +#define PHCON2_FRCLINK 0x4000 +#define PHCON2_TXDIS 0x2000 +#define PHCON2_JABBER 0x0400 +#define PHCON2_HDLDIS 0x0100 + +// ENC28J60 Packet Control Byte Bit Definitions +#define PKTCTRL_PHUGEEN 0x08 +#define PKTCTRL_PPADEN 0x04 +#define PKTCTRL_PCRCEN 0x02 +#define PKTCTRL_POVERRIDE 0x01 + +// SPI operation codes +#define ENC28J60_READ_CTRL_REG 0x00 +#define ENC28J60_READ_BUF_MEM 0x3A +#define ENC28J60_WRITE_CTRL_REG 0x40 +#define ENC28J60_WRITE_BUF_MEM 0x7A +#define ENC28J60_BIT_FIELD_SET 0x80 +#define ENC28J60_BIT_FIELD_CLR 0xA0 +#define ENC28J60_SOFT_RESET 0xFF + + +// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata +// buffer boundaries applied to internal 8K ram +// the entire available packet buffer space is allocated +// +// start with recbuf at 0/ +#define RXSTART_INIT 0x0 +// receive buffer end +#define RXSTOP_INIT (0x1FFF-0x0600-1) +// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes) +#define TXSTART_INIT (0x1FFF-0x0600) +// stp TX buffer at end of mem +#define TXSTOP_INIT 0x1FFF +// +// max frame length which the conroller will accept: +#define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518) +//#define MAX_FRAMELEN 600 + + +// functions +extern uint8_t enc28j60ReadOp(uint8_t op, uint8_t address); +extern void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data); +extern void enc28j60ReadBuffer(uint16_t len, uint8_t* data); +extern void enc28j60WriteBuffer(uint16_t len, uint8_t* data); +extern void enc28j60SetBank(uint8_t address); +extern uint8_t enc28j60Read(uint8_t address); +extern void enc28j60Write(uint8_t address, uint8_t data); +extern void enc28j60PhyWrite(uint8_t address, uint16_t data); +extern void enc28j60clkout(uint8_t clk); +extern void enc28j60Init(uint8_t* macaddr); +extern void enc28j60PacketSend(uint16_t len, uint8_t* packet); +extern uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet); +extern uint8_t enc28j60getrev(void); + +#endif +//@} diff --git a/libraries/etherShield/etherShield.cpp b/libraries/etherShield/etherShield.cpp new file mode 100644 index 0000000..123f69c --- /dev/null +++ b/libraries/etherShield/etherShield.cpp @@ -0,0 +1,109 @@ +// a wrapper class for EtherShield + +extern "C" { + #include "enc28j60.h" + #include "ip_arp_udp_tcp.h" + +} +#include "etherShield.h" + +//constructor +EtherShield::EtherShield(){ +} + +uint16_t EtherShield::ES_fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s){ + return fill_tcp_data_p(buf, pos, progmem_s); +} + +uint16_t EtherShield::ES_fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s){ + return fill_tcp_data(buf,pos, s); +} + + +void EtherShield::ES_enc28j60Init(uint8_t* macaddr){ + enc28j60Init(macaddr); + +} +void EtherShield::ES_enc28j60clkout(uint8_t clk){ + enc28j60clkout(clk); +} + +void EtherShield::ES_enc28j60PhyWrite(uint8_t address, uint16_t data){ + enc28j60PhyWrite(address, data); +} + +uint16_t EtherShield::ES_enc28j60PacketReceive(uint16_t len, uint8_t* packet){ + return enc28j60PacketReceive(len, packet); +} + + +void EtherShield::ES_init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp){ + init_ip_arp_udp_tcp(mymac,myip,wwwp); +} + +uint8_t EtherShield::ES_eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len){ + return eth_type_is_arp_and_my_ip(buf,len); +} + +void EtherShield::ES_make_arp_answer_from_request(uint8_t *buf){ + make_arp_answer_from_request(buf); +} + +uint8_t EtherShield::ES_eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len){ + return eth_type_is_ip_and_my_ip(buf, len); +} + + +void EtherShield::ES_make_echo_reply_from_request(uint8_t *buf,uint16_t len){ + make_echo_reply_from_request(buf,len); +} + +void EtherShield::ES_make_tcp_synack_from_syn(uint8_t *buf){ + make_tcp_synack_from_syn(buf); +} + +void EtherShield::ES_init_len_info(uint8_t *buf){ + init_len_info(buf); +} + +uint16_t EtherShield::ES_get_tcp_data_pointer(void){ + return get_tcp_data_pointer(); +} + +void EtherShield::ES_make_tcp_ack_from_any(uint8_t *buf){ + make_tcp_ack_from_any(buf); +} + +void EtherShield::ES_make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen){ + make_tcp_ack_with_data(buf,dlen); +} + +void EtherShield::ES_make_arp_request(uint8_t *buf, uint8_t *server_ip){ + make_arp_request(buf, server_ip); +} + +uint8_t EtherShield::ES_arp_packet_is_myreply_arp ( uint8_t *buf ){ + return arp_packet_is_myreply_arp (buf); +} + +void EtherShield::ES_tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, + uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip){ + + tcp_client_send_packet(buf, dest_port, src_port, flags, max_segment_size, clear_seqck, next_ack_num, dlength,dest_mac,dest_ip); +} + +uint16_t EtherShield::ES_tcp_get_dlength( uint8_t *buf ){ + return tcp_get_dlength(buf); +} + + + + + + + + + + + + diff --git a/libraries/etherShield/etherShield.h b/libraries/etherShield/etherShield.h new file mode 100644 index 0000000..a2dcc57 --- /dev/null +++ b/libraries/etherShield/etherShield.h @@ -0,0 +1,61 @@ +/* + EHTERSHIELD_H library for Arduino etherShield + Copyright (c) 2008 Xing Yu. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ETHERSHIELD_H +#define ETHERSHIELD_H + +#include +#include "enc28j60.h" +#include "ip_arp_udp_tcp.h" +#include "net.h" + + +class EtherShield +{ + public: + + EtherShield(); + uint16_t ES_fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s); + uint16_t ES_fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s); + void ES_enc28j60Init(uint8_t* macaddr); + void ES_enc28j60clkout(uint8_t clk); + void ES_enc28j60PhyWrite(uint8_t address, uint16_t data); + uint16_t ES_enc28j60PacketReceive(uint16_t len, uint8_t* packet); + void ES_init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp); + uint8_t ES_eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len); + void ES_make_arp_answer_from_request(uint8_t *buf); + uint8_t ES_eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len); + void ES_make_echo_reply_from_request(uint8_t *buf,uint16_t len); + void ES_make_tcp_synack_from_syn(uint8_t *buf); + void ES_init_len_info(uint8_t *buf); + uint16_t ES_get_tcp_data_pointer(void); + void ES_make_tcp_ack_from_any(uint8_t *buf); + void ES_make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen); + + // new web client functions + void ES_make_arp_request(uint8_t *buf, uint8_t *server_ip); + uint8_t ES_arp_packet_is_myreply_arp ( uint8_t *buf ); + void ES_tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, + uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip); + uint16_t ES_tcp_get_dlength( uint8_t *buf ); + +}; + +#endif + diff --git a/libraries/etherShield/examples/etherShield_client/etherShield_client.pde b/libraries/etherShield/examples/etherShield_client/etherShield_client.pde new file mode 100644 index 0000000..48b6f08 --- /dev/null +++ b/libraries/etherShield/examples/etherShield_client/etherShield_client.pde @@ -0,0 +1,411 @@ +#include "etherShield.h" + +// please modify the following lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = {192,168,1,88}; +static uint16_t my_port = 1200; // client port + +// client_ip - modify it when you have multiple client on the network +// for server to distinguish each ethershield client +static char client_ip[] = "192.168.1.88"; + +// server settings - modify the service ip to your own server +static uint8_t dest_ip[4]={192,168,1,4}; +static uint8_t dest_mac[6]; + +enum CLIENT_STATE +{ + IDLE, ARP_SENT, ARP_REPLY, SYNC_SENT + }; + +static CLIENT_STATE client_state; + +static uint8_t client_data_ready; + +static uint8_t syn_ack_timeout = 0; + + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; + +char sensorData[10]; + +EtherShield es=EtherShield(); + +// prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf); +int8_t analyse_cmd(char *str); +// get current temperature +#define TEMP_PIN 3 +void getCurrentTemp( char *temperature); +void client_process(void); + +void setup(){ + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + // intialize varible; + syn_ack_timeout =0; + client_data_ready = 0; + client_state = IDLE; + // initialize DS18B20 datapin + digitalWrite(TEMP_PIN, LOW); + pinMode(TEMP_PIN, INPUT); // sets the digital pin as input (logic 1) + + +} + +void loop(){ + + if(client_data_ready==0){ + delay(60000UL); // delay 60s + getCurrentTemp(sensorData); + client_data_ready = 1; + } + client_process(); + +} + +uint16_t gen_client_request(uint8_t *buf ) +{ + uint16_t plen; + byte i; + + plen= es.ES_fill_tcp_data_p(buf,0, PSTR ( "GET /ethershield_log/save.php?pwd=secret&client=" ) ); + for(i=0; client_ip[i]!='\0'; i++){ + buf[TCP_DATA_P+plen]=client_ip[i]; + plen++; + } + plen= es.ES_fill_tcp_data_p(buf,plen, PSTR ( "&status=temperature-" ) ); + for(i=0; sensorData[i]!='\0'; i++){ + + buf[TCP_DATA_P+plen]=sensorData[i]; + plen++; + } + + + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( " HTTP/1.0\r\n" )); + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Host: 192.168.1.4\r\n" )); + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "User-Agent: AVR ethernet\r\n" )); + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Accept: text/html\r\n" )); + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Keep-Alive: 300\r\n" )); + plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Connection: keep-alive\r\n\r\n" )); + + return plen; +} + +//***************************************************************************************** +// +// Function : client_process +// Description : send temparature to web server, this option is disabled by default. +// YOU MUST install webserver and server script before enable this option, +// I recommented Apache webserver and PHP script. +// More detail about Apache and PHP installation please visit http://www.avrportal.com/ +// +//***************************************************************************************** +void client_process ( void ) +{ + uint16_t plen; + uint8_t i; + + if (client_data_ready == 0) return; // nothing to send + + if(client_state == IDLE){ // initialize ARP + es.ES_make_arp_request(buf, dest_ip); + + client_state = ARP_SENT; + return; + } + + + if(client_state == ARP_SENT){ + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + // destination ip address was found on network + if ( plen!=0 ) + { + if ( es.ES_arp_packet_is_myreply_arp ( buf ) ){ + client_state = ARP_REPLY; + syn_ack_timeout=0; + return; + } + + } + delay(10); + syn_ack_timeout++; + + + if(syn_ack_timeout== 100) { //timeout, server ip not found + client_state = IDLE; + client_data_ready =0; + syn_ack_timeout=0; + return; + } + } + + + + // send SYN packet to initial connection + if(client_state == ARP_REPLY){ + // save dest mac + for(i=0; i<6; i++){ + dest_mac[i] = buf[ETH_SRC_MAC+i]; + } + + es.ES_tcp_client_send_packet ( + buf, + 80, + 1200, + TCP_FLAG_SYN_V, // flag + 1, // (bool)maximum segment size + 1, // (bool)clear sequence ack number + 0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data + 0, // tcp data length + dest_mac, + dest_ip + ); + + client_state = SYNC_SENT; + } + // get new packet + if(client_state == SYNC_SENT){ + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + // no new packet incoming + if ( plen == 0 ) + { + return; + } + + // check ip packet send to avr or not? + // accept ip packet only + if ( es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){ + return; + } + + // check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR + if ( buf [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) ) + { + + // send ACK to answer SYNACK + + es.ES_tcp_client_send_packet ( + buf, + 80, + 1200, + TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 1, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data + 0, // tcp data length + dest_mac, + dest_ip + ); + // setup http request to server + plen = gen_client_request( buf ); + // send http request packet + // send packet with PSHACK + es.ES_tcp_client_send_packet ( + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_ACK_V | TCP_FLAG_PUSH_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + plen, // tcp data length + dest_mac, + dest_ip + ); + return; + } + // after AVR send http request to server, server response by send data with PSHACK to AVR + // AVR answer by send ACK and FINACK to server + if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PUSH_V) ) + { + plen = es.ES_tcp_get_dlength( (uint8_t*)&buf ); + + // send ACK to answer PSHACK from server + es.ES_tcp_client_send_packet ( + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + plen, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, // tcp data length + dest_mac, + dest_ip + );; + // send finack to disconnect from web server + + es.ES_tcp_client_send_packet ( + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, + dest_mac, + dest_ip + ); + + return; + + } + // answer FINACK from web server by send ACK to web server + if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_FIN_V) ) + { + // send ACK with seqack = 1 + es.ES_tcp_client_send_packet( + + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, + dest_mac, + dest_ip + ); + client_state = IDLE; // return to IDLE state + client_data_ready =0; // client data sent + } + } +} + +void OneWireReset(int Pin) // reset. Should improve to act as a presence pulse +{ + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); // bring low for 500 us + delayMicroseconds(500); + pinMode(Pin, INPUT); + delayMicroseconds(500); +} + +void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first). +{ + byte n; + + for(n=8; n!=0; n--) + { + if ((d & 0x01) == 1) // test least sig bit + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(5); + pinMode(Pin, INPUT); + delayMicroseconds(60); + } + else + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(60); + pinMode(Pin, INPUT); + } + + d=d>>1; // now the next bit is in the least sig bit position. + } + +} + +byte OneWireInByte(int Pin) // read byte, least sig byte first +{ + byte d, n, b; + + for (n=0; n<8; n++) + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(5); + pinMode(Pin, INPUT); + delayMicroseconds(5); + b = digitalRead(Pin); + delayMicroseconds(50); + d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position + } + return(d); +} + + +void getCurrentTemp(char *temp) +{ + int HighByte, LowByte, TReading, Tc_100, sign, whole, fract; + + OneWireReset(TEMP_PIN); + OneWireOutByte(TEMP_PIN, 0xcc); + OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec + + OneWireReset(TEMP_PIN); + OneWireOutByte(TEMP_PIN, 0xcc); + OneWireOutByte(TEMP_PIN, 0xbe); + + LowByte = OneWireInByte(TEMP_PIN); + HighByte = OneWireInByte(TEMP_PIN); + TReading = (HighByte << 8) + LowByte; + sign = TReading & 0x8000; // test most sig bit + if (sign) // negative + { + TReading = (TReading ^ 0xffff) + 1; // 2's comp + } + Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 + + whole = Tc_100 / 100; // separate off the whole and fractional portions + fract = Tc_100 % 100; + + if(sign) temp[0]='-'; + else temp[0]='+'; + + + temp[1]= (whole-(whole/100)*100)/10 +'0' ; + temp[2]= whole-(whole/10)*10 +'0'; + + temp[3]='.'; + temp[4]=fract/10 +'0'; + temp[5]=fract-(fract/10)*10 +'0'; + + temp[6] = '\0'; +} diff --git a/libraries/etherShield/examples/etherShield_client1/etherShield_client1.pde b/libraries/etherShield/examples/etherShield_client1/etherShield_client1.pde new file mode 100644 index 0000000..2fcac13 --- /dev/null +++ b/libraries/etherShield/examples/etherShield_client1/etherShield_client1.pde @@ -0,0 +1,333 @@ +#include "etherShield.h" +/*infrared sensor setting*/ +#define INFRARED_IN 3 +#define LED_STATUS 5 +#define ENABLE_EXTERNAL1_INTERRUPT() ( EIMSK |= ( 1<< INT1 ) ) +#define DISABLE_EXTERNAL1_INTERRUPT() ( EIMSK &= ~( 1<< INT1 ) ) + +// please modify the following lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x33}; +static uint8_t myip[4] = {192,168,1,89}; +static uint16_t my_port = 1200; // client port + +// client_ip - modify it when you have multiple client on the network +// for server to distinguish each ethershield client +static char client_ip[] = "192.168.1.89"; + +// server settings - modify the service ip to your own server +static uint8_t dest_ip[4]={192,168,1,4}; +static uint8_t dest_mac[6]; + +enum CLIENT_STATE +{ + IDLE, ARP_SENT, ARP_REPLY, SYNC_SENT + }; + +static CLIENT_STATE client_state; + +static uint8_t client_data_ready; + +static uint8_t syn_ack_timeout = 0; + + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; + + + +EtherShield es=EtherShield(); + + +void setup(){ + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + // intialize varible; + syn_ack_timeout =0; + client_data_ready = 0; + client_state = IDLE; + + // infrared sensor initialization + pinMode(LED_STATUS, OUTPUT); // infrad + digitalWrite(LED_STATUS,LOW); + + + pinMode(INFRARED_IN, INPUT); + + + ENABLE_EXTERNAL1_INTERRUPT(); + // tigger at INT1 rising edge + EICRA = 0x0c; + + + SREG|=1<1 new seq,seqack with data + plen, // tcp data length + dest_mac, + dest_ip + ); + return; + } + // after AVR send http request to server, server response by send data with PSHACK to AVR + // AVR answer by send ACK and FINACK to server + if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PUSH_V) ) + { + plen = es.ES_tcp_get_dlength( (uint8_t*)&buf ); + + // send ACK to answer PSHACK from server + es.ES_tcp_client_send_packet ( + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + plen, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, // tcp data length + dest_mac, + dest_ip + );; + // send finack to disconnect from web server + + es.ES_tcp_client_send_packet ( + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, + dest_mac, + dest_ip + ); + + return; + + } + // answer FINACK from web server by send ACK to web server + if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_FIN_V) ) + { + // send ACK with seqack = 1 + es.ES_tcp_client_send_packet( + + buf, + 80, // destination port + 1200, // source port + TCP_FLAG_ACK_V, // flag + 0, // (bool)maximum segment size + 0, // (bool)clear sequence ack number + 1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data + 0, + dest_mac, + dest_ip + ); + client_state = IDLE; // return to IDLE state + client_data_ready =0; // client data sent + } + } +} + diff --git a/libraries/etherShield/examples/etherShield_ping/Makefile b/libraries/etherShield/examples/etherShield_ping/Makefile new file mode 100644 index 0000000..e7594b3 --- /dev/null +++ b/libraries/etherShield/examples/etherShield_ping/Makefile @@ -0,0 +1,239 @@ +# Arduino makefile +# +# This makefile allows you to build sketches from the command line +# without the Arduino environment (or Java). +# +# The Arduino environment does preliminary processing on a sketch before +# compiling it. If you're using this makefile instead, you'll need to do +# a few things differently: +# +# - Give your program's file a .cpp extension (e.g. foo.cpp). +# +# - Put this line at top of your code: #include +# +# - Write prototypes for all your functions (or define them before you +# call them). A prototype declares the types of parameters a +# function will take and what type of value it will return. This +# means that you can have a call to a function before the definition +# of the function. A function prototype looks like the first line of +# the function, with a semi-colon at the end. For example: +# int digitalRead(int pin); +# +# - Write a main() function for your program that returns an int, calls +# init() and setup() once (in that order), and then calls loop() +# repeatedly(): +# +# int main() +# { +# init(); +# setup(); +# +# for (;;) +# loop(); +# +# return 0; +# } +# +# Instructions for using the makefile: +# +# 1. Copy this file into the folder with your sketch. +# +# 2. Below, modify the line containing "TARGET" to refer to the name of +# of your program's file without an extension (e.g. TARGET = foo). +# +# 3. Modify the line containg "ARDUINO" to point the directory that +# contains the Arduino core (for normal Arduino installations, this +# is the hardware/cores/arduino sub-directory). +# +# 4. Modify the line containing "PORT" to refer to the filename +# representing the USB or serial connection to your Arduino board +# (e.g. PORT = /dev/tty.USB0). If the exact name of this file +# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). +# +# 5. At the command line, change to the directory containing your +# program's file and the makefile. +# +# 6. Type "make" and press enter to compile/verify your program. +# +# 7. Type "make upload", reset your Arduino board, and press enter to +# upload your program to the Arduino board. +# +# $Id$ + +PORT = /dev/tty.usbserial* +TARGET = foo +ARDUINO = arduino +SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \ +$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \ +$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \ +$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c +CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp +MCU = atmega168 +F_CPU = 16000000 +FORMAT = ihex +UPLOAD_RATE = 19200 + +# Name of this Makefile (used for "make depend"). +MAKEFILE = Makefile + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs + +OPT = s + +# Place -D or -U options here +CDEFS = -DF_CPU=$(F_CPU) +CXXDEFS = -DF_CPU=$(F_CPU) + +# Place -I options here +CINCS = -I$(ARDUINO) +CXXINCS = -I$(ARDUINO) + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 +CDEBUG = -g$(DEBUG) +CWARN = -Wall -Wstrict-prototypes +CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) + +CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) +CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT) +#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +LDFLAGS = -lm + + +# Programming support using avrdude. Settings and variables. +AVRDUDE_PROGRAMMER = stk500 +AVRDUDE_PORT = $(PORT) +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ + -b $(UPLOAD_RATE) + +# Program settings +CC = avr-gcc +CXX = avr-g++ +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +AR = avr-ar +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +MV = mv -f + +# Define all object files. +OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: build + +build: elf hex + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + +# Program the device. +upload: $(TARGET).hex + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + $(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof + + +.SUFFIXES: .elf .hex .eep .lss .sym + +.elf.hex: + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +.elf.eep: + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +.elf.lss: + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +.elf.sym: + $(NM) -n $< > $@ + + +core.a: $(OBJ) + @for i in $(OBJ); do echo $(AR) rcs core.a $$i; $(AR) rcs core.a $$i; done + +# Link: create ELF output file from library. +$(TARGET).elf: core.a + $(CC) $(ALL_CFLAGS) -o $@ $(TARGET).cpp -L. core.a $(LDFLAGS) -Map=$(TARGET).map + +# Compile: create object files from C++ source files. +.cpp.o: + $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ + +# Compile: create object files from C source files. +.c.o: + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +.c.s: + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +.S.o: + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: + $(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \ + $(TARGET).map $(TARGET).sym $(TARGET).lss core.a \ + $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) + +depend: + if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ + then \ + sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ + $(MAKEFILE).$$$$ && \ + $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ + fi + echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ + >> $(MAKEFILE); \ + $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE) + +.PHONY: all build elf hex eep lss sym program coff extcoff clean depend diff --git a/libraries/etherShield/examples/etherShield_ping/etherShield_ping.pde b/libraries/etherShield/examples/etherShield_ping/etherShield_ping.pde new file mode 100644 index 0000000..07b6745 --- /dev/null +++ b/libraries/etherShield/examples/etherShield_ping/etherShield_ping.pde @@ -0,0 +1,87 @@ +#include "etherShield.h" + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = { + 0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = { + 192,168,1,15}; +// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX + +#define BUFFER_SIZE 250 +unsigned char buf[BUFFER_SIZE+1]; + +uint16_t plen; + +EtherShield es=EtherShield(); + + +void setup(){ + + + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=green LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + +} + +void loop(){ + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will be unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + } + // check if ip packets (icmp or udp) are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)!=0){ + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + // a ping packet, let's send pong + + es.ES_make_echo_reply_from_request(buf,plen); + } + } + + } +} diff --git a/libraries/etherShield/examples/etherShield_web_switch/etherShield_web_switch.pde b/libraries/etherShield/examples/etherShield_web_switch/etherShield_web_switch.pde new file mode 100644 index 0000000..37abbc4 --- /dev/null +++ b/libraries/etherShield/examples/etherShield_web_switch/etherShield_web_switch.pde @@ -0,0 +1,229 @@ +#include "etherShield.h" + + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = {192,168,1,15}; +static char baseurl[]="http://192.168.1.15/"; +static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254) + + + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; +#define STR_BUFFER_SIZE 22 +static char strbuf[STR_BUFFER_SIZE+1]; + +EtherShield es=EtherShield(); + +// prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf, byte on_off); +int8_t analyse_cmd(char *str); + +// LED cathode connects the Pin4, anode to 5V through 1K resistor +#define LED_PIN 4 + + +void setup(){ + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); // switch on LED +} + +void loop(){ + uint16_t plen, dat_p; + int8_t cmd; + byte on_off = 1; + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will ne unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + + // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address. + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + return; + } + + // check if ip packets are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){ + return; + } + + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + es.ES_make_echo_reply_from_request(buf,plen); + return; + } + + // tcp port www start, compare only the lower byte + if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport){ + if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){ + es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack + return; + } + if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){ + es.ES_init_len_info(buf); // init some data structures + dat_p=es.ES_get_tcp_data_pointer(); + if (dat_p==0){ // we can possibly have no data, just ack: + if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){ + es.ES_make_tcp_ack_from_any(buf); + } + return; + } + if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ + // head, post and other methods for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); + goto SENDTCP; + } + if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ + plen=print_webpage(buf, on_off); + goto SENDTCP; + } + cmd=analyse_cmd((char *)&(buf[dat_p+5])); + + if (cmd==2){ + on_off=1; + digitalWrite(LED_PIN, LOW); // switch on LED + } + else if (cmd==3){ + on_off=0; + digitalWrite(LED_PIN, HIGH); // switch off LED + } + plen=print_webpage(buf, on_off); + + plen=print_webpage(buf, on_off); +SENDTCP: es.ES_make_tcp_ack_from_any(buf); // send ack for http get + es.ES_make_tcp_ack_with_data(buf,plen); // send data + } + } + } + +} +// The returned value is stored in the global var strbuf +uint8_t find_key_val(char *str,char *key) +{ + uint8_t found=0; + uint8_t i=0; + char *kp; + kp=key; + while(*str && *str!=' ' && found==0){ + if (*str == *kp){ + kp++; + if (*kp == '\0'){ + str++; + kp=key; + if (*str == '='){ + found=1; + } + } + }else{ + kp=key; + } + str++; + } + if (found==1){ + // copy the value to a buffer and terminate it with '\0' + while(*str && *str!=' ' && *str!='&' && i 0x2f){ + // is a ASCII number, return it + r=(*strbuf-0x30); + } + } + return r; +} + + +uint16_t print_webpage(uint8_t *buf, byte on_off) +{ + + int i=0; + + + uint16_t plen; + + + + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

Welcome to Arduino Ethernet Shield V1.0

")); + + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

REMOTE LED is

")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

")); + + if(on_off) + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("ON")); + else + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("OFF")); + + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("


") ); + + if(on_off){ + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("
")); + } + else { + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("")); + } + + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

V1.0 www.nuelectronics.com")); + + return(plen); +} + diff --git a/libraries/etherShield/examples/etherShield_web_temperature/etherShield_web_temperature.pde b/libraries/etherShield/examples/etherShield_web_temperature/etherShield_web_temperature.pde new file mode 100644 index 0000000..537b3da --- /dev/null +++ b/libraries/etherShield/examples/etherShield_web_temperature/etherShield_web_temperature.pde @@ -0,0 +1,317 @@ +#include "etherShield.h" + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = {192,168,1,15}; +static char baseurl[]="http://192.168.1.15/"; +static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254) +// or on a different port: +//static char baseurl[]="http://10.0.0.24:88/"; +//static uint16_t mywwwport =88; // listen port for tcp/www (max range 1-254) +// + + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; +#define STR_BUFFER_SIZE 22 +static char strbuf[STR_BUFFER_SIZE+1]; + +EtherShield es=EtherShield(); + +// prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf); +int8_t analyse_cmd(char *str); +// get current temperature +#define TEMP_PIN 3 +void getCurrentTemp( int *sign, int *whole, int *fract); + +void setup(){ + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + // initialize DS18B20 datapin + digitalWrite(TEMP_PIN, LOW); + pinMode(TEMP_PIN, INPUT); // sets the digital pin as input (logic 1) + + +} + +void loop(){ + uint16_t plen, dat_p; + int8_t cmd; + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will ne unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + + // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address. + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + return; + } + + // check if ip packets are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){ + return; + } + + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + es.ES_make_echo_reply_from_request(buf,plen); + return; + } + + // tcp port www start, compare only the lower byte + if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport){ + if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){ + es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack + return; + } + if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){ + es.ES_init_len_info(buf); // init some data structures + dat_p=es.ES_get_tcp_data_pointer(); + if (dat_p==0){ // we can possibly have no data, just ack: + if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){ + es.ES_make_tcp_ack_from_any(buf); + } + return; + } + if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ + // head, post and other methods for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); + goto SENDTCP; + } + if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ + plen=print_webpage(buf); + goto SENDTCP; + } + cmd=analyse_cmd((char *)&(buf[dat_p+5])); + if (cmd==1){ + plen=print_webpage(buf); + } +SENDTCP: es.ES_make_tcp_ack_from_any(buf); // send ack for http get + es.ES_make_tcp_ack_with_data(buf,plen); // send data + } + } + } + +} +// The returned value is stored in the global var strbuf +uint8_t find_key_val(char *str,char *key) +{ + uint8_t found=0; + uint8_t i=0; + char *kp; + kp=key; + while(*str && *str!=' ' && found==0){ + if (*str == *kp){ + kp++; + if (*kp == '\0'){ + str++; + kp=key; + if (*str == '='){ + found=1; + } + } + }else{ + kp=key; + } + str++; + } + if (found==1){ + // copy the value to a buffer and terminate it with '\0' + while(*str && *str!=' ' && *str!='&' && i 0x2f){ + // is a ASCII number, return it + r=(*strbuf-0x30); + } + } + return r; +} + + +uint16_t print_webpage(uint8_t *buf) +{ + char temp_string[10]; + int i=0; + //char *temp_string="100"; + + uint16_t plen; + + getCurrentTemp(temp_string); + + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

Welcome to Arduino Ethernet Shield V1.0

")); + + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

Current Temperature is

")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

")); + + + while (temp_string[i]) { + buf[TCP_CHECKSUM_L_P+3+plen]=temp_string[i++]; + plen++; + } + + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(" °C


") ); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("
")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

V1.0 www.nuelectronics.com")); + + return(plen); +} + + +void OneWireReset(int Pin) // reset. Should improve to act as a presence pulse +{ + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); // bring low for 500 us + delayMicroseconds(500); + pinMode(Pin, INPUT); + delayMicroseconds(500); +} + +void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first). +{ + byte n; + + for(n=8; n!=0; n--) + { + if ((d & 0x01) == 1) // test least sig bit + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(5); + pinMode(Pin, INPUT); + delayMicroseconds(60); + } + else + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(60); + pinMode(Pin, INPUT); + } + + d=d>>1; // now the next bit is in the least sig bit position. + } + +} + +byte OneWireInByte(int Pin) // read byte, least sig byte first +{ + byte d, n, b; + + for (n=0; n<8; n++) + { + digitalWrite(Pin, LOW); + pinMode(Pin, OUTPUT); + delayMicroseconds(5); + pinMode(Pin, INPUT); + delayMicroseconds(5); + b = digitalRead(Pin); + delayMicroseconds(50); + d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position + } + return(d); +} + + +void getCurrentTemp(char *temp) +{ + int HighByte, LowByte, TReading, Tc_100, sign, whole, fract; + + OneWireReset(TEMP_PIN); + OneWireOutByte(TEMP_PIN, 0xcc); + OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec + + OneWireReset(TEMP_PIN); + OneWireOutByte(TEMP_PIN, 0xcc); + OneWireOutByte(TEMP_PIN, 0xbe); + + LowByte = OneWireInByte(TEMP_PIN); + HighByte = OneWireInByte(TEMP_PIN); + TReading = (HighByte << 8) + LowByte; + sign = TReading & 0x8000; // test most sig bit + if (sign) // negative + { + TReading = (TReading ^ 0xffff) + 1; // 2's comp + } + Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 + + whole = Tc_100 / 100; // separate off the whole and fractional portions + fract = Tc_100 % 100; + + + if(sign) temp[0]='-'; + else temp[0]='+'; + + if(whole/100==0) + temp[1] =' '; + else + temp[1]= whole/100+'0'; + temp[2]= (whole-(whole/100)*100)/10 +'0' ; + temp[3]= whole-(whole/10)*10 +'0'; + + temp[4]='.'; + temp[5]=fract/10 +'0'; + temp[6]=fract-(fract/10)*10 +'0'; + + temp[7] = '\0'; + + + +} diff --git a/libraries/etherShield/examples/etherShield_webserver/ethershield_webserver.pde b/libraries/etherShield/examples/etherShield_webserver/ethershield_webserver.pde new file mode 100644 index 0000000..edcf26d --- /dev/null +++ b/libraries/etherShield/examples/etherShield_webserver/ethershield_webserver.pde @@ -0,0 +1,187 @@ +#include "etherShield.h" + +// please modify the following two lines. mac and ip have to be unique +// in your local area network. You can not have the same numbers in +// two devices: +static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; +static uint8_t myip[4] = {192,168,1,15}; +static char baseurl[]="http://192.168.1.15/"; +static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254) +// or on a different port: +//static char baseurl[]="http://10.0.0.24:88/"; +//static uint16_t mywwwport =88; // listen port for tcp/www (max range 1-254) +// + +#define BUFFER_SIZE 500 +static uint8_t buf[BUFFER_SIZE+1]; +#define STR_BUFFER_SIZE 22 +static char strbuf[STR_BUFFER_SIZE+1]; + +EtherShield es=EtherShield(); + +// prepare the webpage by writing the data to the tcp send buffer +uint16_t print_webpage(uint8_t *buf); +int8_t analyse_cmd(char *str); +void setup(){ + + /*initialize enc28j60*/ + es.ES_enc28j60Init(mymac); + es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz + delay(10); + + /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ + // LEDA=greed LEDB=yellow + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x880 is PHLCON LEDB=on, LEDA=on + // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x880); + delay(500); + // + // 0x990 is PHLCON LEDB=off, LEDA=off + // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00); + es.ES_enc28j60PhyWrite(PHLCON,0x990); + delay(500); + // + // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit + // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); + es.ES_enc28j60PhyWrite(PHLCON,0x476); + delay(100); + + //init the ethernet/ip layer: + es.ES_init_ip_arp_udp_tcp(mymac,myip,80); + + +} + +void loop(){ + uint16_t plen, dat_p; + int8_t cmd; + + plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); + + /*plen will ne unequal to zero if there is a valid packet (without crc error) */ + if(plen!=0){ + + // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address. + if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){ + es.ES_make_arp_answer_from_request(buf); + return; + } + + // check if ip packets are for us: + if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){ + return; + } + + if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ + es.ES_make_echo_reply_from_request(buf,plen); + return; + } + + // tcp port www start, compare only the lower byte + if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport){ + if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){ + es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack + return; + } + if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){ + es.ES_init_len_info(buf); // init some data structures + dat_p=es.ES_get_tcp_data_pointer(); + if (dat_p==0){ // we can possibly have no data, just ack: + if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){ + es.ES_make_tcp_ack_from_any(buf); + } + return; + } + if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ + // head, post and other methods for possible status codes see: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); + goto SENDTCP; + } + if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ + plen=print_webpage(buf); + goto SENDTCP; + } + cmd=analyse_cmd((char *)&(buf[dat_p+5])); + if (cmd==1){ + plen=print_webpage(buf); + } +SENDTCP: es.ES_make_tcp_ack_from_any(buf); // send ack for http get + es.ES_make_tcp_ack_with_data(buf,plen); // send data + } + } + } + +} +// The returned value is stored in the global var strbuf +uint8_t find_key_val(char *str,char *key) +{ + uint8_t found=0; + uint8_t i=0; + char *kp; + kp=key; + while(*str && *str!=' ' && found==0){ + if (*str == *kp){ + kp++; + if (*kp == '\0'){ + str++; + kp=key; + if (*str == '='){ + found=1; + } + } + }else{ + kp=key; + } + str++; + } + if (found==1){ + // copy the value to a buffer and terminate it with '\0' + while(*str && *str!=' ' && *str!='&' && i 0x2f){ + // is a ASCII number, return it + r=(*strbuf-0x30); + } + } + return r; +} + + +uint16_t print_webpage(uint8_t *buf) +{ + uint16_t plen; + plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

Welcome to Arduino Ethernet Shield V1.0

")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

-- Put your ARDUINO online -- ")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("
Control digital outputs ")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("
Read digital analog inputs HERE ")); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

") ); + plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

V1.0
www.nuelectronics.com")); + + return(plen); + } \ No newline at end of file diff --git a/libraries/etherShield/ip_arp_udp_tcp.c b/libraries/etherShield/ip_arp_udp_tcp.c new file mode 100644 index 0000000..046d26f --- /dev/null +++ b/libraries/etherShield/ip_arp_udp_tcp.c @@ -0,0 +1,714 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * + * Author: Guido Socher + * Copyright: GPL V2 + * See http://www.gnu.org/licenses/gpl.html + * + * IP, Arp, UDP and TCP functions. + * + * The TCP implementation uses some size optimisations which are valid + * only if all data can be sent in one single packet. This is however + * not a big limitation for a microcontroller as you will anyhow use + * small web-pages. The TCP stack is therefore a SDP-TCP stack (single data packet TCP). + * + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ + /********************************************* + * Modified: nuelectronics.com -- Ethershield for Arduino + *********************************************/ +#include +#include +//#include "avr_compat.h" +#include "net.h" +#include "enc28j60.h" + +static uint8_t wwwport=80; +static uint8_t macaddr[6]; +static uint8_t ipaddr[4]; +static int16_t info_hdr_len=0; +static int16_t info_data_len=0; +static uint8_t seqnum=0xa; // my initial tcp sequence number + +// The Ip checksum is calculated over the ip header only starting +// with the header length field and a total length of 20 bytes +// unitl ip.dst +// You must set the IP checksum field to zero before you start +// the calculation. +// len for ip is 20. +// +// For UDP/TCP we do not make up the required pseudo header. Instead we +// use the ip.src and ip.dst fields of the real packet: +// The udp checksum calculation starts with the ip.src field +// Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len +// In other words the len here is 8 + length over which you actually +// want to calculate the checksum. +// You must set the checksum field to zero before you start +// the calculation. +// len for udp is: 8 + 8 + data length +// len for tcp is: 4+4 + 20 + option len + data length +// +// For more information on how this algorithm works see: +// http://www.netfor2.com/checksum.html +// http://www.msc.uky.edu/ken/cs471/notes/chap3.htm +// The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.html +uint16_t checksum(uint8_t *buf, uint16_t len,uint8_t type){ + // type 0=ip + // 1=udp + // 2=tcp + uint32_t sum = 0; + + //if(type==0){ + // // do not add anything + //} + if(type==1){ + sum+=IP_PROTO_UDP_V; // protocol udp + // the length here is the length of udp (data+header len) + // =length given to this function - (IP.scr+IP.dst length) + sum+=len-8; // = real tcp len + } + if(type==2){ + sum+=IP_PROTO_TCP_V; + // the length here is the length of tcp (data+header len) + // =length given to this function - (IP.scr+IP.dst length) + sum+=len-8; // = real tcp len + } + // build the sum of 16bit words + while(len >1){ + sum += 0xFFFF & (*buf<<8|*(buf+1)); + buf+=2; + len-=2; + } + // if there is a byte left then add it (padded with zero) + if (len){ + sum += (0xFF & *buf)<<8; + } + // now calculate the sum over the bytes in the sum + // until the result is only 16bit long + while (sum>>16){ + sum = (sum & 0xFFFF)+(sum >> 16); + } + // build 1's complement: + return( (uint16_t) sum ^ 0xFFFF); +} + +// you must call this function once before you use any of the other functions: +void init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp){ + uint8_t i=0; + wwwport=wwwp; + while(i<4){ + ipaddr[i]=myip[i]; + i++; + } + i=0; + while(i<6){ + macaddr[i]=mymac[i]; + i++; + } +} + +uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len){ + uint8_t i=0; + // + if (len<41){ + return(0); + } + if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || + buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V){ + return(0); + } + while(i<4){ + if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i]){ + return(0); + } + i++; + } + return(1); +} + +uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len){ + uint8_t i=0; + //eth+ip+udp header is 42 + if (len<42){ + return(0); + } + if(buf[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V || + buf[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V){ + return(0); + } + if (buf[IP_HEADER_LEN_VER_P]!=0x45){ + // must be IP V4 and 20 byte header + return(0); + } + while(i<4){ + if(buf[IP_DST_P+i]!=ipaddr[i]){ + return(0); + } + i++; + } + return(1); +} +// make a return eth header from a received eth packet +void make_eth(uint8_t *buf) +{ + uint8_t i=0; + // + //copy the destination mac from the source and fill my mac into src + while(i<6){ + buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i]; + buf[ETH_SRC_MAC +i]=macaddr[i]; + i++; + } +} + +// make a new eth header for IP packet +void make_eth_ip_new(uint8_t *buf, uint8_t* dst_mac) +{ + uint8_t i=0; + // + //copy the destination mac from the source and fill my mac into src + while(i<6){ + buf[ETH_DST_MAC +i]=dst_mac[i]; + buf[ETH_SRC_MAC +i]=macaddr[i]; + i++; + } + + buf[ ETH_TYPE_H_P ] = ETHTYPE_IP_H_V; + buf[ ETH_TYPE_L_P ] = ETHTYPE_IP_L_V; +} + + +void fill_ip_hdr_checksum(uint8_t *buf) +{ + uint16_t ck; + // clear the 2 byte checksum + buf[IP_CHECKSUM_P]=0; + buf[IP_CHECKSUM_P+1]=0; + buf[IP_FLAGS_P]=0x40; // don't fragment + buf[IP_FLAGS_P+1]=0; // fragement offset + buf[IP_TTL_P]=64; // ttl + // calculate the checksum: + ck=checksum(&buf[IP_P], IP_HEADER_LEN,0); + buf[IP_CHECKSUM_P]=ck>>8; + buf[IP_CHECKSUM_P+1]=ck& 0xff; +} + +static uint16_t ip_identifier = 1; + +// make a new ip header for tcp packet + +// make a return ip header from a received ip packet +void make_ip_tcp_new(uint8_t *buf, uint16_t len,uint8_t *dst_ip) +{ + uint8_t i=0; + + // set ipv4 and header length + buf[ IP_P ] = IP_V4_V | IP_HEADER_LENGTH_V; + + // set TOS to default 0x00 + buf[ IP_TOS_P ] = 0x00; + + // set total length + buf[ IP_TOTLEN_H_P ] = (len >>8)& 0xff; + buf[ IP_TOTLEN_L_P ] = len & 0xff; + + // set packet identification + buf[ IP_ID_H_P ] = (ip_identifier >>8) & 0xff; + buf[ IP_ID_L_P ] = ip_identifier & 0xff; + ip_identifier++; + + // set fragment flags + buf[ IP_FLAGS_H_P ] = 0x00; + buf[ IP_FLAGS_L_P ] = 0x00; + + // set Time To Live + buf[ IP_TTL_P ] = 128; + + // set ip packettype to tcp/udp/icmp... + buf[ IP_PROTO_P ] = IP_PROTO_TCP_V; + + // set source and destination ip address + while(i<4){ + buf[IP_DST_P+i]=dst_ip[i]; + buf[IP_SRC_P+i]=ipaddr[i]; + i++; + } + fill_ip_hdr_checksum(buf); +} + + +// make a return ip header from a received ip packet +void make_ip(uint8_t *buf) +{ + uint8_t i=0; + while(i<4){ + buf[IP_DST_P+i]=buf[IP_SRC_P+i]; + buf[IP_SRC_P+i]=ipaddr[i]; + i++; + } + fill_ip_hdr_checksum(buf); +} + +// make a return tcp header from a received tcp packet +// rel_ack_num is how much we must step the seq number received from the +// other side. We do not send more than 255 bytes of text (=data) in the tcp packet. +// If mss=1 then mss is included in the options list +// +// After calling this function you can fill in the first data byte at TCP_OPTIONS_P+4 +// If cp_seq=0 then an initial sequence number is used (should be use in synack) +// otherwise it is copied from the packet we received +void make_tcphead(uint8_t *buf,uint16_t rel_ack_num,uint8_t mss,uint8_t cp_seq) +{ + uint8_t i=0; + uint8_t tseq; + while(i<2){ + buf[TCP_DST_PORT_H_P+i]=buf[TCP_SRC_PORT_H_P+i]; + buf[TCP_SRC_PORT_H_P+i]=0; // clear source port + i++; + } + // set source port (http): + buf[TCP_SRC_PORT_L_P]=wwwport; + i=4; + // sequence numbers: + // add the rel ack num to SEQACK + while(i>0){ + rel_ack_num=buf[TCP_SEQ_H_P+i-1]+rel_ack_num; + tseq=buf[TCP_SEQACK_H_P+i-1]; + buf[TCP_SEQACK_H_P+i-1]=0xff&rel_ack_num; + if (cp_seq){ + // copy the acknum sent to us into the sequence number + buf[TCP_SEQ_H_P+i-1]=tseq; + }else{ + buf[TCP_SEQ_H_P+i-1]= 0; // some preset vallue + } + rel_ack_num=rel_ack_num>>8; + i--; + } + if (cp_seq==0){ + // put inital seq number + buf[TCP_SEQ_H_P+0]= 0; + buf[TCP_SEQ_H_P+1]= 0; + // we step only the second byte, this allows us to send packts + // with 255 bytes or 512 (if we step the initial seqnum by 2) + buf[TCP_SEQ_H_P+2]= seqnum; + buf[TCP_SEQ_H_P+3]= 0; + // step the inititial seq num by something we will not use + // during this tcp session: + seqnum+=2; + } + // zero the checksum + buf[TCP_CHECKSUM_H_P]=0; + buf[TCP_CHECKSUM_L_P]=0; + + // The tcp header length is only a 4 bit field (the upper 4 bits). + // It is calculated in units of 4 bytes. + // E.g 24 bytes: 24/4=6 => 0x60=header len field + //buf[TCP_HEADER_LEN_P]=(((TCP_HEADER_LEN_PLAIN+4)/4)) <<4; // 0x60 + if (mss){ + // the only option we set is MSS to 1408: + // 1408 in hex is 0x580 + buf[TCP_OPTIONS_P]=2; + buf[TCP_OPTIONS_P+1]=4; + buf[TCP_OPTIONS_P+2]=0x05; + buf[TCP_OPTIONS_P+3]=0x80; + // 24 bytes: + buf[TCP_HEADER_LEN_P]=0x60; + }else{ + // no options: + // 20 bytes: + buf[TCP_HEADER_LEN_P]=0x50; + } +} + + + + +void make_arp_answer_from_request(uint8_t *buf) +{ + uint8_t i=0; + // + make_eth(buf); + buf[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V; + buf[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V; + // fill the mac addresses: + while(i<6){ + buf[ETH_ARP_DST_MAC_P+i]=buf[ETH_ARP_SRC_MAC_P+i]; + buf[ETH_ARP_SRC_MAC_P+i]=macaddr[i]; + i++; + } + i=0; + while(i<4){ + buf[ETH_ARP_DST_IP_P+i]=buf[ETH_ARP_SRC_IP_P+i]; + buf[ETH_ARP_SRC_IP_P+i]=ipaddr[i]; + i++; + } + // eth+arp is 42 bytes: + enc28j60PacketSend(42,buf); +} + +void make_echo_reply_from_request(uint8_t *buf,uint16_t len) +{ + make_eth(buf); + make_ip(buf); + buf[ICMP_TYPE_P]=ICMP_TYPE_ECHOREPLY_V; + // we changed only the icmp.type field from request(=8) to reply(=0). + // we can therefore easily correct the checksum: + if (buf[ICMP_CHECKSUM_P] > (0xff-0x08)){ + buf[ICMP_CHECKSUM_P+1]++; + } + buf[ICMP_CHECKSUM_P]+=0x08; + // + enc28j60PacketSend(len,buf); +} + +// you can send a max of 220 bytes of data +void make_udp_reply_from_request(uint8_t *buf,char *data,uint8_t datalen,uint16_t port) +{ + uint8_t i=0; + uint16_t ck; + make_eth(buf); + if (datalen>220){ + datalen=220; + } + // total length field in the IP header must be set: + buf[IP_TOTLEN_H_P]=0; + buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+UDP_HEADER_LEN+datalen; + make_ip(buf); + buf[UDP_DST_PORT_H_P]=port>>8; + buf[UDP_DST_PORT_L_P]=port & 0xff; + // source port does not matter and is what the sender used. + // calculte the udp length: + buf[UDP_LEN_H_P]=0; + buf[UDP_LEN_L_P]=UDP_HEADER_LEN+datalen; + // zero the checksum + buf[UDP_CHECKSUM_H_P]=0; + buf[UDP_CHECKSUM_L_P]=0; + // copy the data: + while(i>8; + buf[UDP_CHECKSUM_L_P]=ck& 0xff; + enc28j60PacketSend(UDP_HEADER_LEN+IP_HEADER_LEN+ETH_HEADER_LEN+datalen,buf); +} + +void make_tcp_synack_from_syn(uint8_t *buf) +{ + uint16_t ck; + make_eth(buf); + // total length field in the IP header must be set: + // 20 bytes IP + 24 bytes (20tcp+4tcp options) + buf[IP_TOTLEN_H_P]=0; + buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4; + make_ip(buf); + buf[TCP_FLAG_P]=TCP_FLAGS_SYNACK_V; + make_tcphead(buf,1,1,0); + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + 4 (one option: mss) + ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+4,2); + buf[TCP_CHECKSUM_H_P]=ck>>8; + buf[TCP_CHECKSUM_L_P]=ck& 0xff; + // add 4 for option mss: + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4+ETH_HEADER_LEN,buf); +} + +// get a pointer to the start of tcp data in buf +// Returns 0 if there is no data +// You must call init_len_info once before calling this function +uint16_t get_tcp_data_pointer(void) +{ + if (info_data_len){ + return((uint16_t)TCP_SRC_PORT_H_P+info_hdr_len); + }else{ + return(0); + } +} + +// do some basic length calculations and store the result in static varibales +void init_len_info(uint8_t *buf) +{ + info_data_len=(buf[IP_TOTLEN_H_P]<<8)|(buf[IP_TOTLEN_L_P]&0xff); + info_data_len-=IP_HEADER_LEN; + info_hdr_len=(buf[TCP_HEADER_LEN_P]>>4)*4; // generate len in bytes; + info_data_len-=info_hdr_len; + if (info_data_len<=0){ + info_data_len=0; + } +} + +// fill in tcp data at position pos. pos=0 means start of +// tcp data. Returns the position at which the string after +// this string could be filled. +uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s) +{ + char c; + // fill in tcp data at position pos + // + // with no options the data starts after the checksum + 2 more bytes (urgent ptr) + while ((c = pgm_read_byte(progmem_s++))) { + buf[TCP_CHECKSUM_L_P+3+pos]=c; + pos++; + } + return(pos); +} + +// fill in tcp data at position pos. pos=0 means start of +// tcp data. Returns the position at which the string after +// this string could be filled. +uint16_t fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s) +{ + // fill in tcp data at position pos + // + // with no options the data starts after the checksum + 2 more bytes (urgent ptr) + while (*s) { + buf[TCP_CHECKSUM_L_P+3+pos]=*s; + pos++; + s++; + } + return(pos); +} + +// Make just an ack packet with no tcp data inside +// This will modify the eth/ip/tcp header +void make_tcp_ack_from_any(uint8_t *buf) +{ + uint16_t j; + make_eth(buf); + // fill the header: + buf[TCP_FLAG_P]=TCP_FLAG_ACK_V; + if (info_data_len==0){ + // if there is no data then we must still acknoledge one packet + make_tcphead(buf,1,0,1); // no options + }else{ + make_tcphead(buf,info_data_len,0,1); // no options + } + + // total length field in the IP header must be set: + // 20 bytes IP + 20 bytes tcp (when no options) + j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN; + buf[IP_TOTLEN_H_P]=j>>8; + buf[IP_TOTLEN_L_P]=j& 0xff; + make_ip(buf); + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len + j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN,2); + buf[TCP_CHECKSUM_H_P]=j>>8; + buf[TCP_CHECKSUM_L_P]=j& 0xff; + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+ETH_HEADER_LEN,buf); +} + +// you must have called init_len_info at some time before calling this function +// dlen is the amount of tcp data (http data) we send in this packet +// You can use this function only immediately after make_tcp_ack_from_any +// This is because this function will NOT modify the eth/ip/tcp header except for +// length and checksum +void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen) +{ + uint16_t j; + // fill the header: + // This code requires that we send only one data packet + // because we keep no state information. We must therefore set + // the fin here: + buf[TCP_FLAG_P]=TCP_FLAG_ACK_V|TCP_FLAG_PUSH_V|TCP_FLAG_FIN_V; + + // total length field in the IP header must be set: + // 20 bytes IP + 20 bytes tcp (when no options) + len of data + j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen; + buf[IP_TOTLEN_H_P]=j>>8; + buf[IP_TOTLEN_L_P]=j& 0xff; + fill_ip_hdr_checksum(buf); + // zero the checksum + buf[TCP_CHECKSUM_H_P]=0; + buf[TCP_CHECKSUM_L_P]=0; + // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len + j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlen,2); + buf[TCP_CHECKSUM_H_P]=j>>8; + buf[TCP_CHECKSUM_L_P]=j& 0xff; + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen+ETH_HEADER_LEN,buf); +} + + +/* new functions for web client interface */ +void make_arp_request(uint8_t *buf, uint8_t *server_ip) +{ + uint8_t i=0; + + while(i<6) + { + buf[ETH_DST_MAC +i]=0xff; + buf[ETH_SRC_MAC +i]=macaddr[i]; + i++; + } + + buf[ ETH_TYPE_H_P ] = ETHTYPE_ARP_H_V; + buf[ ETH_TYPE_L_P ] = ETHTYPE_ARP_L_V; + + // generate arp packet + buf[ARP_OPCODE_H_P]=ARP_OPCODE_REQUEST_H_V; + buf[ARP_OPCODE_L_P]=ARP_OPCODE_REQUEST_L_V; + + // fill in arp request packet + // setup hardware type to ethernet 0x0001 + buf[ ARP_HARDWARE_TYPE_H_P ] = ARP_HARDWARE_TYPE_H_V; + buf[ ARP_HARDWARE_TYPE_L_P ] = ARP_HARDWARE_TYPE_L_V; + + // setup protocol type to ip 0x0800 + buf[ ARP_PROTOCOL_H_P ] = ARP_PROTOCOL_H_V; + buf[ ARP_PROTOCOL_L_P ] = ARP_PROTOCOL_L_V; + + // setup hardware length to 0x06 + buf[ ARP_HARDWARE_SIZE_P ] = ARP_HARDWARE_SIZE_V; + + // setup protocol length to 0x04 + buf[ ARP_PROTOCOL_SIZE_P ] = ARP_PROTOCOL_SIZE_V; + + // setup arp destination and source mac address + for ( i=0; i<6; i++) + { + buf[ ARP_DST_MAC_P + i ] = 0x00; + buf[ ARP_SRC_MAC_P + i ] = macaddr[i]; + } + + // setup arp destination and source ip address + for ( i=0; i<4; i++) + { + buf[ ARP_DST_IP_P + i ] = server_ip[i]; + buf[ ARP_SRC_IP_P + i ] = ipaddr[i]; + } + + // eth+arp is 42 bytes: + enc28j60PacketSend(42,buf); + +} + + +uint8_t arp_packet_is_myreply_arp ( uint8_t *buf ) +{ + uint8_t i; + + // if packet type is not arp packet exit from function + if( buf[ ETH_TYPE_H_P ] != ETHTYPE_ARP_H_V || buf[ ETH_TYPE_L_P ] != ETHTYPE_ARP_L_V) + return 0; + // check arp request opcode + if ( buf[ ARP_OPCODE_H_P ] != ARP_OPCODE_REPLY_H_V || buf[ ARP_OPCODE_L_P ] != ARP_OPCODE_REPLY_L_V ) + return 0; + // if destination ip address in arp packet not match with avr ip address + for(i=0; i<4; i++){ + if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i]){ + return 0; + } + } + return 1; +} + +// make a tcp header +void tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, + uint8_t clear_seqack, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip) +{ + uint8_t i=0; + uint8_t tseq; + uint16_t ck; + + make_eth_ip_new(buf, dest_mac); + + buf[TCP_DST_PORT_H_P]= (uint8_t) ( (dest_port>>8) & 0xff); + buf[TCP_DST_PORT_L_P]= (uint8_t) (dest_port & 0xff); + + buf[TCP_SRC_PORT_H_P]= (uint8_t) ( (src_port>>8) & 0xff); + buf[TCP_SRC_PORT_L_P]= (uint8_t) (src_port & 0xff); + + // sequence numbers: + // add the rel ack num to SEQACK + + if(next_ack_num) + { + for(i=4; i>0; i--) + { + next_ack_num=buf[TCP_SEQ_H_P+i-1]+next_ack_num; + tseq=buf[TCP_SEQACK_H_P+i-1]; + buf[TCP_SEQACK_H_P+i-1]=0xff&next_ack_num; + // copy the acknum sent to us into the sequence number + buf[TCP_SEQ_P + i - 1 ] = tseq; + next_ack_num>>=8; + } + } + + // initial tcp sequence number,require to setup for first transmit/receive + if(max_segment_size) + { + // put inital seq number + buf[TCP_SEQ_H_P+0]= 0; + buf[TCP_SEQ_H_P+1]= 0; + // we step only the second byte, this allows us to send packts + // with 255 bytes or 512 (if we step the initial seqnum by 2) + buf[TCP_SEQ_H_P+2]= seqnum; + buf[TCP_SEQ_H_P+3]= 0; + // step the inititial seq num by something we will not use + // during this tcp session: + seqnum+=2; + + // setup maximum segment size + buf[TCP_OPTIONS_P]=2; + buf[TCP_OPTIONS_P+1]=4; + buf[TCP_OPTIONS_P+2]=0x05; + buf[TCP_OPTIONS_P+3]=0x80; + // 24 bytes: + buf[TCP_HEADER_LEN_P]=0x60; + + dlength +=4; + } + else{ + // no options: + // 20 bytes: + buf[TCP_HEADER_LEN_P]=0x50; + } + + make_ip_tcp_new(buf,IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlength, dest_ip); + + // clear sequence ack numer before send tcp SYN packet + if(clear_seqack) + { + buf[TCP_SEQACK_P] = 0; + buf[TCP_SEQACK_P+1] = 0; + buf[TCP_SEQACK_P+2] = 0; + buf[TCP_SEQACK_P+3] = 0; + } + // zero the checksum + buf[TCP_CHECKSUM_H_P]=0; + buf[TCP_CHECKSUM_L_P]=0; + + // set up flags + buf[TCP_FLAG_P] = flags; + // setup maximum windows size + buf[ TCP_WINDOWSIZE_H_P ] = ((600 - IP_HEADER_LEN - ETH_HEADER_LEN)>>8) & 0xff; + buf[ TCP_WINDOWSIZE_L_P ] = (600 - IP_HEADER_LEN - ETH_HEADER_LEN) & 0xff; + + // setup urgend pointer (not used -> 0) + buf[ TCP_URGENT_PTR_H_P ] = 0; + buf[ TCP_URGENT_PTR_L_P ] = 0; + + // check sum + ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlength,2); + buf[TCP_CHECKSUM_H_P]=ck>>8; + buf[TCP_CHECKSUM_L_P]=ck& 0xff; + // add 4 for option mss: + enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlength+ETH_HEADER_LEN,buf); + +} + +uint16_t tcp_get_dlength ( uint8_t *buf ) +{ + int dlength, hlength; + + dlength = ( buf[ IP_TOTLEN_H_P ] <<8 ) | ( buf[ IP_TOTLEN_L_P ] ); + dlength -= IP_HEADER_LEN; + hlength = (buf[ TCP_HEADER_LEN_P ]>>4) * 4; // generate len in bytes; + dlength -= hlength; + if ( dlength <= 0 ) + dlength=0; + + return ((uint16_t)dlength); +} + +/* end of ip_arp_udp.c */ diff --git a/libraries/etherShield/ip_arp_udp_tcp.h b/libraries/etherShield/ip_arp_udp_tcp.h new file mode 100644 index 0000000..8dad55d --- /dev/null +++ b/libraries/etherShield/ip_arp_udp_tcp.h @@ -0,0 +1,44 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * + * IP/ARP/UDP/TCP functions + * + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ + /********************************************* + * Modified: nuelectronics.com -- Ethershield for Arduino + *********************************************/ +//@{ +#ifndef IP_ARP_UDP_TCP_H +#define IP_ARP_UDP_TCP_H +#include + +// you must call this function once before you use any of the other functions: +extern void init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp); +// +extern uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len); +extern uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len); +extern void make_arp_answer_from_request(uint8_t *buf); +extern void make_echo_reply_from_request(uint8_t *buf,uint16_t len); +extern void make_udp_reply_from_request(uint8_t *buf,char *data,uint8_t datalen,uint16_t port); + + +extern void make_tcp_synack_from_syn(uint8_t *buf); +extern void init_len_info(uint8_t *buf); +extern uint16_t get_tcp_data_pointer(void); +extern uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s); +extern uint16_t fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s); +extern void make_tcp_ack_from_any(uint8_t *buf); +extern void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen); +extern void make_arp_request(uint8_t *buf, uint8_t *server_ip); +extern uint8_t arp_packet_is_myreply_arp ( uint8_t *buf ); +extern void tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, + uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip); +extern uint16_t tcp_get_dlength ( uint8_t *buf ); + + +#endif /* IP_ARP_UDP_TCP_H */ +//@} diff --git a/libraries/etherShield/keywords.txt b/libraries/etherShield/keywords.txt new file mode 100644 index 0000000..3d46a1d --- /dev/null +++ b/libraries/etherShield/keywords.txt @@ -0,0 +1,39 @@ +####################################### +# Syntax Coloring Map For Matrix +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +EtherShield KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +ES_fill_tcp_data_p KEYWORD2 +ES_fill_tcp_data KEYWORD2 +ES_enc28j60Init KEYWORD2 +ES_enc28j60clkout KEYWORD2 +ES_enc28j60PhyWrite KEYWORD2 +ES_enc28j60PacketReceive KEYWORD2 +ES_init_ip_arp_udp_tcp KEYWORD2 +ES_eth_type_is_arp_and_my_ip KEYWORD2 +ES_make_arp_answer_from_request KEYWORD2 +ES_eth_type_is_ip_and_my_ip KEYWORD2 +ES_make_echo_reply_from_request KEYWORD2 +ES_make_tcp_synack_from_syn KEYWORD2 +ES_init_len_info KEYWORD2 +ES_get_tcp_data_pointer KEYWORD2 +ES_make_tcp_ack_from_any KEYWORD2 +ES_make_tcp_ack_with_data KEYWORD2 +ES_make_arp_request KEYWORD2 +ES_arp_packet_is_myreply_arp KEYWORD2 +ES_tcp_client_send_packet KEYWORD2 +ES_tcp_get_dlength KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/etherShield/net.h b/libraries/etherShield/net.h new file mode 100644 index 0000000..8360d5a --- /dev/null +++ b/libraries/etherShield/net.h @@ -0,0 +1,177 @@ +/********************************************* + * vim:sw=8:ts=8:si:et + * To use the above modeline in vim you must have "set modeline" in your .vimrc + * Author: Guido Socher + * Copyright: GPL V2 + * + * Based on the net.h file from the AVRlib library by Pascal Stang. + * For AVRlib See http://www.procyonengineering.com/ + * Used with explicit permission of Pascal Stang. + * + * Chip type : ATMEGA88 with ENC28J60 + *********************************************/ + /********************************************* + * Modified: nuelectronics.com -- Ethershield for Arduino + *********************************************/ + +// notation: _P = position of a field +// _V = value of a field + +//@{ + +#ifndef NET_H +#define NET_H + +// ******* ETH ******* +#define ETH_HEADER_LEN 14 +// values of certain bytes: +#define ETHTYPE_ARP_H_V 0x08 +#define ETHTYPE_ARP_L_V 0x06 +#define ETHTYPE_IP_V 0x0800 +#define ETHTYPE_IP_H_V 0x08 +#define ETHTYPE_IP_L_V 0x00 +// byte positions in the ethernet frame: +// +// Ethernet type field (2bytes): +#define ETH_TYPE_H_P 12 +#define ETH_TYPE_L_P 13 +// +#define ETH_DST_MAC 0 +#define ETH_SRC_MAC 6 + + +// ******* ARP ******* +#define ETH_ARP_OPCODE_REPLY_H_V 0x0 +#define ETH_ARP_OPCODE_REPLY_L_V 0x02 +// +#define ETHTYPE_ARP_L_V 0x06 +// arp.dst.ip +#define ETH_ARP_DST_IP_P 0x26 +// arp.opcode +#define ETH_ARP_OPCODE_H_P 0x14 +#define ETH_ARP_OPCODE_L_P 0x15 +// arp.src.mac +#define ETH_ARP_SRC_MAC_P 0x16 +#define ETH_ARP_SRC_IP_P 0x1c +#define ETH_ARP_DST_MAC_P 0x20 +#define ETH_ARP_DST_IP_P 0x26 + +#define ARP_OPCODE_REQUEST_H_V 0x00 +#define ARP_OPCODE_REQUEST_L_V 0x01 +#define ARP_OPCODE_REPLY_H_V 0x00 +#define ARP_OPCODE_REPLY_L_V 0x02 + +#define ARP_HARDWARE_TYPE_H_V 0x00 +#define ARP_HARDWARE_TYPE_L_V 0x01 +#define ARP_PROTOCOL_H_V 0x08 +#define ARP_PROTOCOL_L_V 0x00 +#define ARP_HARDWARE_SIZE_V 0x06 +#define ARP_PROTOCOL_SIZE_V 0x04 + +#define ARP_HARDWARE_TYPE_H_P 0x0E +#define ARP_HARDWARE_TYPE_L_P 0x0F +#define ARP_PROTOCOL_H_P 0x10 +#define ARP_PROTOCOL_L_P 0x11 +#define ARP_HARDWARE_SIZE_P 0x12 +#define ARP_PROTOCOL_SIZE_P 0x13 +#define ARP_OPCODE_H_P 0x14 +#define ARP_OPCODE_L_P 0x15 +#define ARP_SRC_MAC_P 0x16 +#define ARP_SRC_IP_P 0x1C +#define ARP_DST_MAC_P 0x20 +#define ARP_DST_IP_P 0x26 + + +// ******* IP ******* +#define IP_HEADER_LEN 20 + +#define IP_PROTO_ICMP_V 0x01 +#define IP_PROTO_TCP_V 0x06 +#define IP_PROTO_UDP_V 0x11 +#define IP_V4_V 0x40 +#define IP_HEADER_LENGTH_V 0x05 + +#define IP_P 0x0E +#define IP_HEADER_VER_LEN_P 0x0E +#define IP_TOS_P 0x0F +#define IP_TOTLEN_H_P 0x10 +#define IP_TOTLEN_L_P 0x11 +#define IP_ID_H_P 0x12 +#define IP_ID_L_P 0x13 +#define IP_FLAGS_P 0x14 +#define IP_FLAGS_H_P 0x14 +#define IP_FLAGS_L_P 0x15 +#define IP_TTL_P 0x16 +#define IP_PROTO_P 0x17 +#define IP_CHECKSUM_P 0x18 +#define IP_CHECKSUM_H_P 0x18 +#define IP_CHECKSUM_L_P 0x19 +#define IP_SRC_IP_P 0x1A +#define IP_DST_IP_P 0x1E + +#define IP_SRC_P 0x1a +#define IP_DST_P 0x1e +#define IP_HEADER_LEN_VER_P 0xe +// ******* ICMP ******* +#define ICMP_TYPE_ECHOREPLY_V 0 +#define ICMP_TYPE_ECHOREQUEST_V 8 +// +#define ICMP_TYPE_P 0x22 +#define ICMP_CHECKSUM_P 0x24 + +// ******* UDP ******* +#define UDP_HEADER_LEN 8 +// +#define UDP_SRC_PORT_H_P 0x22 +#define UDP_SRC_PORT_L_P 0x23 +#define UDP_DST_PORT_H_P 0x24 +#define UDP_DST_PORT_L_P 0x25 +// +#define UDP_LEN_H_P 0x26 +#define UDP_LEN_L_P 0x27 +#define UDP_CHECKSUM_H_P 0x28 +#define UDP_CHECKSUM_L_P 0x29 +#define UDP_DATA_P 0x2a + +// ******* TCP ******* +// plain len without the options: +#define TCP_HEADER_LEN_PLAIN 20 + + +#define TCP_FLAG_FIN_V 0x01 +#define TCP_FLAGS_FIN_V 0x01 +#define TCP_FLAGS_SYN_V 0x02 +#define TCP_FLAG_SYN_V 0x02 +#define TCP_FLAG_RST_V 0x04 +#define TCP_FLAG_PUSH_V 0x08 +#define TCP_FLAGS_ACK_V 0x10 +#define TCP_FLAG_ACK_V 0x10 +#define TCP_FLAG_URG_V 0x20 +#define TCP_FLAG_ECE_V 0x40 +#define TCP_FLAG_CWR_V 0x80 +#define TCP_FLAGS_SYNACK_V 0x12 + +#define TCP_SRC_PORT_H_P 0x22 +#define TCP_SRC_PORT_L_P 0x23 +#define TCP_DST_PORT_H_P 0x24 +#define TCP_DST_PORT_L_P 0x25 +#define TCP_SEQ_P 0x26 // the tcp seq number is 4 bytes 0x26-0x29 +#define TCP_SEQ_H_P 0x26 +#define TCP_SEQACK_P 0x2A // 4 bytes +#define TCP_SEQACK_H_P 0x2A +#define TCP_HEADER_LEN_P 0x2E +#define TCP_FLAGS_P 0x2F +#define TCP_FLAG_P 0x2F +#define TCP_WINDOWSIZE_H_P 0x30 // 2 bytes +#define TCP_WINDOWSIZE_L_P 0x31 +#define TCP_CHECKSUM_H_P 0x32 +#define TCP_CHECKSUM_L_P 0x33 +#define TCP_URGENT_PTR_H_P 0x34 // 2 bytes +#define TCP_URGENT_PTR_L_P 0x35 +#define TCP_OPTIONS_P 0x36 +#define TCP_DATA_P 0x36 + +// +#endif +//@} + diff --git a/libraries/readme.txt b/libraries/readme.txt new file mode 100644 index 0000000..a8f1390 --- /dev/null +++ b/libraries/readme.txt @@ -0,0 +1 @@ +For information on installing libraries, see: http://arduino.cc/en/Guide/Libraries diff --git a/licht/licht.pde b/licht/licht.pde new file mode 100644 index 0000000..102f0ba --- /dev/null +++ b/licht/licht.pde @@ -0,0 +1,270 @@ +#define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt +#define TSL_S0 5 +#define TSL_S1 6 +#define TSL_S2 4 +#define TSL_S3 3 +#define TSL_LED 13 + + // 1000ms = 1s +#define READ_TM 1000 + +unsigned long pulse_cnt = 0; + + // two variables used to track time +unsigned long cur_tm = millis(); +unsigned long pre_tm = cur_tm; + +// we'll need to access the amount +// of time passed +unsigned int tm_diff = 0; + +// need to measure what to divide freq by +// 1x sensitivity = 10, +// 10x sens = 100, +// 100x sens = 1000 +int calc_sensitivity = 10; + +// set our frequency multiplier to a default of 1 +// which maps to output frequency scaling of 100x +int freq_mult = 100; + + +void setup() { + + Serial.begin(9600); + +// attach interrupt to pin2, send output pin of TSL230R to arduino 2 +// call handler on each rising pulse + + attachInterrupt(0, add_pulse, RISING); + + pinMode(TSL_FREQ_PIN, INPUT); + pinMode(TSL_S0, OUTPUT); + pinMode(TSL_S1, OUTPUT); + pinMode(TSL_S2, OUTPUT); + pinMode(TSL_S3, OUTPUT); + pinMode(TSL_LED, OUTPUT); + + digitalWrite(TSL_S0, HIGH); + digitalWrite(TSL_S1, LOW); + digitalWrite(TSL_S2, HIGH); + digitalWrite(TSL_S3, HIGH); + digitalWrite(TSL_LED, LOW); +} + +void loop() { + + // check the value of the light sensor every READ_TM ms + + // calculate how much time has passed + + pre_tm = cur_tm; + cur_tm = millis(); + + if( cur_tm > pre_tm ) { + tm_diff += cur_tm - pre_tm; + } + else if( cur_tm < pre_tm ) { + // handle overflow and rollover (Arduino 011) + tm_diff += ( cur_tm + ( 34359737 - pre_tm )); + } + + // if enough time has passed to do a new reading... + + if( tm_diff >= READ_TM ) { + + // re-set the ms counter + tm_diff = 0; + + // get our current frequency reading + unsigned long frequency = get_tsl_freq(); + + // calculate radiant energy + float uw_cm2 = calc_uwatt_cm2( frequency ); + + // calculate illuminance + float lux = calc_lux_single( uw_cm2, 0.175 ); + //print(lux); + Serial.print(lux, DEC); + + + Serial.print("\n"); + /* + Serial.print("tm_diff: "); + Serial.print(tm_diff, DEC); + Serial.print(" pulse_cnt: "); + Serial.print(pulse_cnt, DEC); + Serial.print("\n"); + */ + if(lux < 400) { + //Serial.print("off\n"); + //digitalWrite(TSL_LED, HIGH); + //Serial.print(1, BYTE); + } else { + //digitalWrite(TSL_LED, LOW); + //Serial.print(0, BYTE); + } + } + +} + +void set_scaling ( int what ) { + + // set output frequency scaling + // adjust frequency multiplier and set proper pin values + // e.g.: + // scale = 2 == freq_mult = 2 + // scale = 10 == freq_mult = 10 + // scale = 100 == freq_mult = 100 + + int pin_2 = HIGH; + int pin_3 = HIGH; + + switch( what ) { + case 2: + pin_3 = LOW; + freq_mult = 2; + break; + case 10: + pin_2 = LOW; + freq_mult = 10; + break; + case 100: + freq_mult = 100; + break; + default: + // don't do anything with levels + // we don't recognize + return; + } + + // set the pins to their appropriate levels + + digitalWrite(TSL_S2, pin_2); + digitalWrite(TSL_S3, pin_3); + + return; +} + +unsigned long get_tsl_freq() { + + // we have to scale out the frequency -- + // Scaling on the TSL230R requires us to multiply by a factor + // to get actual frequency + + unsigned long freq = pulse_cnt * freq_mult; + + // reset the pulse counter + + pulse_cnt = 0; + + return(freq); +} + +void add_pulse() { + + // increase pulse count + pulse_cnt++; + return; +} + +void sensitivity( bool dir ) { + + // adjust sensitivity in 3 steps of 10x either direction + + int pin_0; + int pin_1; + + if( dir == true ) { + + // increasing sensitivity + + // -- already as high as we can get + if( calc_sensitivity == 1000 ) + return; + + if( calc_sensitivity == 100 ) { + // move up to max sensitivity + pin_0 = true; + pin_1 = true; + } + else { + // move up to med. sesitivity + pin_0 = false; + pin_1 = true; + } + + // increase sensitivity divider + calc_sensitivity *= 10; + } + else { + // reducing sensitivity + + // already at lowest setting + + if( calc_sensitivity == 10 ) + return; + + if( calc_sensitivity == 100 ) { + // move to lowest setting + pin_0 = true; + pin_1 = false; + } + else { + // move to medium sensitivity + pin_0 = false; + pin_1 = true; + } + + // reduce sensitivity divider + calc_sensitivity = calc_sensitivity / 10; + } + + // make any necessary changes to pin states + + digitalWrite(TSL_S0, pin_0); + digitalWrite(TSL_S1, pin_1); + + return; +} + +float calc_uwatt_cm2(unsigned long freq) { + + // get uW observed - assume 640nm wavelength + // calc_sensitivity is our divide-by to map to a given signal strength + // for a given sensitivity (each level of greater sensitivity reduces the signal + // (uW) by a factor of 10) + + float uw_cm2 = (float) freq / (float) calc_sensitivity; + + // extrapolate into entire cm2 area + + uw_cm2 *= ( (float) 1 / (float) 0.0136 ); + + return(uw_cm2); + +} + +float calc_lux_single(float uw_cm2, float efficiency) { + + // calculate lux (lm/m^2), using standard formula: + // Xv = Xl * V(l) * Km + // Xl is W/m^2 (calculate actual receied uW/cm^2, extrapolate from sensor size (0.0136cm^2) + // to whole cm size, then convert uW to W) + // V(l) = efficiency function (provided via argument) + // Km = constant, lm/W @ 555nm = 683 (555nm has efficiency function of nearly 1.0) + // + // Only a single wavelength is calculated - you'd better make sure that your + // source is of a single wavelength... Otherwise, you should be using + // calc_lux_gauss() for multiple wavelengths + + // convert to w_m2 + float w_m2 = (uw_cm2 / (float) 1000000) * (float) 100; + + // calculate lux + float lux = w_m2 * efficiency * (float) 683; + + return(lux); +} + + diff --git a/light.c b/light.c new file mode 100644 index 0000000..7039a04 --- /dev/null +++ b/light.c @@ -0,0 +1,246 @@ +#define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt +#define TSL_S0 5 +#define TSL_S1 6 +#define TSL_S2 7 +#define TSL_S3 8 + + // 1000ms = 1s +#define READ_TM 1000 + +unsigned long pulse_cnt = 0; + + // two variables used to track time +unsigned long cur_tm = millis(); +unsigned long pre_tm = cur_tm; + +// we'll need to access the amount +// of time passed +unsigned int tm_diff = 0; + +// need to measure what to divide freq by +// 1x sensitivity = 10, +// 10x sens = 100, +// 100x sens = 1000 +int calc_sensitivity = 10; + +// set our frequency multiplier to a default of 1 +// which maps to output frequency scaling of 100x +int freq_mult = 100; + + +void setup() { + +// attach interrupt to pin2, send output pin of TSL230R to arduino 2 +// call handler on each rising pulse + + attachInterrupt(0, add_pulse, RISING); + + pinMode(TSL_FREQ_PIN, INPUT); + pinMode(TSL_S0, OUTPUT); + pinMode(TSL_S1, OUTPUT); + pinMode(TSL_S2, OUTPUT); + pinMode(TSL_S3, OUTPUT); + + digitalWrite(TSL_S0, HIGH); + digitalWrite(TSL_S1, LOW); + digitalWrite(TSL_S2, HIGH); + digitalWrite(TSL_S3, HIGH); +} + +void loop() { + + // check the value of the light sensor every READ_TM ms + + // calculate how much time has passed + + pre_tm = cur_tm; + cur_tm = millis(); + + if( cur_tm > pre_tm ) { + tm_diff += cur_tm - pre_tm; + } + else if( cur_tm < pre_tm ) { + // handle overflow and rollover (Arduino 011) + tm_diff += ( cur_tm + ( 34359737 - pre_tm )); + } + + // if enough time has passed to do a new reading... + + if( tm_diff >= READ_TM ) { + + // re-set the ms counter + tm_diff = 0; + + // get our current frequency reading + unsigned long frequency = get_tsl_freq(); + + // calculate radiant energy + float uw_cm2 = calc_uwcm2( frequency ); + + // calculate illuminance + float lux = calc_lux_single( uw_cm2, 0.175 ); +print(lux); + } + +} + +void set_scaling ( int what ) { + + // set output frequency scaling + // adjust frequency multiplier and set proper pin values + // e.g.: + // scale = 2 == freq_mult = 2 + // scale = 10 == freq_mult = 10 + // scale = 100 == freq_mult = 100 + + int pin_2 = HIGH; + int pin_3 = HIGH; + + switch( what ) { + case 2: + pin_3 = LOW; + freq_mult = 2; + break; + case 10: + pin_2 = LOW; + freq_mult = 10; + break; + case 100: + freq_mult = 100; + break; + default: + // don't do anything with levels + // we don't recognize + return; + } + + // set the pins to their appropriate levels + + digitalWrite(TSL_S2, pin_2); + digitalWrite(TSL_S3, pin_3); + + return; +} + +unsigned long get_tsl_freq() { + + // we have to scale out the frequency -- + // Scaling on the TSL230R requires us to multiply by a factor + // to get actual frequency + + unsigned long freq = pulse_cnt * freq_mult; + + // reset the pulse counter + + pulse_cnt = 0; + + return(freq); +} + +void add_pulse() { + + // increase pulse count + pulse_cnt++; + return; +} + +void sensitivity( bool dir ) { + + // adjust sensitivity in 3 steps of 10x either direction + + int pin_0; + int pin_1; + + if( dir == true ) { + + // increasing sensitivity + + // -- already as high as we can get + if( calc_sensitivity == 1000 ) + return; + + if( calc_sensitivity == 100 ) { + // move up to max sensitivity + pin_0 = true; + pin_1 = true; + } + else { + // move up to med. sesitivity + pin_0 = false; + pin_1 = true; + } + + // increase sensitivity divider + calc_sensitivity *= 10; + } + else { + // reducing sensitivity + + // already at lowest setting + + if( calc_sensitivity == 10 ) + return; + + if( calc_sensitivity == 100 ) { + // move to lowest setting + pin_0 = true; + pin_1 = false; + } + else { + // move to medium sensitivity + pin_0 = false; + pin_1 = true; + } + + // reduce sensitivity divider + calc_sensitivity = calc_sensitivity / 10; + } + + // make any necessary changes to pin states + + digitalWrite(TSL_S0, pin_0); + digitalWrite(TSL_S1, pin_1); + + return; +} + +float calc_uwatt_cm2(unsigned long freq) { + + // get uW observed - assume 640nm wavelength + // calc_sensitivity is our divide-by to map to a given signal strength + // for a given sensitivity (each level of greater sensitivity reduces the signal + // (uW) by a factor of 10) + + float uw_cm2 = (float) freq / (float) calc_sensitivity; + + // extrapolate into entire cm2 area + + uw_cm2 *= ( (float) 1 / (float) 0.0136 ); + + return(uw_cm2); + +} + +float calc_lux_single(float uw_cm2, float efficiency) { + + // calculate lux (lm/m^2), using standard formula: + // Xv = Xl * V(l) * Km + // Xl is W/m^2 (calculate actual receied uW/cm^2, extrapolate from sensor size (0.0136cm^2) + // to whole cm size, then convert uW to W) + // V(l) = efficiency function (provided via argument) + // Km = constant, lm/W @ 555nm = 683 (555nm has efficiency function of nearly 1.0) + // + // Only a single wavelength is calculated - you'd better make sure that your + // source is of a single wavelength... Otherwise, you should be using + // calc_lux_gauss() for multiple wavelengths + + // convert to w_m2 + float w_m2 = (u_cm2 / (float) 1000000) * (float) 100; + + // calculate lux + float lux = w_m2 * efficiency * (float) 683; + + return(lux); +} + + diff --git a/light.txt b/light.txt new file mode 100644 index 0000000..9c54bc5 --- /dev/null +++ b/light.txt @@ -0,0 +1,37 @@ + 1. #define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt + 2. #define TSL_S0 5 + 3. #define TSL_S1 6 + 4. #define TSL_S2 7 + 5. #define TSL_S3 8 + + 1. unsigned long pulse_cnt = 0; + 2. + 3. void setup() { + 4. + 5. // attach interrupt to pin2, send output pin of TSL230R to arduino 2 + 6. // call handler on each rising pulse + 7. + 8. attachInterrupt(0, add_pulse, RISING); + 9. + 10. pinMode(TSL_FREQ_PIN, INPUT); + 11. pinMode(TSL_S0, OUTPUT); + 12. pinMode(TSL_S1, OUTPUT); + 13. pinMode(TSL_S2, OUTPUT); + 14. pinMode(TSL_S3, OUTPUT); + 15. + 16. digitalWrite(TSL_S0, HIGH); + 17. digitalWrite(TSL_S1, LOW); + 18. digitalWrite(TSL_S2, HIGH); + 19. digitalWrite(TSL_S3, HIGH); + 20. } + 21. + 22. void loop() { + 23. + 24. } + 25. + 26. void add_pulse() { + 27. + 28. // increase pulse count + 29. pulse_cnt++; + 30. return; + 31. } diff --git a/lm35/lm35.ino b/lm35/lm35.ino new file mode 100644 index 0000000..9848298 --- /dev/null +++ b/lm35/lm35.ino @@ -0,0 +1,21 @@ +#include + +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +float temp; +int tempPin = 0; + +void setup() { + lcd.begin(16, 2); + lcd.print("Temperature:"); +} + +void loop() { + temp = analogRead(tempPin); + temp = temp * 0.48828125; + //temp = (5.0 * temp * 100.0)/1024.0; + lcd.setCursor(0, 1); + lcd.print(temp); + delay(1000); +} + diff --git a/matrix_01/matrix_01.pde b/matrix_01/matrix_01.pde new file mode 100644 index 0000000..cbecf09 --- /dev/null +++ b/matrix_01/matrix_01.pde @@ -0,0 +1,225 @@ +#include +#include + +#define COLS 5 +#define ROWS 7 +#define PINS 13 + +#define MATRIX1 { \ + {1,0,1,0,1,0,1}, \ + {0,1,0,1,0,1,0}, \ + {1,0,1,0,1,0,1}, \ + {0,1,0,1,0,1,0}, \ + {1,0,1,0,1,0,1} \ +} + +#define MATRIX2 { \ + {0,1,0,1,0,1,0}, \ + {1,0,1,0,1,0,1}, \ + {0,1,0,1,0,1,0}, \ + {1,0,1,0,1,0,1}, \ + {0,1,0,1,0,1,0} \ +} + +byte col = 0; +byte leds[COLS][ROWS]; + +// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1) +int pins[PINS]= {-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + +// col[xx] of leds = pin yy on led matrix +int cols[COLS] = {pins[1], pins[3], pins[10], pins[7], pins[8]}; + +// row[xx] of leds = pin yy on led matrix +int rows[ROWS] = {pins[12], pins[11], pins[2], pins[9], pins[4], pins[5], pins[6]}; + +const int numPatterns = 16; +byte patterns[numPatterns][COLS][ROWS] = {H,A,L,L,O,DASH,H,E,L,M,U,T,SPACE,MATRIX1,MATRIX2,MATRIX1}; + +int pattern = 0; + +void setup() { + + //Serial.begin(9600); + + // sets the pins as output + for (int i = 0; i < PINS; i++) { + pinMode(pins[i], OUTPUT); + } + + // set up cols + for (int i = 1; i <= COLS; i++) { + digitalWrite(cols[i - 1], 0); + } + // and rows + for (int i = 1; i <= ROWS; i++) { + digitalWrite(rows[i - 1], 1); + } + + blink(); + five2one(); + + clearLeds(); + + Timer1.initialize(2000); // initialize timer1, and set a 1/2 second period + Timer1.attachInterrupt(display); // attaches display() as a timer overflow interrupt + + setPattern(pattern); +} + +void loop() { + pattern = ++pattern % numPatterns; + slidePattern(pattern, 120); +} +// Interrupt routine +void display() { + digitalWrite(cols[col], 0); // Turn whole previous column off + col++; + if (col == 5) { + col = 0; + } + for (int row = 0; row < 7; row++) { + if (leds[col][(ROWS - 1) - row] == 1) { + digitalWrite(rows[row], 0); // Turn on this led + } + else { + digitalWrite(rows[row], 1); // Turn off this led + } + // delay(10); + } + digitalWrite(cols[col], 1); // Turn whole column on at once (for equal lighting times) + +} + +void slidePattern(int pattern, int del) { + for (int l = 0; l < COLS; l++) { + for (int i = 0; i < (COLS - 1); i++) { + for (int j = 0; j < ROWS; j++) { + leds[i][j] = leds[i + 1][j]; + } + } + for (int j = 0; j < ROWS; j++) { + leds[4][j] = patterns[pattern][0 + l][j]; + } + delay(del); + } +} + +void clearLeds() { + // Clear display array + for (int i = 0; i < COLS; i++) { + for (int j = 0; j < ROWS; j++) { + leds[i][j] = 0; + } + } +} + +void setPattern(int pattern) { + for (int i = 0; i < COLS; i++) { + for (int j = 0; j < ROWS; j++) { + leds[i][j] = patterns[pattern][i][j]; + } + } +} + +void blink() { + for(int i = 0; i < 12; i++) { + if(i % 2 != 0) { + digitalWrite(cols[0], 1); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + } else { + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 1); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + } + delay(100); + } +} + +void five2one() { + digitalWrite(cols[0], 1); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(100); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 1); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(100); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 1); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(100); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 1); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(100); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 1); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(100); +} + diff --git a/matrix_02/matrix_02.pde b/matrix_02/matrix_02.pde new file mode 100644 index 0000000..ee9132d --- /dev/null +++ b/matrix_02/matrix_02.pde @@ -0,0 +1,162 @@ +#include + +#define COLS 5 +#define ROWS 7 +#define PINS 13 + +#define SPACE { \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0}, \ + {0, 0, 0, 0, 0} \ +} + +#define H { \ + {1, 0, 0, 0, 1}, \ + {1, 0, 0, 0, 1}, \ + {1, 0, 0, 0, 1}, \ + {1, 1, 1, 1, 1}, \ + {1, 0, 0, 0, 1}, \ + {1, 0, 0, 0, 1}, \ + {1, 0, 0, 0, 1} \ +} + +#define E { \ + {1, 1, 1, 1, 1}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 1, 1, 1, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 1, 1, 1, 1} \ +} + +#define L { \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 0, 0, 0, 0}, \ + {1, 1, 1, 1, 1} \ +} + +byte col = 0; +byte leds[COLS][ROWS]; + +// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1) +int pins[PINS]= {-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + +// col[xx] of leds = pin yy on led matrix +int cols[COLS] = {pins[1], pins[3], pins[10], pins[7], pins[8]}; + +// row[xx] of leds = pin yy on led matrix +int rows[ROWS] = {pins[12], pins[11], pins[2], pins[9], pins[4], pins[5], pins[6]}; + + +void setup() { + + Serial.begin(9600); + + for (int i = 0; i < PINS; i++) { + pinMode(pins[i], OUTPUT); + } + for (int i = 1; i <= COLS; i++) { + digitalWrite(cols[i - 1], 0); + } + for (int i = 1; i <= ROWS; i++) { + digitalWrite(rows[i - 1], 1); + } + + + + /* + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 1); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(2000); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 1); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(2000); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 1); + digitalWrite(cols[4], 0); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(2000); + digitalWrite(cols[0], 0); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 0); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 1); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 1); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 1); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 1); + digitalWrite(rows[6], 1); + delay(2000); + */ +} + +void loop() { + Serial.println("Foo"); + + digitalWrite(cols[0], 1); + digitalWrite(cols[1], 1); + digitalWrite(cols[2], 1); + digitalWrite(cols[3], 1); + digitalWrite(cols[4], 1); + digitalWrite(rows[0], 0); + digitalWrite(rows[1], 0); + digitalWrite(rows[2], 0); + digitalWrite(rows[3], 0); + digitalWrite(rows[4], 0); + digitalWrite(rows[5], 0); + digitalWrite(rows[6], 0); + delay(2000); + digitalWrite(cols[0], 1); + digitalWrite(cols[1], 0); + digitalWrite(cols[2], 1); + digitalWrite(cols[3], 0); + digitalWrite(cols[4], 1); + digitalWrite(rows[0], 1); + digitalWrite(rows[1], 0); + digitalWrite(rows[2], 1); + digitalWrite(rows[3], 0); + digitalWrite(rows[4], 1); + digitalWrite(rows[5], 0); + digitalWrite(rows[6], 1); + delay(2000); + +} diff --git a/multiplexer_01/multiplexer_01.pde b/multiplexer_01/multiplexer_01.pde new file mode 100644 index 0000000..32ff910 --- /dev/null +++ b/multiplexer_01/multiplexer_01.pde @@ -0,0 +1,35 @@ + +#define OUTPUT0 13 +#define OUTPUT1 12 +#define OUTPUT2 11 + +void setup() { + + //Serial.begin(9600); + + + pinMode(OUTPUT0, OUTPUT); + pinMode(OUTPUT1, OUTPUT); + pinMode(OUTPUT2, OUTPUT); + + +} + +void loop() { + digitalWrite(OUTPUT0, LOW); + digitalWrite(OUTPUT1, LOW); + digitalWrite(OUTPUT2, LOW); + delay(100); + digitalWrite(OUTPUT0, HIGH); + digitalWrite(OUTPUT1, LOW); + digitalWrite(OUTPUT2, LOW); + delay(100); + digitalWrite(OUTPUT0, LOW); + digitalWrite(OUTPUT1, HIGH); + digitalWrite(OUTPUT2, LOW); + delay(100); + digitalWrite(OUTPUT0, HIGH); + digitalWrite(OUTPUT1, HIGH); + digitalWrite(OUTPUT2, LOW); + delay(100); +} diff --git a/ps2_kbd/ps2_kbd.pde b/ps2_kbd/ps2_kbd.pde new file mode 100644 index 0000000..e40f381 --- /dev/null +++ b/ps2_kbd/ps2_kbd.pde @@ -0,0 +1,37 @@ +/* + * an arduino sketch to interface with a ps/2 keyboard. + * Also uses serial protocol to talk back to the host + * and report what it finds. Used the ps2 library. + */ + +#include + +/* + * Pin 5 is the ps2 data pin, pin 6 is the clock pin + * Feel free to use whatever pins are convenient. + */ + +PS2 kbd(6, 5); + +void setup() +{ + Serial.begin(9600); + kbd.init_kbd(); +} + +/* + * get a keycode from the kbd and report it back to the + * host via the serial line. + */ +void loop() +{ + unsigned char code; + + for (;;) { /* ever */ + /* read a keycode */ + code = kbd.read(); + /* send the data back up */ + Serial.println(code, HEX); + // delay(20); /* twiddle */ + } +} diff --git a/ps2_mouse/ps2_mouse.pde b/ps2_mouse/ps2_mouse.pde new file mode 100644 index 0000000..9828e8e --- /dev/null +++ b/ps2_mouse/ps2_mouse.pde @@ -0,0 +1,52 @@ +#include + +/* + * an arduino sketch to interface with a ps/2 mouse. + * Also uses serial protocol to talk back to the host + * and report what it finds. + */ + +/* + * Pin 5 is the mouse data pin, pin 6 is the clock pin + * Feel free to use whatever pins are convenient. + */ +PS2 mouse(6, 5); + +/* + * initialize the mouse. Reset it, and place it into remote + * mode, so we can get the encoder data on demand. + */ + + +void setup() +{ + Serial.begin(9600); + mouse.init_mouse(); +} + +/* + * get a reading from the mouse and report it back to the + * host via the serial line. + */ +void loop() +{ + char mstat; + char mx; + char my; + + /* get a reading from the mouse */ + mouse.write(0xeb); // give me data! + mouse.read(); // ignore ack + mstat = mouse.read(); + mx = mouse.read(); + my = mouse.read(); + + /* send the data back up */ + Serial.print(mstat, BIN); + Serial.print("\tX="); + Serial.print(mx, DEC); + Serial.print("\tY="); + Serial.print(my, DEC); + Serial.println(); + delay(20); /* twiddle */ +} diff --git a/sketch_090319a/sketch_090319a.pde b/sketch_090319a/sketch_090319a.pde new file mode 100644 index 0000000..d487eb8 --- /dev/null +++ b/sketch_090319a/sketch_090319a.pde @@ -0,0 +1,21 @@ + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte x = 0; + +void loop() +{ + Wire.beginTransmission(72); // transmit to device #4 + Wire.send("x is "); // sends five bytes + Wire.send(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} diff --git a/sketch_090627a/sketch_090627a.pde b/sketch_090627a/sketch_090627a.pde new file mode 100644 index 0000000..6e8876f --- /dev/null +++ b/sketch_090627a/sketch_090627a.pde @@ -0,0 +1,88 @@ +//3led fnordlicht// + +int value = 0; +int bluepin = 9; +int greenpin = 10; +int redpin = 11; + +void setup() +{ +pinMode(bluepin, OUTPUT); +pinMode(greenpin, OUTPUT); +pinMode(redpin,OUTPUT); + +//led test start +digitalWrite(bluepin, HIGH); +delay(200); +digitalWrite(bluepin, LOW); +digitalWrite(greenpin, HIGH); +delay(200); +digitalWrite(greenpin, LOW); +digitalWrite(redpin, HIGH); +delay(200); +digitalWrite(redpin, LOW); + +digitalWrite(bluepin, HIGH); +delay(200); +digitalWrite(bluepin, LOW); +digitalWrite(greenpin, HIGH); +delay(200); +digitalWrite(greenpin, LOW); +digitalWrite(redpin, HIGH); +delay(200); +digitalWrite(redpin, LOW); + +digitalWrite(bluepin, HIGH); +delay(200); +digitalWrite(bluepin, LOW); +digitalWrite(greenpin, HIGH); +delay(200); +digitalWrite(greenpin, LOW); +digitalWrite(redpin, HIGH); +delay(200); +digitalWrite(redpin, LOW); +delay(5000); +} + +void loop() +{ +digitalWrite(bluepin, 255+value); +for(value = 4 ; value <= 255; value+=1) +{ +analogWrite(redpin, value); +analogWrite(greenpin, value); +delay(50); +} +for(value = 255; value >=4; value-=1) +{ +analogWrite(bluepin, value); +analogWrite(greenpin, value); +delay(50); +} +//fading 2 +for(value = 4 ; value <= 255; value+=1) +{ +analogWrite(bluepin, value); +analogWrite(greenpin, value); +delay(50); +} +for(value = 255; value >=4; value-=1) +{ +analogWrite(bluepin, value); +analogWrite(redpin, value); +delay(50); +} +//fading 3 +for(value = 4 ; value <= 255; value+=1) +{ +analogWrite(redpin, value); +analogWrite(bluepin, value); +delay(50); +} +for(value = 255; value >=4; value-=1) +{ +analogWrite(redpin, value); +analogWrite(greenpin, value); +delay(50); +} +} diff --git a/sketch_100405a/sketch_100405a.pde b/sketch_100405a/sketch_100405a.pde new file mode 100644 index 0000000..6e53429 --- /dev/null +++ b/sketch_100405a/sketch_100405a.pde @@ -0,0 +1,95 @@ +//164 pins +int clearPin = 2; // enablepin +int dataPin = 3; +int clockPin = 4; + +//165 pins +int inclearPin = 11; // enablepin +int indataPin = 9; +int inclockPin = 10; +int inloadPin = 12; // toggling this tells the 165 to read the value into its memory for reading + +int temp = 0; + +void setup() { + + //start serial + Serial.begin(9600); + + //164 + pinMode(clearPin, OUTPUT); + digitalWrite(clearPin, 1); // enable output, you could also tie this pin to VCC + pinMode(dataPin, OUTPUT); + pinMode(clockPin, OUTPUT); + + //165 + pinMode(inclearPin, OUTPUT); + digitalWrite(inclearPin, 0); // enable input, you could also tie this pin to GND + pinMode(indataPin, INPUT); + pinMode(inclockPin, OUTPUT); + pinMode(inloadPin, OUTPUT); + + + //we want to set the 164's outputs to any combination of 1's and 0's we want + //going to set the 164 outputs to 11101101 or on,on,on,off,on,on,off,on if you prefer, where on is 5v and off is grnd + //1st bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + //2nd bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + //3rd bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + //4th bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 0); + digitalWrite(clockPin, 1); + //5th bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + //6th bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + //7th bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 0); + digitalWrite(clockPin, 1); + //8th bit + digitalWrite(clockPin, 0); + digitalWrite(dataPin, 1); + digitalWrite(clockPin, 1); + +} + +// now its time to read the values that we outputted back in + +void loop() { + + digitalWrite(inloadPin, 0); // read into register (tells the 165 to take a snapshot of its input pins) + digitalWrite(inloadPin, 1); // done reading into register, ready for us to read + + for(int i=0; i<=7; i++){ // read each of the 165's 8 inputs (or its snapshot of it rather) + + // tell the 165 to send the inputs pin state + digitalWrite(inclockPin, 0); + // read the current output + temp = digitalRead(indataPin); // read the state + // tell the 165 we are done reading + digitalWrite(inclockPin, 1); + + Serial.print (temp); + + } + + Serial.println (""); + Serial.println ("--------"); + + delay(2000); + +}