A LoRa APRS node with KISS interface based on a Raspberry Pi Pico
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
4.2 KiB

/*********************************************************************************
*
* lora_aprs_node_pico is a LoRa APRS KISS modem with additional PE1RXF telemetry
* capabilities. It runs on a Raspberry Pi Pico.
*
* (C)2023 M.T. Konstapel https://meezenest.nl/mees
*
* This file is part of lora_aprs_node_pico.
*
* lora_aprs_node_pico is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lora_aprs_node_pico is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lora_aprs_node_pico. If not, see <https://www.gnu.org/licenses/>.
*
**********************************************************************************/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "i2c_sensor.h"
/*******************************************************************************
* Function Definitions
*/
// Write 1 byte to the specified register
int reg_write( i2c_inst_t *i2c,
const uint addr,
const uint8_t reg,
uint8_t *buf,
const uint8_t nbytes) {
int num_bytes_read = 0;
uint8_t msg[nbytes + 1];
// Check to make sure caller is sending 1 or more bytes
if (nbytes < 1) {
return 0;
}
// Append register address to front of data packet
msg[0] = reg;
for (int i = 0; i < nbytes; i++) {
msg[i + 1] = buf[i];
}
// Write data to register(s) over I2C
i2c_write_timeout_us(i2c, addr, msg, (nbytes + 1), false, 1000000);
return num_bytes_read;
}
// Read byte(s) from specified register. If nbytes > 1, read from consecutive
// registers.
int reg_read( i2c_inst_t *i2c,
const uint addr,
const uint8_t reg,
uint8_t *buf,
const uint8_t nbytes) {
int num_bytes_read = 0;
// Check to make sure caller is asking for 1 or more bytes
if (nbytes < 1) {
return 0;
}
// Read data from register(s) over I2C
i2c_write_timeout_us(i2c, addr, &reg, 1, true, 1000000);
num_bytes_read = i2c_read_timeout_us(i2c, addr, buf, nbytes, false, 1000000);
return num_bytes_read;
}
/*******************************************************************************
* Initialize
*/
int initAM2315(void) {
int16_t humidity;
int16_t temperature;
// Ports
i2c_inst_t *i2c = i2c1;
// Buffer to store raw reads
uint8_t data[6];
//Initialize I2C port at 100 kHz
i2c_init(i2c, 100 * 1000);
// Initialize I2C pins
gpio_set_function(PIN_SDA, GPIO_FUNC_I2C);
gpio_set_function(PIN_SCL, GPIO_FUNC_I2C);
gpio_pull_up(PIN_SDA);
gpio_pull_up(PIN_SCL);
// Wake up AM2315
reg_write(i2c, AM2315_I2CADDR, AM2315_READREG, data, 1);
sleep_ms(10);
// Request read registers from AM2315
data[0]=0x00;// start at address 0x0
data[1]=4;// request 4 bytes data
reg_write(i2c, AM2315_I2CADDR, AM2315_READREG, data, 3);
// Actual read registers
reg_read(i2c, AM2315_I2CADDR, AM2315_READREG, data, 8);
if (data[0] != AM2315_READREG) {
return 1;
}
return 0;
}
int ReadAM2315(int16_t* humidity, int16_t* temperature){
// Ports
i2c_inst_t *i2c = i2c1;
// Buffer to store raw reads
uint8_t data[6];
// Wake up AM2315
reg_write(i2c, AM2315_I2CADDR, AM2315_READREG, data, 1);
sleep_ms(10);
// Request read registers from AM2315
data[0]=0x00;// start at address 0x0
data[1]=4;// request 4 bytes data
reg_write(i2c, AM2315_I2CADDR, AM2315_READREG, data, 3);
// Actual read registers
reg_read(i2c, AM2315_I2CADDR, AM2315_READREG, data, 8);
// Convert 2 bytes (little-endian) into 16-bit integer (signed)
*humidity = (int16_t)((data[2] << 8) | data[3]);
*temperature = (int16_t)((data[4] << 8) | data[5]);
}