I am working on a project using wire.h to address an i2c device.
I am trying to debug and would like to be able to send addresses to my device via the serial monitor.
I am having trouble trying to set it up proper. I wrote a quick test program to try and figure out how to change my variable to the proper coding.
I would like to be able to send 0x08 by #08 or 0xA4 by #A4. I would then take the result and go Wire.BeginTransmission(0x08);
int RecievedVaris="0x" & Vari1 & vari2;
Wire.BeginTransmission(RecievedVaris);
I think my trouble is I am trying to send a decimal encoded ascii character and translate it back to hex addressing. I've read so much stuff trying to figure it out, that I think I've confused myself!
void setup() {
Serial.begin(9600);
delay(1500);
Serial.println(" Please enter #-- to read as 0x--");
}
void loop() {
if(Serial.available()){
int TEXT =Serial.read();
Serial.print("SERIAL REC'd:");
Serial.println(TEXT, BYTE);
if(TEXT=='#'){
int Vari = Serial.read();
int Test = Vari;
String SERIALSTRING = Vari;
Vari = Serial.read();
SERIALSTRING =SERIALSTRING + Vari;
Serial.print("0x");Serial.print(Test,BYTE);Serial.print(Vari,BYTE);Serial.print(" = " );Serial.print("0x");Serial.println(SERIALSTRING);
Serial.print(Test,BYTE);Serial.print("= " );Serial.println(Vari,DEC);
Serial.print(Vari,BYTE);Serial.print("= " );Serial.println(Test,DEC);
int digit = Test - 'A' ;
Serial.println(digit);
//Wire.BeginTransmission('0x'+ Test & Vari);
}
}
}
A little off thread (but related), but pasted below is a nice little I2C troubleshooting sketch. It will output all possible I2C address and tell you if any devices respond by printing results on the serial monitor. I've found it very useful in the past.
/**
* I2CScanner.pde -- I2C bus scanner for Arduino
*
* 2009, Tod E. Kurt, http://todbot.com/blog/
*
*/
#include "Wire.h"
extern "C" {
#include "utility/twi.h" // from Wire library, so we can do bus scanning
}
// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
void(*callback)(byte address, byte result) )
{
byte rc;
byte data = 0; // not used, just an address to feed to twi_writeTo()
for( byte addr = from_addr; addr <= to_addr; addr++ ) {
rc = twi_writeTo(addr, &data, 0, 1);
callback( addr, rc );
}
}
// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
Serial.print("addr: ");
Serial.print(addr,HEX);
Serial.print( (result==0) ? " found!":" ");
Serial.print( (addr%4) ? "\t":"\n");
}
byte start_address = 1;
byte end_address = 127;
// standard Arduino setup()
void setup()
{
delay(2000);
Wire.begin();
Serial.begin(38400);
Serial.println("\nI2CScanner ready!");
Serial.print("starting scanning of I2C bus from ");
Serial.print(start_address,HEX);
Serial.print(" to ");
Serial.print(end_address,HEX);
Serial.println("...Hex");
// start the scan, will call "scanFunc()" on result from each address
scanI2CBus( start_address, end_address, scanFunc );
Serial.println("\ndone");
}
// standard Arduino loop()
void loop()
{
// Nothing to do here, so we'll just blink the built-in LED
digitalWrite(13,HIGH);
delay(300);
digitalWrite(13,LOW);
delay(300);
}
As the int digit value finally ends up containing a valid I2C binary value, it can be used directly by the I2C commands. You don't send 'hex' values to the wire library, you just send a single integer value parameter that contains a binary value of 0 to 127. Don't confuse how one represents via printing out a variable's value in a print statement, to the underlining value contained in the variable. The integers internal format is always just a 16 bit signed binary value.
Example:
//Function to read ADC conversion data from device
int adcRead(int deviceAdd) // read and return 16 bit analog voltage reading
{
int data;
Wire.beginTransmission(deviceAdd); // transmit to I2c device address
Wire.send(0x00); // point to device register 0, 16 bit ADC conversion results
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(deviceAdd, 2); // request 2 bytes from slave device
while(Wire.available()) // need two bytes, MSB and LSB of converstion result value
{
data = Wire.receive() << 8; // get MSB of reading and shift it to high byte
data += Wire.receive(); // add in LSB to data
}
return data;
}
if(Serial.available()){
int TEXT =Serial.read();
Serial.print("SERIAL REC'd:");
Serial.println(TEXT, BYTE);
if(TEXT=='#'){
int digit = Serial.read();
int digit2 = Serial.read();
So, if there is one byte available to read, read all 3 of them. Got it.
If it is, then read the next two bytes and convert them if they are valid hex numbers.
I'll post up one with comments and a little error checking later.
It was built quickly as a piece to include in a bigger program. It is just a way to test the serial data conversion, not as a fully fledged program.
Right, it should reply with a -1 if nothing is available.
It's checking if the first byte received is a #. Then it says okay, we're translating, grab the next two bytes that come in.
That was more just a proof of concept, not a final design.
By the way, I did test it on i2c. It worked beautifully
Here is the final code with error checking and comments.
Thanks guys!
Thank you lefty for explaining how the variables are stored, it's not what I'm used to.
/* Serial HEX text to Integer
Decodes two bytes of ascii endocded decimal hex
characters into one byte hex integer.
Designed for simple I2C debugging or addressing.
Created 2011
Turner Software Solutions
*/
void setup() {
// initalize serial at baud rate of 9600
Serial.begin(9600);
// delay so that upon upload you have time to hit the serial monitor button
delay(5000);
// remind yourself to use the proper formatting
Serial.println(" Please enter #-- to read as 0x--");
}
void loop() {
// Check if there is 3 or more bytes of data available.
if(Serial.available()>=3){
// read the first byte available.
int TEXT =Serial.read();
// Check if the byte is a #, if not all else will be ignored
if(TEXT=='#'){
// read/store second byte
int digit = Serial.read();
// read/store third byte
int digit2 = Serial.read();
// Check to see if second byte is a valid hex character
// and if it is a letter value, zero it to A, add 10... IE B = 1 + 10
// Then multiply by 16 to get the digit in first places value
if ((digit >= 'A') && (digit <= 'F')){digit = ((digit -'A') +10)*16;}
else if ((digit >= 'a') && (digit <= 'f')){digit = ((digit -'a') +10)*16;}
else if ((digit >= '0') && (digit <= '9')){digit = (digit -'0')*16;}
else {Serial.println("Please enter a hex number!!"); goto Error;}
// Check to see if third byte is a valid hex character, no need for x16.
if ((digit2 >= 'A') && (digit2 <= 'F')){digit2 = (digit2 -'A') +10;}
else if ((digit2 >= 'a') && (digit2 <= 'f')){digit2 = (digit2 -'a') +10;}
else if ((digit2 >= '0') && (digit2 <= '9')){digit2 = (digit2 -'0');}
else {Serial.println("Please enter a hex number!!"); goto Error;}
// Add the two value together to get the resultant value
digit = digit + digit2;
Serial.print("Decimal SUM="); Serial.println(digit);
Serial.print("HEX Value="); Serial.println(digit,HEX);
// Lets do something with this digit... like Wire.BeginTransmission(digit);
// or Wire.send(digit);
}
Error: // Just an easy way to stop proccessing the bytes
delay(1); // Delay
}
}