Hi I am struggling to get the sensor work with the Atmel Sam4s. I have verified UART comms works on a serial monitor and now connected the SPS30. I have also verified the serial communication is some how working because when i mess up the serial configuration the sensor int16_t sps30_probe(void);
does not run.
Here are my observations.
First I run sps30_probe()
. At some points it fails once but then it successfully probs.
I then set sps30_set_fan_auto_cleaning_interval_days
which does not return an error and that is ok.
I then set sps30_start_measurement
. Which reads ok. At this point I can hear the fan from the sensor.
The problem now comes on ret = sps30_read_measurement
. To start with i get ret = -2
then next loop iteration i get ret = 0
.
Can anyone help me please? Firstly to explain what is actually going on and secondly what i am doing wrong.
I am using the ASF library in Atmel Studio. The API is very easy to understand here http://asf.atmel.com/docs/latest/sam4c/html/group__buart__plc__group.html
Here is my main loop
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
sysclk_init();
board_init();
configUART();
configTWI();
adc_setup();
SetupUART0();
uint8_t uart0_i = 0, uart0_len;
char uart0_buf[20];
char ret_string[] = "";
char pm_string[] = "";
uint8_t len;
char buf;
struct sps30_measurement m;
char serial[SPS30_MAX_SERIAL_LEN];
const uint8_t AUTO_CLEAN_DAYS = 4;
int16_t ret;
while (sensirion_uart_open() != 0) {
sendBTMessage("SEND 15 UART init failed\n\r");
sensirion_sleep_usec(1000000); /* sleep for 1s */
}
sendBTMessage("SEND 15 UART opened\n\r");
//sendBTMessage (" UART 1 Alive \n\r");
/* Busy loop for initialization, because the main loop does not work without
* a sensor.
*/
while (sps30_probe() != 0) {
sendBTMessage("SEND 15 SPS30 sensor probing failed\n\r");
sensirion_sleep_usec(1000000); /* sleep for 1s */
}
sendBTMessage("SEND 15 SPS30 sensor probing successful\n\r");
ret = sps30_set_fan_auto_cleaning_interval_days(AUTO_CLEAN_DAYS);
if (ret) {
sprintf(ret_string, "SEND 15 error %d setting the auto-clean interval\n\r", ret);
sendBTMessage(ret_string);
} else {
sendBTMessage("SEND 15 fan stuff seem to be alright \n\r");
}
ret = sps30_start_measurement();
if (ret < 0) {
sendBTMessage("SEND 15 error starting measurement\n\r");
} else {
sendBTMessage("SEND 15 start measurement seem to be alright \n\r");
}
sendBTMessage("SEND 15 measurements started\n\r");
/* Insert application code here, after the board has been initialized. */
while (1) {
sendBTMessage ("SEND 15 testing PM \n\r");
ret = sps30_read_measurement(&m);
sprintf(ret_string, "SEND 15 reading message ret %d \n\r", ret);
sendBTMessage(ret_string);
if (ret < 0) {
sendBTMessage("SEND 15 error reading measurement\n\r");
} else {
if (SPS30_IS_ERR_STATE(ret)) {
sprintf(ret_string, "SEND 15 Chip state: %u - measurements may not be accurate\n\r", SPS30_GET_ERR_STATE(ret));
sendBTMessage(ret_string);
}
sprintf(pm_string, "SEND 15 measured values: 0.2f pm1.0, pm2.5 %0.2f, pm4.0 %0.2f, pm10.0 %0.2f, nc0.5 %0.2f, nc1.0 %0.2f, nc2.5 %0.2f nc4.5, %0.2f nc10.0, %0.2f typical particle size\n\r",
m.mc_1p0, m.mc_2p5, m.mc_4p0, m.mc_10p0, m.nc_0p5, m.nc_1p0,
m.nc_2p5, m.nc_4p0, m.nc_10p0, m.typical_particle_size);
sendBTMessage(pm_string);
sensirion_sleep_usec(1000000); /* sleep for 1s */
}
}
}
Here is my UART implementation.
int16_t sensirion_uart_select_port(uint8_t port) {
return 0;
}
int16_t sensirion_uart_open() {
return (buart_if_open(SERIAL_UART_0, 115200UL));
}
int16_t sensirion_uart_close() {
return (buart_if_close (SERIAL_UART_0));
}
int16_t sensirion_uart_tx(uint16_t data_len, const uint8_t *data) {
return buart_if_write (SERIAL_UART_0, data, data_len);
}
int16_t sensirion_uart_rx(uint16_t max_data_len, uint8_t *data) {
return buart_if_read (SERIAL_UART_0, (uint8_t *) data, max_data_len);
}
void sensirion_sleep_usec(uint32_t useconds) {
delay_us(useconds);
}