[McHUG] Serial for debugging Arduino code
Rich Mitchell
geobra at att.net
Tue Nov 4 16:55:41 EST 2008
Pete,
Wire should be in the Arduino IDE. Theoretically it takes care of the send bit and is set up for 7 bit addresses. So in my version of your code (just the 2 Si570 functions) I'm not worrying about send/receive bits. You have to do a bit more if you have a device with an 8 bit address. The following is close to the sketch I was trying to run. It was an old copy that I updated so it may not compile. Not on my Arduino machine now. Will check it tonight.
/**********SKETCH BEGINS**************/
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
}
// real simple just to prove we are using the Si570
// no LCD etc - plan to make it a library once it works
void loop() {
unsigned long int f;
f = 7050000;
send_freq(f);
delay(1000);
f = 7060000;
send_freq(f);
delay(1000);
}
void send_freq(unsigned long int f)
{
unsigned long int FX = 114222749;
int FTABLE[50] = // frequency table in MHz x 10
{
40, 46, 53, 61, 69, 80, 91, 102, 116, 127,
141, 159, 182, 196, 212, 232, 255, 284, 320, 368,
427, 443, 513, 523, 553, 642, 674, 737, 857, 900,
1048,1105,1286,1348,1573,1735,2023,2207,2575,2697,
3148,3467,4048,4720,5152,5391,6280,6950,8090,9451
};
unsigned char HS_DIV[50] = // HS_DIV high-speed deivider table
{
11,11,11,11,11,11,11,11,11,11,
11,11,11,11,11,11,11,11,11,11,
11, 9,11, 9, 7,11, 7, 9,11, 6,
9, 6,11, 7, 9, 4, 7, 6,11, 5,
9, 4, 7, 6,11, 5, 9, 4, 7, 6
};
unsigned char N1[50] = // N1 output divider table
{
126,112, 96, 84, 74, 64, 56, 50, 44, 40,
36, 32, 28, 26, 24, 22, 20, 18, 16, 14,
12, 14, 10, 12, 14, 8, 12, 8, 6, 10,
6, 8, 4, 6, 4, 8, 4, 4, 2, 4,
2, 4, 2, 2, 1, 2, 1, 2, 1, 1
};
unsigned long int fdco; // dco frequency /2 in Hz
unsigned char rffreq_int; // rffreq integer
unsigned long int rffreq_man; // rffreq mantissa
unsigned long int r; // remainder in mantissa calculation
int fi; // f / 100000 for searching look-up table
unsigned char hs_div,n1; // si570 output divider nos.
unsigned char hs_div2, n12; // scaled si570 divider nos.
unsigned char i; // general indexer
fi = f/100000; // convert to f in MHz * 10
i = 0; // for look-up table
while(fi >= FTABLE[i]) i++; // find f in look-up table
hs_div = HS_DIV[i]; // get high-speed divider constant
n1 = N1[i]; // get output divider constant
/*************************************************************************************
The following code will scale down the dco frequency calculation by a factor of 2
to keep the dco frequency within the range of an unsigned long integer (32 bits). If
n1 is even, it is divided by 2. If n1 is odd (only above 472 MHz) and hs_div is
even, hs_div is divided by 2. For three frequency ranges above 472 MHz, both n1 and
hs_div are odd, so f is divided by 2 and 1 Hz resolution is reduced to 2 Hz resolution.
Note: rf_freq is scaled up by 2 later in the program to correct for the scaling
**************************************************************************************/
n12 = n1;
hs_div2 = hs_div;
if ((n1 % 2) && (hs_div % 2)) // if n1 and hs_div both odd
{
f = f>>1; // Scale f by 2
}
else if (n1 % 2) // if n1 is odd, hs_div is even
{
hs_div2 = hs_div>>1; // scale hs_div2 by 2
}
else // else (n1 is even)
{
n12 = n1>>1; // scale n12 by 2
}
fdco = f * hs_div2 * n12; // compute half dco freq
rffreq_int = (fdco / FX)<<1; // Compute rffreq integer value.
// Integer divide and multiply by 2
// ..(may increment by 1 later
// ..if mantissa *2 carry is a 1)
/************************************************************************************
Compute 29 bit mantissa using slow integer arithmetic method. Calculating mantissa to 29 bits,
truncating the mantissa to the 28 least significant bits, and using the 29th bit as a carry
is equivalent to multiplying the mantissa by 2. If the 29th bit (msb) is a 1 (the carry bit),
increment rffreq integer value by 1.
**************************************************************************************/
r = fdco % FX; // find remainder
r = r<<1; // shift remainder left 1 bit
if (r >= FX) // compute msb of 29 bits
{
rffreq_int++; // increment rffreq integer if msb = 1
r = r % FX; // find new remainder
}
r = r<<1; // shift remainder left 1 bit
rffreq_man = 0; // set mantissa to 0
for (i=0;i<28;i++) // compute mantissa 28 bits
{
if (r >= FX) // mantissa bit is a 1
{
rffreq_man = (rffreq_man<<1) + 1; // shift mantissa and add 1
r = r % FX; // calculate new remainder
}
else // mantissa bit is a 0
{
rffreq_man = rffreq_man<<1; // shift mantissa
}
r = r<<1; // shift remainder left
} // get next mantissa bit
update_si570(hs_div,n1,rffreq_int,rffreq_man); // write data to si570
}
// ............. function definition .................
void update_si570(unsigned char hs_d, unsigned char n1_d, unsigned char rffreq_int, unsigned long int rffreq_man) {
// unsigned char I2C_ADDR = 0x55;
unsigned char hs_div, n1, data, r137_data;
// unsigned char i2c_add;
// i2c_add = I2C_ADDR<<1; // shift 7-bit i2c address to 7 most significant bits
int i2c_add = 0x55;
// ..for the i2c library routines
hs_div = hs_d - 4;
n1 = n1_d - 1;
// read si570 register 137
r137_data = readI2CData (i2c_add, 137);
r137_data = 0x10 | r137_data; // set dco freeze bit to 1
sendI2CData(i2c_add, 137, r137_data); // freeze DCO
data = (hs_div<<5) + ((0x7f & n1)>>2);
sendI2CData(i2c_add, 7, data); // start at register 7
data = (n1<<6) + (rffreq_int>>4);
sendI2CData(i2c_add, 8, data); // register 8
data = (rffreq_int<<4) + ((0x0f000000 & rffreq_man)>>24);
sendI2CData(i2c_add, 9, data); // register 9
data = (0x00ff0000 & rffreq_man)>>16;
sendI2CData(i2c_add, 10, data); // register 10
data = (0x0000ff00 & rffreq_man)>>8;
sendI2CData(i2c_add, 11, data); // register 11
data = 0x000000ff & rffreq_man;
sendI2CData(i2c_add, 12, data); // register 12
r137_data = 0xef & r137_data; // set dc0 freeze bit to 0
sendI2CData(i2c_add, 137, r137_data); // unfreeze DCO
sendI2CData(i2c_add, 135, 0x40); // uset "new freq" bit to a 1
delay(10); // pause
}
// I2C send method
void sendI2CData(unsigned char i2c_add, int reg, unsigned char data) {
Wire.beginTransmission(i2c_add);
Wire.send(reg);
Wire.send(data);
Wire.endTransmission();
}
// I2C read method
unsigned char readI2CData(unsigned char i2c_add, int reg) {
unsigned char data;
Serial.print(i2c_add);
Serial.println(" is the device address.");
Serial.print(reg);
Serial.println(" is the device register.");
// setting the register
Wire.beginTransmission(i2c_add);
Wire.send(reg);
Serial.println("Ready to send register.");
Wire.endTransmission(); // send actually happens here.
Serial.println("Register was sent."); // I don't get this message
Wire.requestFrom(i2c_add, 1); // request 1 byte
while (Wire.available()) {
r137_data = Wire.receive();
}
Serial.print("Data retrieved was ");
Serial.println(data);
return data;
}
/**********SKETCH ENDS****************/
73,
Rich, N3III
--
McHUG - Physical Computing ;)
MicroController Ham User Group
-------------- Original message from "Peter Morton" <mortonph at comcast.net>: --------------
> Rich-
>
> Is the WIRE library part of the Arduino IDE or must it be downloaded from
> somewhere?
>
> -Pete, W3GVX
>
More information about the McHUG
mailing list