In this article you can find instruction on how to make a simple ethernet cable tester driven by an Arduino.
I was inspired by this page that simply and clearly describes how to make a tester for ethernet cables (straight or cross) with a master and a slave unit, so to be able to test also cable already in place.
I did nothing more than following the instructions and writing few lines of code for Arduino.
Hardware
What you need:
eight LED
eight resistor (I’ve used 33 ohm resistors)
two ethernet plug (female)
a switch (to be able to test straight and cross cables)
and, obviously, wires and two small pieces of board
We need to build to separate small boards:
a master board, that will be inserted into the Arduino and that will be plugged into one side of the ethernet cable that we need to test
a slave board, that will be plugged into the other side of the ethernet cable that we need to test
This is the circuit:
Software
The process implemented with the software is very simple:
Arduino set an HIGH value (5 V) on each wire of the cable for one second (and then reset a LOW value) one wire after the other
If everything is ok, you should see LEDs on the slave unit turning on one after the other for one second each
If there is some broken wire, the corresponding LED will not turn on
If there is some inverted wire in the cable, you will see the LEDs turning on not in a sequential order
The switch tells Arduino the type of cable under test (straight or cross)
The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.
Here’s an excerpt:
A San Francisco cable car holds 60 people. This blog was viewed about 1.400 times in 2011. If it were a cable car, it would take about 23 trips to carry that many people.
The DS1307 serial real-time clock (RTC) is a low-power, full binary-coded decimal (BCD) clock/calendar plus 56 bytes of NV SRAM.
Address and data are transferred serially through an I2C, bidirectional bus.
The lock/calendar provides seconds, minutes, hours, day, date, month, and year information.
The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for leap year.
The clock operates in either the 24-hour or 12-hour format with AM/PM indicator.
The DS1307 has a built-in power-sense circuit that detects power failures and automatically switches to the battery supply.
So the main differences between DS1307 and PCF8563 are:
Although not expressly stated, DS1307 works only at I2C standard mode (100 kbit/s) while PCF8563 can also work at I2C fast mode (400 kbit/s). This means that if you need to build a fast I2C circuit, as I need, you have to use PCF8563 (because every I2C component of the circuit has to be capable of running at fast mode), otherwise you can use DS1307 (that is much more common)
DS1307 accept a standard 3V alternate power supply (a lithium cell battery, for example) that in case of failure of the primary power supply can back up the RTC for a long time even (a lithium battery with 48mAhr or greater will back up
the DS1307 for more than 10 years)
DS1307 does not have the possibility to manage alarm and timer (countdown), as PCF8563 can do
Other minor differences exists on how registers are organized
This is register organization of DS1307 (click to enlarge):
This is the PIN configuration of DS1307 (DIP8 package – from DS1307 datasheet):
Where:
X1 = oscillator input
X2 = oscillator output
VBAT = backup supply input for any standard 3V lithium cell
GND = ground
SDA = serial data input and output
SCL = serial clock input
SQL/OUT = square wave/output driver
VCC = primary power supply
With respect to PCF8563, as far as pin configuration is concerned, the only difference is the presence of the alternate power supply pin (VBAT) in place of the interrupt pin of PCF8563 (INT). This means that if you are using only basic functions of the RTC (set date & time and get date & time) DS1307 and PCF8563 are pin-compatible.
The circuit is exactly the same as the PCF8563 (since we are not using neither alarms, timers, interrupts nor a backup battery):
Software
The code is slightly different from the code of the PCF8563. The only differences are:
DS1307 7 bit address is 68 (hexadecimal), while PCF8563 address is 51 (hexadecimal)
when reading seconds, DS1307 does not raise a bit if the integrity of the clock is not guaranteed (as PCF8563 do)
week day goes from 1 to 7 in DS1307 while goes from 0 to 6 in PCF8563
as seen, registry organization is a little bit different:
DS1307 does not have the century register
DS1307 does not have alarm and timer registers
Day and weekday registers are in reverse order
DS1307 has one control register that is the last register (PCF8563 has two control registers in first position)
Once again, the code is optimized, in a way that Arduino ask to the RTC only pieces of information that changed: this way the code can be added to an existing complex application without breaking anything (hopefully).
#include <Wire.h>//I2C header file// Defines//#define DEBUG // Uncomment to turn on verbose mode#define I2C_RTC 0x68 // 7 bit address (without last bit - look at the datasheet)#define ERROR_LED 13// Errors#define ERROR_RTC_SET 1 // Unable to set RTC time and date#define ERROR_RTC_GET 2 // Unable to get RTC time and date// Global variables
byte result;
byte second;
byte second_old;// The code ask the RTC for data only when the previous value has changed
byte minute;
byte minute_old;// The code ask the RTC for data only when the previous value has changed
byte hour;
byte hour_old;// The code ask the RTC for data only when the previous value has changed
byte weekday;
byte day;
byte month;
byte year;char* weekdayname[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};// Function prototypes
byte BcdToDec(byte);
byte DecToBcd(byte);void SetError(int);void setup(){
pinMode(ERROR_LED, OUTPUT);// Set error LED
Wire.begin();// Initiate the Wire library and join the I2C bus as a master
Serial.begin(9600);// Initiate serial communication// Set initial date and time
second_old = second =53;// Second (0-59)
minute_old = minute =59;// Minute (0-59)
hour_old = hour =23;// Hour (0-23)
weekday =1;// Day of the week (1-7)
day =31;// Day (1-31)
month =12;// Month (1-12)
year =11;// Year (0-99)
Wire.beginTransmission(I2C_RTC);// Select RTC
Wire.send(0);// Start address
Wire.send(DecToBcd(second));// Second
Wire.send(DecToBcd(minute));// Minute
Wire.send(DecToBcd(hour));// Hour
Wire.send(DecToBcd(weekday));// Weekday
Wire.send(DecToBcd(day));// Day
Wire.send(DecToBcd(month));// Month (with century bit = 0)
Wire.send(DecToBcd(year));// Year
Wire.send(0b10000);// Output clock frequency enabled (1 Hz)
Wire.endTransmission();
result = Wire.endTransmission();#ifdef DEBUG
Serial.print("Result of setting date and time: ");
Serial.println(result, DEC);#endifif(result) SetError(ERROR_RTC_SET);}void loop(){
Wire.beginTransmission(I2C_RTC);
Wire.send(0);// Start address
result = Wire.endTransmission();#ifdef DEBUG
Serial.print("Result of asking for date and time: ");
Serial.println(result, DEC);#endifif(result) SetError(ERROR_RTC_GET);
Wire.requestFrom(I2C_RTC,1);
second = BcdToDec(Wire.receive());if(second != second_old)// Cycle begins only when it has changed{
second_old = second;if(second ==0)// If second is zero I need to ask for the minute{
Wire.requestFrom(I2C_RTC,1);
minute = BcdToDec(Wire.receive());if(minute != minute_old)// Cycle begins only when it has changed{
minute_old = minute;if(minute ==0)// If minute is zero I need to ask for the hour{
Wire.requestFrom(I2C_RTC,1);
hour = BcdToDec(Wire.receive()&0b111111);if(hour != hour_old)// Cycle begins only when it has changed{
hour_old = hour;if(hour ==0)// If hour is zero I need to ask for other elements{
Wire.requestFrom(I2C_RTC,4);
weekday = BcdToDec(Wire.receive());
day = BcdToDec(Wire.receive());
month = BcdToDec(Wire.receive());
year = BcdToDec(Wire.receive());}}}}}
Serial.print(weekdayname[weekday -1]);
Serial.print("(");
Serial.print(weekday, DEC);
Serial.print(") 20");if(year <10) Serial.print("0");
Serial.print(year, DEC);
Serial.print("-");if(month <10) Serial.print("0");
Serial.print(month,DEC);
Serial.print("-");if(day <10) Serial.print("0");
Serial.print(day, DEC);
Serial.print("");if(hour <10) Serial.print("0");
Serial.print(hour,DEC);
Serial.print(":");if(minute <10) Serial.print("0");
Serial.print(minute, DEC);
Serial.print(":");if(second <10) Serial.print("0");
Serial.println(second, DEC);}}// Converts a BCD (binary coded decimal) to decimal
byte BcdToDec(byte value){return((value /16)*10+ value %16);}// Converts a decimal to BCD (binary coded decimal)
byte DecToBcd(byte value){return(value /10*16+ value %10);}void SetError(int error)// Blinks forever the error led a number of times corresponding to error number{while(1)// Forever{for(byte index =0; index < error; index++){
digitalWrite(ERROR_LED, HIGH);
delay(500);
digitalWrite(ERROR_LED, LOW);
delay(500);}
delay(1000);}}
The final result
Finally, this is the video of the DS1307 connected to the arduino. Look at what happens when I detach one of the I2C lines…