Start implementing AHT20 sensor reading
This commit is contained in:
5
Makefile
5
Makefile
@@ -78,6 +78,11 @@ distclean: clean
|
|||||||
$(E) "[REM] $(BINDIR)"
|
$(E) "[REM] $(BINDIR)"
|
||||||
$(Q) $(RMR) $(BINDIR)
|
$(Q) $(RMR) $(BINDIR)
|
||||||
|
|
||||||
|
.PHONY: listen
|
||||||
|
listen: ./opt/tools/serial-listen.py
|
||||||
|
$(E) "[PY3] $<"
|
||||||
|
$(Q) ./$<
|
||||||
|
|
||||||
$(TMPDIRS):
|
$(TMPDIRS):
|
||||||
$(E) "[DIR] $@"
|
$(E) "[DIR] $@"
|
||||||
$(Q) $(MKDIR) $@
|
$(Q) $(MKDIR) $@
|
||||||
|
|||||||
BIN
docs/AHT20.pdf
BIN
docs/AHT20.pdf
Binary file not shown.
@@ -77,6 +77,35 @@ int TWI_Write(unsigned char data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char TWI_Read_ACK(void)
|
||||||
|
{
|
||||||
|
// Read data and acknowledge
|
||||||
|
|
||||||
|
TWCR = (1 << TWEN) // Enable TWI
|
||||||
|
| (1 << TWINT) // Clear interrupt flag
|
||||||
|
| (1 << TWEA); // Send acknowledgment
|
||||||
|
|
||||||
|
// Wait until data read
|
||||||
|
|
||||||
|
while ((TWCR & (1 << TWINT)) == 0);
|
||||||
|
|
||||||
|
return TWDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char TWI_Read_NACK(void)
|
||||||
|
{
|
||||||
|
// Read data, expect last byte
|
||||||
|
|
||||||
|
TWCR = (1 << TWEN) // Enable TWI
|
||||||
|
| (1 << TWINT); // Clear interrupt flag
|
||||||
|
|
||||||
|
// Wait until data read
|
||||||
|
|
||||||
|
while ((TWCR & (1 << TWINT)) == 0);
|
||||||
|
|
||||||
|
return TWDR;
|
||||||
|
}
|
||||||
|
|
||||||
int TWI_Wait_ACK(void)
|
int TWI_Wait_ACK(void)
|
||||||
{
|
{
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ int TWI_Init(void);
|
|||||||
int TWI_Start(unsigned char addr, unsigned char mode);
|
int TWI_Start(unsigned char addr, unsigned char mode);
|
||||||
int TWI_SetChannel(int channel);
|
int TWI_SetChannel(int channel);
|
||||||
int TWI_Write(unsigned char data);
|
int TWI_Write(unsigned char data);
|
||||||
|
unsigned char TWI_Read_ACK(void);
|
||||||
|
unsigned char TWI_Read_NACK(void);
|
||||||
int TWI_Wait_ACK(void);
|
int TWI_Wait_ACK(void);
|
||||||
int TWI_Stop(void);
|
int TWI_Stop(void);
|
||||||
|
|
||||||
|
|||||||
137
src/main.c
137
src/main.c
@@ -6,6 +6,136 @@
|
|||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
short TWI_ReadAHT20(void)
|
||||||
|
{
|
||||||
|
unsigned char data, crc;
|
||||||
|
|
||||||
|
// After the transmission is initiated, the first
|
||||||
|
// byte of the subsequent I2C transmission includes
|
||||||
|
// the 7-bit I2C device address 0x38 and a SDA
|
||||||
|
// direction bit.
|
||||||
|
|
||||||
|
// Soft reset device.
|
||||||
|
|
||||||
|
TWI_Start(0x38, 0);
|
||||||
|
TWI_Write(0xBA);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
// Wait 40ms after power-on.
|
||||||
|
|
||||||
|
Sleep(40);
|
||||||
|
|
||||||
|
// Before reading the temperature and humidity
|
||||||
|
// values, first check whether the calibration
|
||||||
|
// enable bit Bit [3] of the status word is 1 (you
|
||||||
|
// can get a byte of status word by sending 0x71).
|
||||||
|
|
||||||
|
TWI_Start(0x38, 0);
|
||||||
|
TWI_Write(0x71);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
|
||||||
|
data = TWI_Read_NACK();
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
Info("Received calibration status %02X.", data);
|
||||||
|
|
||||||
|
// If not 1, need to send 0xBE command (for
|
||||||
|
// initialization), this command parameter has two
|
||||||
|
// bytes, the first byte is 0x08, the second byte
|
||||||
|
// is 0x00, and then wait for 10ms.
|
||||||
|
|
||||||
|
if (data & ~BIT(3)) {
|
||||||
|
Info("Requesting calibration...");
|
||||||
|
|
||||||
|
TWI_Start(0x38, 0);
|
||||||
|
TWI_Write(0xBE);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Write(0x08);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Write(0x00);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
|
||||||
|
Sleep(10);
|
||||||
|
data = TWI_Read_NACK();
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
if (data & ~BIT(3)) {
|
||||||
|
Info("Error: Calibration failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the 0xAC command directly (trigger
|
||||||
|
// measurement). The parameter of this command has
|
||||||
|
// two bytes, the first byte is 0x33 and the second
|
||||||
|
// byte is 0x00.
|
||||||
|
|
||||||
|
Info("Triggering measurement...");
|
||||||
|
|
||||||
|
TWI_Start(0x38, 0);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Write(0xAC);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Write(0x33);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Write(0x00);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
// Wait for 80ms to wait for the measurement to be
|
||||||
|
// completed. If the read status word Bit [7] is 0,
|
||||||
|
// it indicates that the measurement is completed,
|
||||||
|
// and six bytes can be read in a row. Otherwise
|
||||||
|
// continue to wait.
|
||||||
|
|
||||||
|
Info("Reading measurement...");
|
||||||
|
|
||||||
|
TWI_Start(0x38, 1); // Read
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
|
||||||
|
do {
|
||||||
|
Sleep(80);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
} while (data & BIT(7));
|
||||||
|
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
data = TWI_Read_ACK();
|
||||||
|
Info("Received data byte %02X.", data);
|
||||||
|
|
||||||
|
// After receiving six bytes, the next byte is the
|
||||||
|
// CRC check data, the user can read it as needed,
|
||||||
|
// if the receiving end needs CRC check, then send
|
||||||
|
// it after receiving the sixth byte ACK response,
|
||||||
|
// otherwise NACK is sent out, CRC initial value is
|
||||||
|
// 0xFF. The CRC8 check polynomial is:
|
||||||
|
// CRC[7:0]= 1 + (x^4) + (x^5) + (x^8)
|
||||||
|
|
||||||
|
crc = TWI_Read_NACK();
|
||||||
|
Info("Received CRC8 byte %02X.", crc);
|
||||||
|
|
||||||
|
// Calculate the temperature and humidity values.
|
||||||
|
// Note: The calibration status check in the first
|
||||||
|
// step only needs to be checked at power-on. No
|
||||||
|
// operation is required during the normal
|
||||||
|
// acquisition process.
|
||||||
|
|
||||||
|
// TODO: Calculate values
|
||||||
|
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
USART_Init();
|
USART_Init();
|
||||||
@@ -27,7 +157,14 @@ int main(void)
|
|||||||
// TODO: Set FAN03 timer frequency
|
// TODO: Set FAN03 timer frequency
|
||||||
// TODO: Implement ADS1115 and AHT20
|
// TODO: Implement ADS1115 and AHT20
|
||||||
|
|
||||||
|
// TEM01, TEM02, TEM03
|
||||||
|
// HUM01, HUM02, HUM03
|
||||||
|
|
||||||
|
// TWI_GetValue(TEM03)
|
||||||
|
// TWI_GetValue(HUM03)
|
||||||
|
|
||||||
TWI_SetChannel(AHT01); // I2C Mux
|
TWI_SetChannel(AHT01); // I2C Mux
|
||||||
|
TWI_ReadAHT20(); // TEMP and RH
|
||||||
|
|
||||||
Info("Running idle loop...");
|
Info("Running idle loop...");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user