I am using a i2c sensor on my basys mx3 board for measuring distance. I've found a demo of this exact sensor with a library for this board and it works as it should. There are 8 leds on the board adresses with LATA, these represent the distance in centimeters to the object it is pointing at.
The goal is to retrieve the data in centimeters and put it in any accessible variable to print it over UART.
I expected to be able to retrieve the data before it was send to the leds but this seemed beyond my knowledge unfortunatly.
i've tried:
-printing the result that goes into the lata directly to uart(result)
-printing the exact same code that goes to the lata directly to uart (result[1])
-converting the char to an int and then later on print the value of the integer
-copying the data from the result to another char using memcopy (memcpy(distance[1], result[1], 20);) and then printing distance or distance[1] to the uart cmd line.
-retrieving the size of the data and printing it in a char variable sprintf(distance,"%d",sizeof(result[1]));
I do not know what other options i have maybe i am not looking at it the right way.
the code for the I2C library that i am using:
unsigned char I2C_Read(unsigned char slaveAddress,
unsigned char* dataBuffer,
unsigned char bytesNumber)
{
unsigned char status = 0;
unsigned char acknowledge = 0;
unsigned char byte = 0;
int cnt_timeout;
I2C1CONbits.RSEN = 1; // Initiate a start condition
cnt_timeout = 0;
while(I2C1CONbits.RSEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for start condition to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
I2C1TRN = (slaveAddress << 1) + 1;
cnt_timeout = 0;
while(I2C1STATbits.TRSTAT && (++cnt_timeout < I2C_WAIT_TIMEOUT)); // Wait for reception to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
acknowledge = I2C1STATbits.ACKSTAT;
if(acknowledge == 0) //Acknowledge was received
{
for(byte = 0; byte < bytesNumber; byte++)
{
I2C1CONbits.RCEN = 1; //Enable receive mode for I2C
if(byte == (bytesNumber - 1))
{
I2C1CONbits.ACKDT = 1;
}
else
{
I2C1CONbits.ACKDT = 0;
}
cnt_timeout = 0;
while(I2C1CONbits.RCEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for reception to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
dataBuffer[byte] = I2C1RCV;
I2C1CONbits.ACKEN = 1;
cnt_timeout = 0;
while(I2C1CONbits.ACKEN && (++cnt_timeout < I2C_WAIT_TIMEOUT));
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
}
}
else
{
status = 0xFF;
}
I2C1CONbits.ACKEN = 1; //Initiate Acknowledge sequence on SDAx and SCLx pins and transmit ACKDT data bit. Wait for Acknowledge sequence to complete
I2C1CONbits.PEN = 1; //Initiate a stop condition
cnt_timeout = 0;
while(I2C1CONbits.PEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for stop condition to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
return status;
}
the code i am using to read the sensor where LATA receives the right distance but any other variable isn't:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <sys/attribs.h>
#include "config.h"
#include "pragma.h"
#include "i2c.h"
#define ADDRESS 0x70
int main (void)
{
TRISA = 0x0;
LATA = 0xF;
I2C_Init(100000);
delay();
char tx_buff[2] = {0x00, 0x51};
char reg_add[1] = {0x02};
char result[2] = {};
while(1)
{
I2C_Write(ADDRESS, tx_buff, 2, 0); // beginnen met meten
delay();// minimaal 65 ms
I2C_Write(ADDRESS, reg_add, 1, 0);
I2C_Read(ADDRESS, result, 2);
delay();
LATA = result[1];
UART_PutString("measured distance is ");
UART_PutString(result);
UART_PutString("cm\n");
}
}
void delay ()
{
_CP0_SET_COUNT(0);
while (_CP0_GET_COUNT() < 4000000)
{
}
}