Great job, congrats!
Thanks! Just made up DB9 to 3-pin female header cable, writing a sketch now to check out the serial port.
Don't you just love breathing life into a new board? When it works of course
It's looking real good Bob.
Rob
Yeah, when it works! I am 100% confident in the hardware, getting the software to play nice is the tricky part.
Since I unique-a-fied my pins_arduino.c file for just this board, I have some fooling around to do now to use my '328 boards.
Anyway, back to an RTC sketch.
Tomorrow, I guess, contacts are getting pretty dry ...
Graynomad:
Don't you just love breathing life into a new board? When it works of course
Well, if it does not work, well then you have not breathed life into it
So everyone, Bob has worked his butt off on this board. The least we can all do is buy one from him!
Thanks for the plug! XD
Here is the pins_arduino.c that I have been using that works with many processors.
pins_arduino.c (13.8 KB)
Thanks mnmis.
This section (actually the 2 above it, but the end results are obvious in this one) show the resulting pin mapping from PA-1 ... PD-7 to the D0-D31 that show up on the actual IO. My board uses them somewhat differently.
I will modify this to reflect mine & check it out. I had the hardest time getting this info pulled in by the IDE, finally resorting to removing everything but my 1284 needs.
If I had understood how this worked when I was assigning pin usage on the board, I may have assigned pin usage differently.
As it was, I tried to match pin usages to reflect the Duemilanove pin usage on shield headers for maximum compatibility.
const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
NOT_ON_TIMER, /* 0 - PB0 */
NOT_ON_TIMER, /* 1 - PB1 */
NOT_ON_TIMER, /* 2 - PB2 */
TIMER0A, /* 3 - PB3 */
TIMER0B, /* 4 - PB4 */
NOT_ON_TIMER, /* 5 - PB5 */
NOT_ON_TIMER, /* 6 - PB6 */
NOT_ON_TIMER, /* 7 - PB7 */
NOT_ON_TIMER, /* 8 - PD0 */
NOT_ON_TIMER, /* 9 - PD1 */
NOT_ON_TIMER, /* 10 - PD2 */
NOT_ON_TIMER, /* 11 - PD3 */
TIMER1B, /* 12 - PD4 */
TIMER1A, /* 13 - PD5 */
TIMER2B, /* 14 - PD6 */
TIMER2A, /* 15 - PD7 */
NOT_ON_TIMER, /* 16 - PC0 */
NOT_ON_TIMER, /* 17 - PC1 */
NOT_ON_TIMER, /* 18 - PC2 */
NOT_ON_TIMER, /* 19 - PC3 */
NOT_ON_TIMER, /* 20 - PC4 */
NOT_ON_TIMER, /* 21 - PC5 */
NOT_ON_TIMER, /* 22 - PC6 */
NOT_ON_TIMER, /* 23 - PC7 */
NOT_ON_TIMER, /* 24 - PA0 */
NOT_ON_TIMER, /* 25 - PA1 */
NOT_ON_TIMER, /* 26 - PA2 */
NOT_ON_TIMER, /* 27 - PA3 */
NOT_ON_TIMER, /* 28 - PA4 */
NOT_ON_TIMER, /* 29 - PA5 */
NOT_ON_TIMER, /* 30 - PA6 */
NOT_ON_TIMER /* 31 - PA7 */
CrossRoads,
Keeping pin compatibly across the different processors isn't too high on my priority.
I just keep track of the pin differences and update the code when necessary.
Mnmis
mnnis,
That seemed to work.
I copied in my pin order, spot checked a couple.
If pito hadn't mentioned the arrays in the file & what they represented, I woudn't have figured this out.
I am not sure why having the 1284 info separate from this file, in the arduino-extras folder, didn't work either.
So, I am moving on. RTC I2C testing next, then finding something I can talk to via SPI, and finally checking out the SD cards.
8)..the best way to test the spi is to read/write the sdcards.. quite curious how to work with two sdcards in parallel.. ]
Btw, for testing purposes the "Bitlash" is a really useful tool. It takes ~29kB (together with sdfat) and then you must not upload a sketch everytime, when debugging hw (it is a cli_like interpreter/scripting language)..
there is a sdcard support built in..p.
skyjumper:
...The least we can all do is buy one from him!
Sign me up!
@pito,
The cards each have their own SS line and are individually accessed.
I am getting a weird error from the compiler for this code to read the 8 registers on the DS1307:
// Reset the register pointer
Wire.beginTransmission(RTC_address);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTC_address, 8 );
seconds = Wire.receive();
minutes = Wire.receive();
hours = Wire.receive();
day_week = Wire.receive();
date_month = Wire.receive();
month = Wire.receive();
year = Wire.receive();
sqwe = Wire.receive();
The same variables all compile okay for writing to the registers earlier in the sketch.
This line is highlighted:
Wire.requestFrom(RTC_address, 8 );
RTC_I2C_test.cpp: In function 'void loop()':
RTC_I2C_test:166: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
C:\Program Files\Arduino-0022\libraries\Wire/Wire.h:53: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
C:\Program Files\Arduino-0022\libraries\Wire/Wire.h:52: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
RTC_I2C_test.cpp: At global scope:
RTC_I2C_test:215: error: expected declaration before '}' token
How is RTC_address declared?
RTC_address declared as a byte.
byte RTC_address = 0x68; // 1101 000
// 0 1101 000, 0x68, or 1101 000 0 0xD0 ??
Hmm, looks like it needs to an int, compiles now.
Thanks for the idea to look at that.
Pressing on ...
Woohoo, I2C & RTC Work, as does Square Wave Output (demonstrated via flashing LED).
/*
Test of RTC DS1307 via I2C.
Counts
Seconds,
Minutes,
Hours,
Date of the Month,
Month,
Day of the week, and
Year with Leap-Year
56 bytes battery backed RAM
Square Wave Output, can connect to INT2/D6 or PD7
*/
#include <Wire.h>
//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6, bits 3-2-1-0 = units of seconds, 0-9
byte minutes_address = 0x01;
byte minutes; // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes
byte hours_address = 0x02;
byte hours; // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 = lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
byte day_week_address = 0x03;
byte day_week = 0; // range 01-07
byte date_month_address = 0x04;
byte date_month = 0; // range 01-31
byte month_address = 0x05;
byte month = 0; // range 01-12
byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9
byte square_address = 0x07;
byte sqwe = 0; // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz
byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F
int RTC_address = 0x68; // 1101 000
byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;
// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back
// use C0xx to read RAM back
byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;
void setup() {
Wire.begin(); // no address, we are master
Serial1.begin (57600);
Serial1.flush();
currentMillis = millis();
}
void loop() {
if (Serial1.available() >1){
incomingCommand = Serial1.read();
//incomingRegister = Serial.read();
incomingData = Serial1.read();
Serial1.print ("command ");
Serial1.println (incomingCommand & 0xF0, HEX);
Serial1.print ("register ");
Serial1.println(incomingCommand & 0x0F, HEX);
Serial1.print ("data ");
Serial1.println (incomingData, HEX);
}
// *******************************************
RTC_write_command = incomingCommand & 0xF0; // mask off high byte
if (RTC_write_command == 0xF0){ // e033check for Write command
RTC_register = incomingCommand & 0x0F; // mask off low btye
incomingCommand = 0;
new_data = incomingData;
Serial1.print (" Sending a command ");
switch (RTC_register){
case 0: // write seconds
Serial1.println ("Seconds ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(seconds_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 1: // write minutes
Serial1.print ("Minutes ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(minutes_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 2: // write hours
Serial1.print ("Hours ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(hours_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 3: // write day
Serial1.print ("Day ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(day_week_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 4: // write date of month
Serial1.print ("Day of Month ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(date_month_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 5: // write month
Serial1.print ("Month ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(month_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 6: // write year
Serial1.print ("Year ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(year_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 7: // write square wave
Serial1.print ("Square Wave ");
Serial1.println (RTC_register, HEX);
Wire.beginTransmission(RTC_address); // select device
Wire.send(square_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 8: // write RAM
Serial1.print ("RAM ");
Serial1.println (RTC_register, HEX);
Wire.beginTransmission(RTC_address); // select device
Wire.send(RTC_ram_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
// all others,do nothing
Serial.println ("Invalid command ");
} // end Switch
} // end if command == F
// ************************************
currentMillis = millis();
if ( (currentMillis - previousMillis) >= duration){
previousMillis = currentMillis;
// Reset the register pointer
Wire.beginTransmission(RTC_address);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTC_address, 8 );
seconds = Wire.receive();
minutes = Wire.receive();
hours = Wire.receive();
day_week = Wire.receive();
date_month = Wire.receive();
month = Wire.receive();
year = Wire.receive();
sqwe = Wire.receive();
// Seconds
// bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6, bits 3-2-1-0 = units of seconds, 0-9
// Hours
// 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 = lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
Serial1.print ("Hrs " );
Serial1.print (hours, HEX);
Serial1.print (" Mins ");
Serial1.print (minutes, HEX);
Serial1.print (" Secs ");
Serial1.print (seconds, HEX);
Serial1.print (" Day ");
Serial1.print (day_week, HEX);
Serial1.print (" Date ");
Serial1.print (date_month, HEX);
Serial1.print (" Month ");
Serial1.print (month, HEX);
Serial1.print (" Year 20");
Serial1.print (year, HEX);
Serial1.print (" Square Wave ");
Serial1.println (sqwe, HEX);
}
}
Moniter output:
Hrs 1 Mins 54 Secs 27 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 32 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 37 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 42 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 47 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Tomorrow, SPI ... And see if the clock is running fast ...
@pito, was that cap on XTAL1 of the RTC suppose to make it go faster, slower, anything?
Has a 22pF cap now.
..as I wrote:
- do not deploy any cap
- if the clock goes fast then start to add a cap. The bigger the cap the slower the clock
- if the clock goes slow (and none cap there) exchange the xtal
- the cap would be typically 0 .. 15pf, but it depends on the xtal used
P.
PS: as far as I can remeber the clock system on arduino works in the way the arduino's internal clock is used (there is a Timer.c for sys time) and the internal clock is synchronised by the external RTC in a specific regular intervals (to be set, e.g. 300sec). The sdfat lib rely on the internal clock..
...
setSyncProvider(RTC.get); // the function to get the time from the actual RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
setSyncInterval(300); // set the number of seconds between re-sync of time
SdFile::dateTimeCallback(dateTime);
...
You have to link the time through a dateTime() callback function in order to use it with FAT.