Ryuk-4
Published

Dynamic-C-library-I2C

Dynamic library in C for the management of the I2C- bus

IntermediateWork in progress331
Dynamic-C-library-I2C

Things used in this project

Hardware components

Barometric/Altimeter/Temperature Sensor Kit for NEO
×1
Temperature Sensor Kit for NEO
×1
UDOO NEO
UDOO NEO
×1

Code

I2C_snap-in.h

C/C++
Header file
#ifndef I2CSNAPIN_H
#define I2CSNAPIN_H

#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <sys/stat.h>

static const char *sensore = "/dev/i2c-1"; //pathname del device
static const double p0 = 101326; //temperatura sul livello del mare

static int fd;// file descriptor
static uint8_t buffer[2]; /*buffer utilizzato per la temp(MSB, LSB)*/
static uint8_t buffer1[3]; /*buffer utilizzato per la press(MSB,CSB,LSB)*/
static __s32 STATUS;//contiene il valore del Sensor Status Register (0x00) 
static int16_t data;/*variabile di appoggio utilizzata per il riordino dei bit*/
static int32_t data1;/*variabile di appoggio utilizzata per il riordino dei bit*/
static int16_t CSB;/*contiene i bit CSB della pressione*/
static int16_t LSB;/*contiene i bit LSB della pressione*/
static float temperatura;
static float pressione;
static float alt;

int Enable(unsigned int I2C_ADDR);//funzione che abilita il device
void GetRawData(int fd, unsigned int I2C_ADDR);//interroga il device restituendo i raw data
void GetData(int fd, unsigned int I2C_ADDR, float* temperatura, float* pressione, float* alt);//restituisce i valori di temp(C),
void Disable(int fd);//funzione che disabilita il device									  // press(kPa) e alt(m)	

void Enable_Gpio();//funzione che abilita la gpio per l'accensione del led
void setHigh(int d);//imposta il valore alto sul led
void setLow(int d);//imposta il valore basso sul led
#endif

I2C.c

C/C++
#include <stdio.h>
#include <math.h>
#include "I2C_snap-in.h"


void Enable_Gpio(){
	
	FILE * fp_export;
	FILE * fp_dir;

	fp_export = fopen ("/sys/class/gpio/export", "w");//apre in modalita' di scrittura il file export
	fprintf(fp_export, "%d", 16);
	fclose(fp_export);
  
	fp_export = fopen ("/sys/class/gpio/export", "w");
	fprintf(fp_export, "%d", 124);
	fclose(fp_export);
	
	fp_dir = fopen ("/sys/class/gpio/gpio16/direction", "w");//assegna il valore output al led
	fprintf(fp_dir,  "out"  );
	
	fclose(fp_dir);
	
    fp_dir = fopen ("/sys/class/gpio/gpio124/direction", "w");
	fprintf(fp_dir,  "out"  );
	
	fclose(fp_dir);

}

void setHigh(int d){

	FILE * fp_val;
	switch(d){
		
		case 16:
			fp_val = fopen ("/sys/class/gpio/gpio16/value", "w");//apre in modalita' di scrittura il file value
			fprintf(fp_val,  "1"  );//assegna il valore alto al led
			fclose(fp_val);
			break;
		
		case 124:
			fp_val = fopen ("/sys/class/gpio/gpio124/value", "w");
			fprintf(fp_val,  "1"  );
			fclose(fp_val);
			break;
	}
}

void setLow(int d){

	FILE * fp_val;
	switch(d){
		
		case 16:
			fp_val = fopen ("/sys/class/gpio/gpio16/value", "w");
			fprintf(fp_val,  "0"  );//assegna il valore basso al led
			fclose(fp_val);
			break;
		
		case 124:
			fp_val = fopen ("/sys/class/gpio/gpio124/value", "w");
			fprintf(fp_val,  "0"  );
			fclose(fp_val);
			break;
	}
  
}

int Enable(unsigned int I2C_ADDR){
    
     fd=0;
    if ((fd = open(sensore, O_RDWR)) < 0 ){//controlla se il device e' collegato alla board
		printf("%d\n",fd);
		perror("Can't find the device\n");
		exit(1);
    }
    
    if ((ioctl(fd, I2C_SLAVE, I2C_ADDR)) < 0){//verifica se la board riesce a comunicare con il device
		perror("Can't talk with the device\n");
		exit(1);
	}
	
	if (I2C_ADDR==0x60){
		 
	     //Abilito event flags
		 i2c_smbus_write_word_data(fd, 0x13, 0x07);
			
         // Setto One Shot
		 i2c_smbus_write_word_data(fd, 0x26, 0xB9);
	}
	
    return fd;
}

void GetRawData(int fd, unsigned int I2C_ADDR){
         
     printf("Reading from %s at address: 0x%.2X\n\n", sensore, I2C_ADDR);
	 
	 if(I2C_ADDR==0x60){
		 //Setto la frequenza di campionamento a 128
		i2c_smbus_write_word_data(fd, 0x26, (0x38 | 0x01 | 0x00));
		
		STATUS = 0;
		
		do{												 //Verifica che i
			STATUS = i2c_smbus_read_byte_data(fd, 0x00); //dati siano disponibili 
		} while((STATUS & 0x08) == 0);					 //sul bus	
		
				
		buffer1[0] = i2c_smbus_read_word_data(fd, 0x01); //MSB
		buffer1[1] = i2c_smbus_read_word_data(fd, 0x02); //CSB
		buffer1[2] = i2c_smbus_read_word_data(fd, 0x03); //LSB
						
		printf("Pressure raw data get from register: 0x%.2X%.2X%.2X\n\n", buffer1[0], buffer1[1], buffer1[2]);
		
		buffer[0] = i2c_smbus_read_word_data(fd, 0x04); //MSB
		buffer[1] = i2c_smbus_read_word_data(fd, 0x05); //LSB
		printf(" Temperature raw data get from register: 0x%.2X%.2X\n\n", buffer[0], buffer[1]);
			
	 }
	 
	 else if(I2C_ADDR==0x48){
			if (read(fd, buffer, 3) != 3 ){
				perror("Can't read from bus i2c");
				exit(1);
			}
			printf("Temperature raw data get from register: 0x%.2X%.2X\n\n", buffer[0], buffer[1]);
	 }
	 else
			perror("ERROR\n");
}

void GetData(int fd, unsigned int I2C_ADDR, float* temperatura, float* pressione, float* alt){
           	
	 switch(I2C_ADDR) {
		 case 0x48:
			
			if (read(fd, buffer, 3) != 3 ){
			perror("Can't read from bus i2c");
			exit(1);
			} 
					
			//riordino i bit per la temperatura
			data =  buffer[0];		
			data = data << 8; //SLL
             
			data = data | buffer[1]; // OR inclusivo
			data = data >> 4; //SRL
			
			*temperatura = data*0.062500;
			printf("Decimal temperature value: %u\n\n", data);
			printf("The temperature is: %f C\n\n", *temperatura);
								
			break;
			
		case 0x60:
			
			i2c_smbus_write_word_data(fd, 0x26, (0x38 | 0x01 | 0x00));
			
			STATUS = 0;
			
			do{												 //Verifica che i
				STATUS = i2c_smbus_read_byte_data(fd, 0x00); //dati siano disponibili
			} while((STATUS & 0x08) == 0); 					 //sul bus
					
			buffer1[0] = i2c_smbus_read_word_data(fd, 0x01); //P_MSB
			buffer1[1] = i2c_smbus_read_word_data(fd, 0x02); //P_CSB
			buffer1[2] = i2c_smbus_read_word_data(fd, 0x03); //P_LSB	
			buffer[0] = i2c_smbus_read_word_data(fd, 0x04);  //T_MSB
			buffer[1] = i2c_smbus_read_word_data(fd, 0x05);  //T_LSB
						
			//riordino i bit per la temperatura
			data =  buffer[0];		
			data = data << 8; //SLL
             
			data = data | buffer[1]; // OR inclusivo
			data = data >> 4; //SRL
			
						
			//riordino i bit per la pressione
			data1=0;
			*pressione = 0.0;
			
			data1 = buffer1[0];
			data1 <<= 12;
						
			CSB = buffer1[1];
			CSB <<= 4;
			data1 |= CSB;
			
			LSB = buffer1[2];
			LSB >>= 4;
			data1 |= LSB;
						
			*pressione = data1*0.00025; // Moltipiplicare per il fattore  di scala (0.00025)
								       // per ottenere kPa	
			
			*temperatura = data*0.062500;
			printf("Decimal temperature value: %u\n\n", data);
			printf("The temperature is: %f C\n\n\n", *temperatura);
			
			printf("Decimal pressure value: %u\n\n\n", data1);
			printf("The pression is: %f kPa\n\n\n", *pressione);
			
			*alt = 44330.77*(1- pow((((*pressione)*1000)/p0),0.1902632));  
			printf("The height is: %f m\n\n\n", *alt);
					
			
			break;
	
		default: 
			perror("ERROR\n");
	}		
     
      
    
     
}

void Disable(int fd){
	
     if(close(fd) < 0){
        printf("ERROR!!!\n");
     }		
     else{	
	printf("Successfully completed\n\n");
     }
     
}

Credits

Ryuk-4

Ryuk-4

1 project • 1 follower

Comments