[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