dumped all my old arduino stuff in here.

This commit is contained in:
Johannes Findeisen 2015-08-15 23:03:28 +02:00
commit 8f8959b76f
76 changed files with 8127 additions and 2 deletions

21
AAA Normal file
View file

@ -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
}

View file

@ -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<n; i++) {
byte b;
b = readbyte();
if(b!=0xFF) // erased mem is filled with ones
{
spibyte(0x40 | (hi<<3));
spiword(addr);
spibyte(b);
delay(5);
}
printhex(b);
count++;
addr += hi; // increment after loading high byte
hi = 1-hi;
// write when we hit the next page
if(addr%PAGESIZE == 0 && hi==0) {
spibyte(0x4C);
spiword(addr-PAGESIZE);
spibyte(0x00);
delay(50); // WD_FLASH
}
}
Serial.println();
} else if(t == 1) {
// end record
done = true;
// write the last page
spibyte(0x4C);
spiword(addr);
spibyte(0x00);
delay(50); // WD_FLASH
}
skipline();
}
Serial.println("programming complete.");
Serial.print(count);
Serial.println(" bytes written.");
// let the slave start
Serial.println("slave start.");
digitalWrite(MOSI, LOW); // clear output state
digitalWrite(RESET, HIGH);
Serial.println("press any key for another round.");
Serial.flush();
readchar();
} else {
Serial.print("not in sync, retry in 1s...");
delay(1000);
}
}
dword spibits(int n, dword output)
{
dword input = 0;
// exchange n bits over SPI
for(int i=n-1; 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');
}

66
Blink/Blink.pde Normal file
View file

@ -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); */
}

0
Blink/Foo.pde Normal file
View file

View file

@ -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
}

30
BlinkNeu/BlinkNeu.pde Normal file
View file

@ -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
}

14
Blink_GNO Normal file
View file

@ -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);
}

19
Blink_test/Blink_test.pde Normal file
View file

@ -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
}

327
DCF77/LCD4Bit.pde Normal file
View file

@ -0,0 +1,327 @@
#include <LCD4Bit.h>
#include <avr/io.h>
//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<<CS22); // turn on CS22 bit
TCCR2 &= ~((1<<CS21) | (1<<CS20)); // turn off CS21 and CS20 bits
// Use normal mode
TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); // turn off WGM21 and WGM20 bits
// Use internal clock - external clock not used in Arduino
ASSR |= (0<<AS2);
TIMSK |= (1<<TOIE2) | (0<<OCIE2); //Timer2 Overflow Interrupt Enable
RESET_TIMER2;
#ifdef DCF_DEBUG
Serial.println("Initializing DCF77 signal listener interrupt");
#endif
attachInterrupt(0, int0handler, CHANGE);
}
/**
* Append a signal to the dcf_rx_buffer. Argument can be 1 or 0. An internal
* counter shifts the writing position within the buffer. If position > 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);
}
*/
}

143
DS1626/DS1626.ino Normal file
View file

@ -0,0 +1,143 @@
//#include <LiquidCrystal.h>
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#include <SoftwareSerial.h>
#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);
}

36
Dimmer/Dimmer.ino Normal file
View file

@ -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);
}
}

61
Display_01/Display_01.pde Normal file
View file

@ -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 <LiquidCrystal.h>
// 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);
}

79
Display_02/Display_02.pde Normal file
View file

@ -0,0 +1,79 @@
#include <LiquidCrystal.h>
// 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);
}

35
Fade/Fade.ino Normal file
View file

@ -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);
}

43
FadeNeu/FadeNeu.pde Normal file
View file

@ -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);
}

33
Fade_test/Fade_test.pde Normal file
View file

@ -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);
}

View file

@ -0,0 +1,29 @@
#include <LiquidCrystal.h>
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
}

51
LCD4Bit/LCD4Bit.pde Normal file
View file

@ -0,0 +1,51 @@
#include <LCD4Bit.h>
//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("<<<<fuck off>>>>"); // 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);
}
*/
}

View file

@ -0,0 +1,47 @@
//example use of LCD4Bit library
#include <LCD4Bit.h>
//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);
}

View file

@ -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
}

View file

@ -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.... ;)

15
Relais/Relais.pde Normal file
View file

@ -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
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}

113
Temp/Temp.pde Normal file
View file

@ -0,0 +1,113 @@
#include <Wire.h>
#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);
}

48
Temp2/Temp2.pde Normal file
View file

@ -0,0 +1,48 @@
#include <Wire.h>
// 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);
}

15
Temp_03/Temp_03.pde Normal file
View file

@ -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);
}

71
WebClient/WebClient.pde Normal file
View file

@ -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 <SPI.h>
#include <Ethernet.h>
// 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(;;)
;
}
}

82
WebServer/WebServer.pde Normal file
View file

@ -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 <SPI.h>
#include <Ethernet.h>
// 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("<br />");
}
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();
}
}

View file

@ -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);
}

View file

@ -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
}

27
_74HC238/_74HC238.pde Normal file
View file

@ -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);
}

33
_7segment/_7segment.ino Normal file
View file

@ -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
}

View file

@ -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);
}

View file

@ -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);
}
}
}
}

View file

@ -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<h1>200 OK</h1>"));
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<STR_BUFFER_SIZE){
strbuf[i]=*str;
i++;
str++;
}
strbuf[i]='\0';
}
return(found);
}
int8_t analyse_cmd(char *str)
{
int8_t r=-1;
if (find_key_val(str,"cmd")){
if (*strbuf < 0x3a && *strbuf > 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);
}

View file

@ -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 <FrequencyTimer2.h>
#include <avr/interrupt.h>
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
}

View file

@ -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 <wiring.h>
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

View file

@ -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)
#######################################

View file

@ -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 <stdio.h> //not needed yet
#include <string.h> //needed for strlen()
#include <inttypes.h>
#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<x; i++) {
commandWrite(0x14);
}
}
//scroll whole display to left
void LCD4Bit::leftScroll(int num_chars, int delay_time){
for (int i=0; i<num_chars; i++) {
commandWrite(CMD_LEFT);
delay(delay_time);
}
}
//Improvements ------------------------------------------------
//Remove the unnecessary delays (e.g. from the end of pulseEnablePin()).
//Allow the user to pass the pins to be used by the LCD in the constructor, and store them as member variables of the class instance.
//-------------------------------------------------------------

View file

@ -0,0 +1,27 @@
#ifndef LCD4Bit_h
#define LCD4Bit_h
#include <inttypes.h>
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

View file

@ -0,0 +1,47 @@
//example use of LCD4Bit library
#include <LCD4Bit.h>
//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);
}

View file

@ -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)
#######################################

View file

@ -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 <LCD4Bit.h>
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"

View file

@ -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} \
}

101
libraries/TimerOne/TimerOne.cpp Executable file
View file

@ -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;
}

41
libraries/TimerOne/TimerOne.h Executable file
View file

@ -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 <avr/io.h>
#include <avr/interrupt.h>
#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;

View file

@ -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 <avr/io.h>
//#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 <util/delay.h>
#else
#include <avr/delay.h>
#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<<SPIF)))
uint8_t enc28j60ReadOp(uint8_t op, uint8_t address)
{
CSACTIVE;
// issue read command
SPDR = op | (address & ADDR_MASK);
waitspi();
// read data
SPDR = 0x00;
waitspi();
// do dummy read if needed (for mac and mii, see datasheet page 29)
if(address & 0x80)
{
SPDR = 0x00;
waitspi();
}
// release CS
CSPASSIVE;
return(SPDR);
}
void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data)
{
CSACTIVE;
// issue write command
SPDR = op | (address & ADDR_MASK);
waitspi();
// write data
SPDR = data;
waitspi();
CSPASSIVE;
}
void enc28j60ReadBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
// issue read command
SPDR = ENC28J60_READ_BUF_MEM;
waitspi();
while(len)
{
len--;
// read data
SPDR = 0x00;
waitspi();
*data = SPDR;
data++;
}
*data='\0';
CSPASSIVE;
}
void enc28j60WriteBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
// issue write command
SPDR = ENC28J60_WRITE_BUF_MEM;
waitspi();
while(len)
{
len--;
// write data
SPDR = *data;
data++;
waitspi();
}
CSPASSIVE;
}
void enc28j60SetBank(uint8_t address)
{
// set the bank (if needed)
if((address & BANK_MASK) != Enc28j60Bank)
{
// set the bank
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>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<<PB3 | 1<<PB5; // mosi, sck output
cbi(DDRB,PINB4); // MISO is input
//
cbi(PORTB,PB3); // MOSI low
cbi(PORTB,PB5); // SCK low
*/
//
// initialize SPI interface
// master mode and Fosc/2 clock:
SPCR = (1<<SPE)|(1<<MSTR);
SPSR |= (1<<SPI2X);
// perform system reset
enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
delay(50);
// check CLKRDY bit to see if reset is complete
// The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
//while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
// do bank 0 stuff
// initialize receive buffer
// 16-bit transfers, must write low byte first
// set receive buffer start address
NextPacketPtr = RXSTART_INIT;
// Rx start
enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
enc28j60Write(ERXSTH, RXSTART_INIT>>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);
}

View file

@ -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 <inttypes.h>
// 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
//@}

View file

@ -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);
}

View file

@ -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 <inttypes.h>
#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

View file

@ -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';
}

View file

@ -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<<SREG_I;
}
void loop(){
if(client_data_ready==1){
DISABLE_EXTERNAL1_INTERRUPT();
client_process();
digitalWrite(LED_STATUS, HIGH);
}
else{
delay(100);
ENABLE_EXTERNAL1_INTERRUPT();
digitalWrite(LED_STATUS, LOW);
}
}
ISR(INT1_vect) {
client_data_ready= 1;
}
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=Infrared_ON" ) );
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
}
}
}

View file

@ -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 <WProgram.h>
#
# - 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

View file

@ -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);
}
}
}
}

View file

@ -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<h1>200 OK</h1>"));
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<STR_BUFFER_SIZE){
strbuf[i]=*str;
i++;
str++;
}
strbuf[i]='\0';
}
return(found);
}
int8_t analyse_cmd(char *str)
{
int8_t r=-1;
if (find_key_val(str,"cmd")){
if (*strbuf < 0x3a && *strbuf > 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("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0 </h1></p> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr><br><form METHOD=get action=\""));
plen=es.ES_fill_tcp_data(buf,plen,baseurl);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("\">"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h2> REMOTE LED is </h2> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));
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(" </font></h1><br> ") );
if(on_off){
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=3>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch off\"></form>"));
}
else {
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=2>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch on\"></form>"));
}
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p> V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));
return(plen);
}

View file

@ -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<h1>200 OK</h1>"));
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<STR_BUFFER_SIZE){
strbuf[i]=*str;
i++;
str++;
}
strbuf[i]='\0';
}
return(found);
}
int8_t analyse_cmd(char *str)
{
int8_t r=-1;
if (find_key_val(str,"cmd")){
if (*strbuf < 0x3a && *strbuf > 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("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0 </h1></p> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr><br><form METHOD=get action=\""));
plen=es.ES_fill_tcp_data(buf,plen,baseurl);
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("\">"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h2> Current Temperature is </h2> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));
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(" &#176C</font></h1><br> ") );
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=1>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Get Temperature\"></form>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p> V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));
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';
}

View file

@ -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<h1>200 OK</h1>"));
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<STR_BUFFER_SIZE){
strbuf[i]=*str;
i++;
str++;
}
strbuf[i]='\0';
}
return(found);
}
int8_t analyse_cmd(char *str)
{
int8_t r=-1;
if (find_key_val(str,"cmd")){
if (*strbuf < 0x3a && *strbuf > 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("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0 </h1></p> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr><br> <h2><font color=\"blue\">-- Put your ARDUINO online -- "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Control digital outputs "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Read digital analog inputs HERE "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(" <br></font></h2> ") );
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));
return(plen);
}

View file

@ -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 <avr/io.h>
#include <avr/pgmspace.h>
//#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<datalen){
buf[UDP_DATA_P+i]=data[i];
i++;
}
ck=checksum(&buf[IP_SRC_P], 16 + datalen,1);
buf[UDP_CHECKSUM_H_P]=ck>>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 */

View file

@ -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 <avr/pgmspace.h>
// 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 */
//@}

View file

@ -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)
#######################################

177
libraries/etherShield/net.h Normal file
View file

@ -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
//@}

1
libraries/readme.txt Normal file
View file

@ -0,0 +1 @@
For information on installing libraries, see: http://arduino.cc/en/Guide/Libraries

270
licht/licht.pde Normal file
View file

@ -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);
}

246
light.c Normal file
View file

@ -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);
}

37
light.txt Normal file
View file

@ -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. }

21
lm35/lm35.ino Normal file
View file

@ -0,0 +1,21 @@
#include <LiquidCrystal.h>
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);
}

225
matrix_01/matrix_01.pde Normal file
View file

@ -0,0 +1,225 @@
#include <TimerOne.h>
#include <MatrixFonts3x5.h>
#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);
}

162
matrix_02/matrix_02.pde Normal file
View file

@ -0,0 +1,162 @@
#include <TimerOne.h>
#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);
}

View file

@ -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);
}

37
ps2_kbd/ps2_kbd.pde Normal file
View file

@ -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 <ps2.h>
/*
* 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 */
}
}

52
ps2_mouse/ps2_mouse.pde Normal file
View file

@ -0,0 +1,52 @@
#include <ps2.h>
/*
* 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 */
}

View file

@ -0,0 +1,21 @@
#include <Wire.h>
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);
}

View file

@ -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);
}
}

View file

@ -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);
}