Çeviriyi Düzenle
I2C Code with Arduino(Sensor ID:0x58)
/**
******************************************************************************
* @file Sencoch_Sensor_0x58_Driver.ino
* @brief Generic I2C driver for Sencoch sensors with device address 0x58
* @version V2.0
* @date 2025-07-19
* @note Compatible with: Arduino Uno, Nano, Mega, ESP8266, ESP32, vesaire.
* Supports all Sencoch sensors with I2C address 0x58
******************************************************************************
*/
/*============================================================================*/
/* Pin Definitions */
/*============================================================================*/
#define SCL_PIN2
#define SDA_PIN3
/*============================================================================*/
/* Sencoch Sensor I2C Configuration */
/*============================================================================*/
#define SENCOCH_I2C_ADDR0x58
#define SENCOCH_REG_DATA0x04
#define SENCOCH_REG_EOF0x20
#define SENCOCH_REG_SHIFT0x21
/*============================================================================*/
/* Sencoch Sensor Parameters */
/*============================================================================*/
/*
* NOTE: Modify PMIN and PMAX according to your specific sensor model
*
* Common Ranges for I2C ADD 0x58 Sensors (unit: Pa):
* 0 ~ 0.5kPa: PMIN = 0.0f, PMAX = 500.0f
* 0 ~ 5kPa: PMIN = 0.0f, PMAX = 5000.0f
* 0 ~ 1000kPa: PMIN = 0.0f, PMAX = 1000000.0f
* -1 ~ 1kPa: PMIN = -1000.0f, PMAX = 1000.0f
* -5 ~ 5kPa: PMIN = -5000.0f, PMAX = 5000.0f
* -100 ~ 100kPa: PMIN = -100000.0f, PMAX = 100000.0f
*/
#define PMIN-100000.0f
#define PMAX100000.0f
/*============================================================================*/
/* Data Buffer Definitions */
/*============================================================================*/
#define SENCOCH_READ_LEN5
/*============================================================================*/
/* Public Data Structure */
/*============================================================================*/
typedef struct {
int32_t pressure_AD;
int16_t temperature_AD;
uint8_t temp_calib_offset_code;
uint8_t temp_calib_gain_exp;
int16_t eof_out;
float shift_n;
float basınç;
float sıcaklık;
} Sencoch_Sensor_Data_t;
/*============================================================================*/
/* Delay Function */
/*============================================================================*/
static void delay_us(uint32_t us)
{
delayMicroseconds(us);
}
/*============================================================================*/
/* I2C GPIO Initialization */
/*============================================================================*/
void I2C_Init(void)
{
pinMode(SCL_PIN, OUTPUT);
pinMode(SDA_PIN, OUTPUT);
digitalWrite(SCL_PIN, HIGH);
digitalWrite(SDA_PIN, HIGH);
}
/*============================================================================*/
/* I2C Timing Generation */
/*============================================================================*/
static void I2C_Start(void)
{
digitalWrite(SDA_PIN, HIGH);
delay_us(5);
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
digitalWrite(SDA_PIN, LOW);
delay_us(5);
digitalWrite(SCL_PIN, LOW);
delay_us(5);
}
static void I2C_Stop(void)
{
digitalWrite(SDA_PIN, LOW);
delay_us(5);
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
digitalWrite(SDA_PIN, HIGH);
delay_us(5);
}
static uint8_t I2C_WaitAck(void)
{
uint8_t ack= 0;
pinMode(SDA_PIN, INPUT_PULLUP);
delay_us(5);
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
if (digitalRead(SDA_PIN)) {
ack= 1;
}
digitalWrite(SCL_PIN, LOW);
delay_us(5);
pinMode(SDA_PIN, OUTPUT);
return ack;
}
static void I2C_SendByte(uint8_t byte)
{
for (uint8_t i= 0; i< 8; i++) {
digitalWrite(SCL_PIN, LOW);
delay_us(5);
if (byte& 0x80) {
digitalWrite(SDA_PIN, HIGH);
} else {
digitalWrite(SDA_PIN, LOW);
}
byte<<= 1;
delay_us(5);
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
}
digitalWrite(SCL_PIN, LOW);
delay_us(5);
}
static uint8_t I2C_ReadByte(uint8_t ack)
{
uint8_t byte= 0;
pinMode(SDA_PIN, INPUT_PULLUP);
for (uint8_t i= 0; i< 8; i++) {
byte<<= 1;
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
if (digitalRead(SDA_PIN)) {
byte|= 0x01;
}
digitalWrite(SCL_PIN, LOW);
delay_us(5);
}
pinMode(SDA_PIN, OUTPUT);
if (ack) {
digitalWrite(SDA_PIN, LOW);
} else {
digitalWrite(SDA_PIN, HIGH);
}
delay_us(5);
digitalWrite(SCL_PIN, HIGH);
delay_us(5);
digitalWrite(SCL_PIN, LOW);
delay_us(5);
return byte;
}
/*============================================================================*/
/* High-Level I2C Operations */
/*============================================================================*/
uint8_t Sencoch_ReadBytes(uint8_t reg_addr, uint8_t *data, uint8_t len)
{
I2C_Start();
I2C_SendByte(SENCOCH_I2C_ADDR<< 1);
if (I2C_WaitAck()) {
I2C_Stop();
return 1;
}
I2C_SendByte(reg_addr);
if (I2C_WaitAck()) {
I2C_Stop();
return 1;
}
I2C_Start();
I2C_SendByte((SENCOCH_I2C_ADDR<< 1) | 0x01);
if (I2C_WaitAck()) {
I2C_Stop();
return 1;
}
for (uint8_t i= 0; i< len; i++) {
data[i] = I2C_ReadByte(i< len- 1);
}
I2C_Stop();
return 0;
}
uint8_t Sencoch_ReadByte(uint8_t reg_addr)
{
uint8_t data;
Sencoch_ReadBytes(reg_addr, &data, 1);
return data;
}
/*============================================================================*/
/* Sencoch Sensor-Specific Operations */
/*============================================================================*/
static uint8_t Sencoch_ReadCalibration(Sencoch_Sensor_Data_t *data)
{
data->temp_calib_offset_code= Sencoch_ReadByte(SENCOCH_REG_EOF);
data->temp_calib_gain_exp= Sencoch_ReadByte(SENCOCH_REG_SHIFT);
switch (data->temp_calib_offset_code) {
case 0x0C: data->eof_out= 4096; break;
case 0x8C: data->eof_out= -4096; break;
case 0x0D: data->eof_out= 8192; break;
case 0x8D: data->eof_out= -8192; break;
case 0x0E: data->eof_out= 16384; break;
case 0x8E: data->eof_out= -16384; break;
default: data->eof_out= 0; break;
}
data->shift_n= pow(2, data->temp_calib_gain_exp/ 10.0f);
return 0;
}
static float Sencoch_ConvertPressure(int32_t raw)
{
const int32_t TWO_POW_21= 2097152;
return ((float)raw/ TWO_POW_21) * (PMAX- PMIN);
}
static float Sencoch_ConvertTemperature(int16_t raw, int16_t eof_out, float shift_n)
{
return ((float)(raw- eof_out) / shift_n) + 25.0f;
}
uint8_t Sencoch_ReadPressureAndTemp(Sencoch_Sensor_Data_t *data)
{
uint8_t raw_data[SENCOCH_READ_LEN];
int32_t pressure_raw;
int16_t temp_raw;
uint8_t result;
result= Sencoch_ReadBytes(SENCOCH_REG_DATA, raw_data, SENCOCH_READ_LEN);
if (result!= 0) {
return 1;
}
pressure_raw= ((int32_t)raw_data[0] << 16) |
((int32_t)raw_data[1] << 8) |
(int32_t)raw_data[2];
if (pressure_raw& 0x800000) {
pressure_raw|= 0xFF000000;
}
temp_raw= ((int16_t)raw_data[3] << 8) |
(int16_t)raw_data[4];
data->pressure_AD= pressure_raw;
data->temperature_AD= temp_raw;
Sencoch_ReadCalibration(data);
data->basınç= Sencoch_ConvertPressure(pressure_raw);
data->sıcaklık= Sencoch_ConvertTemperature(temp_raw, data->eof_out, data->shift_n);
return 0;
}
/*============================================================================*/
/* Setup Function */
/*============================================================================*/
void setup()
{
Serial.begin(115200);
Serial.println("I2C ADD 0x58 Sensor Driver Started");
Serial.println("==========================================");
Serial.print("Pressure Range: ");
Serial.print(PMIN);
Serial.print(" ~ ");
Serial.print(PMAX);
Serial.println(" Pa");
I2C_Init();
delay(100);
}
/*============================================================================*/
/* Loop Function */
/*============================================================================*/
void loop()
{
Sencoch_Sensor_Data_t sensor_data;
if (Sencoch_ReadPressureAndTemp(&sensor_data) == 0) {
Serial.print("Pressure: ");
Serial.print(sensor_data.pressure/ 1000.0f, 2);
Serial.print(" kPa| Sıcaklık: ");
Serial.print(sensor_data.temperature, 2);
Serial.println(" C");
} else {
Serial.println("Error: Sensor communication failed!");
}
delay(100);
}