Merge pull request #54 from alanbjohnston/dev-py

python sensor reading
pull/58/head
alanbjohnston 5 years ago committed by GitHub
commit 2a1cab1afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,13 +1,11 @@
all: DEBUG_BEHAVIOR=
all: libax5043.a
all: radioafsk
all: radiocw
all: telem
debug: DEBUG_BEHAVIOR = -DDEBUG_LOGGING
debug: libax5043.a
debug: radioafsk
debug: radiocw
debug: telem
rebuild: clean
@ -17,7 +15,6 @@ lib: libax5043.a
clean:
rm -f radiochat
rm -f radiocw
rm -f radiopiglatin
rm -f testax5043rx
rm -f testax5043tx
@ -55,13 +52,6 @@ radiochat: libax5043.a
radiochat: chat/chat_main.o
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o radiochat -pthread -L./ chat/chat_main.o -lwiringPi -lax5043
radiocw: libax5043.a
radiocw: cw/cw_main.o
radiocw: afsk/ax25.o
radiocw: afsk/ax5043.o
radiocw: afsk/send_afsk.o
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o radiocw -L./ afsk/ax25.o afsk/ax5043.o afsk/send_afsk.o cw/cw_main.o -lwiringPi -lax5043
radiopiglatin: libax5043.a
radiopiglatin: piglatin/piglatin_main.o
gcc -std=gnu99 $(DEBUG_BEHAVIOR) -o radiopiglatin -pedantic -Wall -Wextra -L./ piglatin/piglatin_main.o -lwiringPi -lax5043
@ -236,20 +226,11 @@ afsk/main.o: afsk/status.h
afsk/main.o: afsk/ax5043.h
afsk/main.o: afsk/ax25.h
afsk/main.o: ax5043/spi/ax5043spi.h
afsk/main.o: afsk/Adafruit_INA219.h
cd afsk; gcc -std=gnu99 $(DEBUG_BEHAVIOR) -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c main.c; cd ..
afsk/telem.o: afsk/telem.c
afsk/telem.o: afsk/Adafruit_INA219.h
cd afsk; gcc -std=gnu99 $(DEBUG_BEHAVIOR) -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c telem.c; cd ..
afsk/send_afsk.o: afsk/send_afsk.c
afsk/send_afsk.o: afsk/send_afsk.h
afsk/send_afsk.o: afsk/status.h
afsk/send_afsk.o: afsk/ax5043.h
afsk/send_afsk.o: afsk/ax25.h
cd afsk; gcc -std=gnu99 $(DEBUG_BEHAVIOR) -I ../ax5043 -pedantic -Wconversion -Wall -Wextra -c send_afsk.c; cd ..
cw/cw_main.o: cw/cw_main.c
cw/cw_main.o: ax5043/spi/ax5043spi.h
cw/cw_main.o: ax5043/spi/ax5043spi_p.h

@ -58,6 +58,14 @@ Remove the following text in cmdline.txt to prevent a console from running on th
Press Ctrl-X then type `y` then hit Enter to save the file and exit the editor. You should back at the pi@... prompt.
Now install the python packages:
`sudo apt install -y python3-pip python-smbus`
`sudo pip3 install --upgrade setuptools`
`sudo pip3 install adafruit-blinka RPI.GPIO adafruit-extended-bus adafruit-circuitpython-ina219`
Reboot by typing:
`sudo reboot now`
@ -160,7 +168,7 @@ Press and release after two blinks of green LED: switches to FSK mode. After abo
Press and release after three blinks of green LED: switches to BPSK mode. After about 5 seconds, the telemetry mode will switch to BPSK.
Press and release after four blinks of green LED: switches to SSTV mode. SSTV images in PD120 mode will be transmitted instead of telemetry.
Press and release after four blinks of green LED: switches to SSTV mode. After about 5 seconds, the telemetry mode will switch to SSTV transmitting PD120 mode SSTV.
Press and release after green LED begins slow blinking: shuts down CubeSatSim.

@ -1,154 +0,0 @@
/*!
* @file Adafruit_INA219.h
*
* This is a library for the Adafruit INA219 breakout board
* ----> https://www.adafruit.com/products/904
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Kevin "KTOWN" Townsend for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
* Converted to C for Raspberry Pi by Alan Johnston KU2Y
*
*/
#include <wiringPi.h>
/** default I2C address **/
#define INA219_ADDRESS (0x40) // 1000000 (A0+A1=GND)
/** read **/
#define INA219_READ (0x01)
/*=========================================================================
CONFIG REGISTER (R/W)
**************************************************************************/
/** config register address **/
#define INA219_REG_CONFIG (0x00)
/** reset bit **/
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
/** mask for bus voltage range **/
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
/** bus voltage range values **/
enum {
INA219_CONFIG_BVOLTAGERANGE_16V = (0x0000), // 0-16V Range
INA219_CONFIG_BVOLTAGERANGE_32V = (0x2000), // 0-32V Range
};
/** mask for gain bits **/
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
/** values for gain bits **/
enum {
INA219_CONFIG_GAIN_1_40MV = (0x0000), // Gain 1, 40mV Range
INA219_CONFIG_GAIN_2_80MV = (0x0800), // Gain 2, 80mV Range
INA219_CONFIG_GAIN_4_160MV = (0x1000), // Gain 4, 160mV Range
INA219_CONFIG_GAIN_8_320MV = (0x1800), // Gain 8, 320mV Range
};
/** mask for bus ADC resolution bits **/
#define INA219_CONFIG_BADCRES_MASK (0x0780)
/** values for bus ADC resolution **/
enum {
INA219_CONFIG_BADCRES_9BIT = (0x0000), // 9-bit bus res = 0..511
INA219_CONFIG_BADCRES_10BIT = (0x0080), // 10-bit bus res = 0..1023
INA219_CONFIG_BADCRES_11BIT = (0x0100), // 11-bit bus res = 0..2047
INA219_CONFIG_BADCRES_12BIT = (0x0180), // 12-bit bus res = 0..4097
};
/** mask for shunt ADC resolution bits **/
#define INA219_CONFIG_SADCRES_MASK \
(0x0078) // Shunt ADC Resolution and Averaging Mask
/** values for shunt ADC resolution **/
enum {
INA219_CONFIG_SADCRES_9BIT_1S_84US = (0x0000), // 1 x 9-bit shunt sample
INA219_CONFIG_SADCRES_10BIT_1S_148US = (0x0008), // 1 x 10-bit shunt sample
INA219_CONFIG_SADCRES_11BIT_1S_276US = (0x0010), // 1 x 11-bit shunt sample
INA219_CONFIG_SADCRES_12BIT_1S_532US = (0x0018), // 1 x 12-bit shunt sample
INA219_CONFIG_SADCRES_12BIT_2S_1060US =
(0x0048), // 2 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_4S_2130US =
(0x0050), // 4 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_8S_4260US =
(0x0058), // 8 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_16S_8510US =
(0x0060), // 16 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_32S_17MS =
(0x0068), // 32 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_64S_34MS =
(0x0070), // 64 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_128S_69MS =
(0x0078), // 128 x 12-bit shunt samples averaged together
};
/** mask for operating mode bits **/
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
/** values for operating mode **/
enum {
INA219_CONFIG_MODE_POWERDOWN,
INA219_CONFIG_MODE_SVOLT_TRIGGERED,
INA219_CONFIG_MODE_BVOLT_TRIGGERED,
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED,
INA219_CONFIG_MODE_ADCOFF,
INA219_CONFIG_MODE_SVOLT_CONTINUOUS,
INA219_CONFIG_MODE_BVOLT_CONTINUOUS,
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS
};
/** shunt voltage register **/
#define INA219_REG_SHUNTVOLTAGE (0x01)
/** bus voltage register **/
#define INA219_REG_BUSVOLTAGE (0x02)
/** power register **/
#define INA219_REG_POWER (0x03)
/** current register **/
#define INA219_REG_CURRENT (0x04)
/** calibration register **/
#define INA219_REG_CALIBRATION (0x05)
/*!
* functions for interacting with INA219
* current/power monitor IC
*/
//void begin(TwoWire *theWire = &Wire);
void setCalibration_32V_2A(int fd);
void setCalibration_32V_1A(int fd);
void setCalibration_16V_400mA(int fd);
void setCalibration_16V_2A(int fd);
float getBusVoltage_V(int fd);
float getShuntVoltage_mV(int fd);
float getCurrent_mA(int fd);
float getPower_mW(int fd);
void powerSave(int fd, int on);
uint8_t ina219_i2caddr;
//uint32_t ina219_calValue;
uint16_t ina219_calValue;
uint16_t ina219_config;
// The following multipliers are used to convert raw current and power
// values to mA and mW, taking into account the current config settings
uint32_t ina219_currentDivider_mA;
float ina219_powerMultiplier_mW;
void init();
void wireWriteRegister(int fd, uint8_t reg, uint16_t value);
uint16_t wireReadRegister(int fd, uint8_t reg);
int16_t getBusVoltage_raw(int fd);
int16_t getShuntVoltage_raw(int fd);
int16_t getCurrent_raw(int fd);
int16_t getPower_raw(int fd);

@ -1,18 +1,3 @@
/* make_wav.h
* Fri Jun 18 17:06:02 PDT 2010 Kevin Karplus
*/
#ifndef MAKE_WAV_H
#define MAKE_WAV_H
void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate);
/* open a file named filename, write signed 16-bit values as a
monoaural WAV file at the specified sampling rate
and close the file
*/
#endif
/*
* TelemEncoding.h
*
@ -559,4 +544,3 @@ int Encode_8b10b[][256] = {
/* ff */ 0x54e,
} };

@ -1,80 +0,0 @@
/*
* Modified from https://github.com/foglamp/foglamp-south-ina219/blob/develop/include/ina219.h
*
* FogLAMP south service plugin
*
* Copyright (c) 2018 Dianomic Systems
*
* Released under the Apache 2.0 Licence
*
* Author: Mark Riddoch
*/
/**
* Values for the gain setting
*/
enum {
INA219_CONFIG_GAIN_40MV = 0x0000, // 40mV Range
INA219_CONFIG_GAIN_80MV = 0x0800, // 80mV Range
INA219_CONFIG_GAIN_160MV = 0x1000, // 160mV Range
INA219_CONFIG_GAIN_320MV = 0x1800, // 320mV Range
};
enum
{
INA219_CONFIG_BVOLTAGERANGE_16V = 0x0000, // 0-16V Range
INA219_CONFIG_BVOLTAGERANGE_32V = 0x2000, // 0-32V Range
};
#define INA219_CONFIG_BADCRES_MASK 0x0780 // ADC Resulotion Mask
enum
{
INA219_CONFIG_BADCRES_9BIT = 0x0000, // 9-bit bus res = 0..511
INA219_CONFIG_BADCRES_10BIT = 0x0080, // 10-bit bus res = 0..1023
INA219_CONFIG_BADCRES_11BIT = 0x0100, // 11-bit bus res = 0..2047
INA219_CONFIG_BADCRES_12BIT = 0x0180, // 12-bit bus res = 0..4097
};
#define INA219_CONFIG_SADCRES_MASK 0x0078 // Mask for shunt ADC resolution bits
enum
{
INA219_CONFIG_SADCRES_9BIT_1S_84US = 0x00, // 1 x 9-bit shunt sample
INA219_CONFIG_SADCRES_10BIT_1S_148US = 0x08, // 1 x 10-bit shunt sample
INA219_CONFIG_SADCRES_11BIT_1S_276US = 0x10, // 1 x 11-bit shunt sample
INA219_CONFIG_SADCRES_12BIT_1S_532US = 0x18, // 1 x 12-bit shunt sample
INA219_CONFIG_SADCRES_12BIT_2S_1060US = 0x48, // 2 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_4S_2130US = 0x50, // 4 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_8S_4260US = 0x58, // 8 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_16S_8510US = 0x60, // 16 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_32S_17MS = 0x68, // 32 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_64S_34MS = 0x70, // 64 x 12-bit shunt samples averaged together
INA219_CONFIG_SADCRES_12BIT_128S_69MS = 0x78, // 128 x 12-bit shunt samples averaged together
};
#define INA219_CONFIG_MODE_MASK 0x0007 // Operating Mode Mask
enum {
INA219_CONFIG_MODE_POWERDOWN = 0x0000,
INA219_CONFIG_MODE_SVOLT_TRIGGERED = 0x0001,
INA219_CONFIG_MODE_BVOLT_TRIGGERED = 0x0002,
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED = 0x0003,
INA219_CONFIG_MODE_ADCOFF = 0x0004,
INA219_CONFIG_MODE_SVOLT_CONTINUOUS = 0x0005,
INA219_CONFIG_MODE_BVOLT_CONTINUOUS = 0x0006,
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS = 0x0007,
};
typedef enum {
CONF_16V_400MA,
CONF_32V_1A,
CONF_32V_2A
} INA219_CONFIGURATION;
/*
* INA219 Registers
*/
#define INA219_REG_CONFIG 0x00
#define INA219_REG_SHUNTVOLTAGE 0x01
#define INA219_REG_BUSVOLTAGE 0x02
#define INA219_REG_POWER 0x03
#define INA219_REG_CURRENT 0x04
#define INA219_REG_CALIBRATION 0x05

@ -1,5 +1,5 @@
/*
* Transmits CubeSat Telemetry at 434.9MHz in AO-7 format
* Transmits CubeSat Telemetry at 434.9MHz in AFSK, FSK, or BPSK format
*
* Copyright Alan B. Johnston
*
@ -17,9 +17,6 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code
* from https://github.com/adafruit/Adafruit_INA219.
*/
#include <fcntl.h>
@ -36,8 +33,7 @@
#include <wiringSerial.h>
#include <time.h>
#include <math.h>
#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino
#include "make_wav.h"
#include "TelemEncoding.h"
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
@ -54,12 +50,13 @@
#define PLUS_X 0
#define PLUS_Y 1
#define PLUS_Z 2
#define BAT 3
#define BAT 2
#define BUS 3
#define MINUS_X 4
#define MINUS_Y 5
#define MINUS_Z 6
#define BUS 7
#define PLUS_Z 6
#define MINUS_Z 7
#define OFF -1
#define ON 1
@ -111,11 +108,6 @@ void write_to_buffer(int i, int symbol, int val);
void write_wave(int i, short int *buffer);
int uart_fd;
//#define BUF_LEN (FRAME_CNT * (SYNC_BITS + 10 * (8 + 6 * DATA_LEN + 96)) * SAMPLES)
//#define BUF_LEN (FRAME_CNT * (SYNC_BITS + 10 * (HEADER_LEN + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN))) * SAMPLES)
//short int buffer[BUF_LEN];
//short int data10[HEADER_LEN + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)];
//short int data8[HEADER_LEN + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)];
int reset_count;
float uptime_sec;
long int uptime;
@ -126,139 +118,11 @@ float sleepTime;
int sampleTime = 0, frames_sent = 0;
int cw_id = ON;
int vB4 = FALSE, vB5 = FALSE, ax5043 = FALSE, transmit = FALSE, onLed, onLedOn, onLedOff, txLed, txLedOn, txLedOff, payload = OFF;
float batteryThreshold = 0;
struct SensorConfig {
int fd;
uint16_t config;
int calValue;
int powerMultiplier;
int currentDivider;
};
struct SensorData {
double current;
double voltage;
double power;
};
/**
* @brief Read the data from one of the i2c current sensors.
*
* Reads the current data from the requested i2c current sensor configuration and
* stores it into a SensorData struct. An invalid file descriptor (i.e. less than zero)
* results in a SensorData struct being returned that has both its #current and #power members
* set to NAN.
*
* @param sensor A structure containing sensor configuration including the file descriptor.
* @return struct SensorData A struct that contains the current, voltage, and power readings
* from the requested sensor.
*/
struct SensorData read_sensor_data(struct SensorConfig sensor) {
struct SensorData data = {
.current = 0,
.voltage = 0,
.power = 0 };
if (sensor.fd < 0) {
return data;
}
// doesn't read negative currents accurately, shows -0.1mA
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CALIBRATION, sensor.calValue);
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CONFIG, sensor.config);
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CALIBRATION, sensor.calValue);
sleep(0.01);
int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT);
if (value == -1)
{
sensor.fd = -1;
return data;
}
data.current = (float) twosToInt(value, 16) / (float) sensor.currentDivider;
wiringPiI2CWrite(sensor.fd, INA219_REG_BUSVOLTAGE);
delay(1); // Max 12-bit conversion time is 586us per sample
value = (wiringPiI2CRead(sensor.fd) << 8 ) | wiringPiI2CRead (sensor.fd);
data.voltage = ((float)(value >> 3) * 4) / 1000;
// power has very low resolution, seems to step in 512mW values
data.power = (float) wiringPiI2CReadReg16(sensor.fd, INA219_REG_POWER) * (float) sensor.powerMultiplier;
return data;
}
/**
* @brief Configures an i2c current sensor.
*
* Calculates the configuration values of the i2c sensor so that
* current, voltage, and power can be read using read_sensor_data.
* Supports 16V 400mA and 16V 2.0A settings.
*
* @param sensor A file descriptor that can be used to read from the sensor.
* @param milliAmps The mA configuration, either 400mA or 2A are supported.
* @return struct SensorConfig A struct that contains the configuraton of the sensor.
*/
//struct SensorConfig config_sensor(int sensor, int milliAmps) {
struct SensorConfig config_sensor(char *bus, int address, int milliAmps) {
struct SensorConfig data;
if (access(bus, W_OK | R_OK) < 0) { // Test if I2C Bus is missing
printf("ERROR: %s bus not present\n Check raspi-config Interfacing Options/I2C and /boot/config.txt \n", bus);
data.fd = OFF;
return (data);
}
char result[128];
int pos = strlen(bus) / sizeof(bus[0]) - 1;
// printf("Bus size %d \n", pos);
// printf("Bus value %d \n", atoi(&bus[pos]));
char command[50] = "timeout 10 i2cdetect -y ";
strcat (command, &bus[pos]);
FILE *i2cdetect = popen(command, "r");
while (fgets(result, 128, i2cdetect) != NULL) {
;
// printf("result: %s", result);
}
int error = pclose(i2cdetect)/256;
// printf("%s error: %d \n", &command, error);
if (error != 0)
{
printf("ERROR: %s bus has a problem \n Check I2C wiring and pullup resistors \n", bus);
data.fd = OFF;
return (data);
}
data.fd = wiringPiI2CSetupInterface(bus, address);
data.config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
if (milliAmps == 400) { // INA219 16V 400mA configuration
data.calValue = 8192;
data.powerMultiplier = 1;
data.currentDivider = 20; // 40; in Adafruit config
}
else { // INA219 16V 2A configuration
data.calValue = 40960;
data.powerMultiplier = 2;
data.currentDivider = 10; // 20; in Adafruit config
}
#ifdef DEBUG_LOGGING
printf("Sensor %s %x configuration: %d %d %d %d %d\n", bus, address, data.fd,
data.config, data.calValue, data.currentDivider, data.powerMultiplier);
#endif
return data;
}
struct SensorConfig sensor[8]; // 8 current sensors in Solar Power PCB vB4/5
struct SensorData reading[8]; // 8 current sensors in Solar Power PCB vB4/5
struct SensorConfig tempSensor;
float batteryThreshold = 3.0, batteryVoltage;
const char pythonCmd[] = "python3 /home/pi/CubeSatSim/python/voltcurrent.py ";
char pythonStr[100], pythonConfigStr[100], busStr[10];
int map[8] = { 0, 1, 2, 3, 4, 5, 6, 7};
char src_addr[5] = "";
char dest_addr[5] = "CQ";
@ -396,7 +260,6 @@ int main(int argc, char *argv[]) {
onLed = 0;
onLedOn = HIGH;
onLedOff = LOW;
batteryThreshold = 3.0;
transmit = TRUE;
}
else
@ -414,10 +277,9 @@ int main(int argc, char *argv[]) {
onLed = 27;
onLedOn = HIGH;
onLedOff = LOW;
batteryThreshold = 3.0;
transmit = TRUE;
}
}
}
}
}
pinMode (txLed, OUTPUT);
@ -431,9 +293,6 @@ int main(int argc, char *argv[]) {
printf("Power LED On\n");
#endif
// if ((cycle == ON) && !ax5043) // don't cycle modes if using AX5043
// mode = (reset_count) % 3; // alternate between the three modes
config_file = fopen("sim.cfg","w");
fprintf(config_file, "%s %d", call, reset_count);
fclose(config_file);
@ -441,47 +300,41 @@ int main(int argc, char *argv[]) {
if (vB4)
{
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x44, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[PLUS_Z] = config_sensor("/dev/i2c-0", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-0", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-0", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-0", 0x45, 400);
map[BAT] = BUS;
map[BUS] = BAT;
strcpy(busStr,"1 0");
}
else if (vB5)
{
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x44, 400);
if (access("/dev/i2c-11", W_OK | R_OK) >= 0) { // Test if I2C Bus 11 is present
printf("/dev/i2c-11 is present\n\n");
sensor[PLUS_Z] = config_sensor("/dev/i2c-11", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-11", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-11", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-11", 0x45, 400);
strcpy(busStr,"1 11");
} else {
sensor[PLUS_Z] = config_sensor("/dev/i2c-3", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-3", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-3", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-3", 0x45, 400);
strcpy(busStr,"1 3");
}
}
else
{
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[PLUS_Z] = config_sensor("/dev/i2c-1", 0x44, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x4a, 2000);
sensor[MINUS_X] = config_sensor("/dev/i2c-0", 0x40, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-0", 0x41, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-0", 0x44, 400);
tempSensor = config_sensor("/dev/i2c-3", 0x48, 0);
map[BUS] = MINUS_Z;
map[BAT] = BUS;
map[PLUS_Z] = BAT;
map[MINUS_Z] = PLUS_Z;
strcpy(busStr,"1 0");
batteryThreshold = 8.0;
}
strcpy(pythonStr, pythonCmd);
strcat(pythonStr, busStr);
strcat(pythonConfigStr, pythonStr);
strcat(pythonConfigStr, " c");
// FILE* file1 = popen("python3 /home/pi/CubeSatSim/python/voltcurrent.py 1 11 c", "r");
FILE* file1 = popen(pythonConfigStr, "r");
char cmdbuffer[1000];
fgets(cmdbuffer, 1000, file1);
// printf("pythonStr result: %s\n", cmdbuffer);
pclose(file1);
// try connecting to Arduino payload using UART
if (!ax5043) // don't test if AX5043 is present
@ -530,56 +383,22 @@ else
//uint8_t data[1024];
tx_freq_hz -= tx_channel * 50000;
if (mode == AFSK)
sleep(10); // delay awaiting CW ID completion
/*
if (transmit == FALSE)
{
fprintf(stderr,"\nNo CubeSatSim Band Pass Filter detected. No transmissions after the CW ID.\n");
fprintf(stderr, " See http://cubesatsim.org/wiki for info about building a CubeSatSim\n\n");
}
// Send ID in CW (Morse Code)
cw_id = OFF;
if (cw_id == ON) // Don't send CW if using AX5043 or in mode cycling or set by 3rd argument
{
char cw_str[200];
char cw_header[] = "echo 'de ";
char cw_footer[] = "' > id.txt && gen_packets -M 20 id.txt -o morse.wav -r 48000 > /dev/null 2>&1 && cat morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.897e3";
strcpy(cw_str, cw_header);
//printf("Before 1st strcpy\n");
strcat(cw_str, call);
//printf("Before 1st strcpy\n");
strcat(cw_str, cw_footer);
//printf("Before 1st strcpy\n");
digitalWrite (txLed, txLedOn);
#ifdef DEBUG_LOGGING
printf("Tx LED On\n");
#endif
//printf("Before cmd\n");
//printf("CW String: %s\n", cw_str);
// FILE* f;
system(cw_str);
// printf("File %d \n", f);
// printf("close: %d \n", pclose(f)); // execute command and wait for termination before continuing
printf("After command\n");
// sleep(7);
//printf("Before Write\n");
digitalWrite (txLed, txLedOn);
#ifdef DEBUG_LOGGING
printf("Tx LED On\n");
#endif
//printf("After Write\n");
}
//printf("Done CW!\n");
*/
while (loop-- != 0)
{
frames_sent++;
float batteryVoltage = read_sensor_data(sensor[BAT]).voltage;
#ifdef DEBUG_LOGGING
fprintf(stderr,"INFO: Battery voltage: %f V Battery Threshold %f V\n", batteryVoltage, batteryThreshold);
#endif
@ -636,8 +455,10 @@ while (loop-- != 0)
bufLen = (frameCnt * (syncBits + 10 * (headerLen + rsFrames * (rsFrameLen + parityLen))) * samples);
// samplePeriod = ((float)((syncBits + 10 * (headerLen + rsFrames * (rsFrameLen + parityLen))))/(float)bitRate) * 1000 - 1800;
samplePeriod = 3000;
sleepTime = 3.0;
// samplePeriod = 3000;
// sleepTime = 3.0;
samplePeriod = 2200; // reduce dut to python and sensor querying delays
sleepTime = 2.2;
printf("\n BPSK Mode, bufLen: %d, %d bits per frame, %d bits per second, %d seconds per frame %d ms sample period\n",
bufLen, bufLen/(samples * frameCnt), bitRate, bufLen/(samples * frameCnt * bitRate), samplePeriod);
@ -683,21 +504,7 @@ while (loop-- != 0)
sleep(loop_count);
printf("Done sleeping\n");
}
/*
// int transmit = popen("timeout 1 sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.897e3","r");
int txResult = popen("sudo killall -9 rpitx > /dev/null 2>&1", "r");
pclose(txResult);
txResult = popen("sudo killall -9 sendiq > /dev/null 2>&1", "r");
pclose(txResult);
txResult = popen("sudo fuser -k 8080/tcp > /dev/null 2>&1", "r");
pclose(txResult);
if(cw_id == ON) // only turn off Power LED if CW ID is enabled (i.e. not demo.sh mode cycling)
digitalWrite (onLed, onLedOff);
#ifdef DEBUG_LOGGING
printf("Tx LED Off\n");
#endif
*/
return 0;
}
@ -754,44 +561,60 @@ for (int j = 0; j < frameCnt; j++)
memset(tlm, 0, sizeof tlm);
// Reading I2C voltage and current sensors
int count;
for (count = 0; count < 8; count++)
{
reading[count] = read_sensor_data(sensor[count]);
#ifdef DEBUG_LOGGING
// printf("Read sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// count, reading[count].voltage, reading[count].current, reading[count].power);
#endif
}
tlm[1][A] = (int)(reading[BUS].voltage /15.0 + 0.5) % 100; // Current of 5V supply to Pi
tlm[1][B] = (int) (99.5 - reading[PLUS_X].current/10.0) % 100; // +X current [4]
tlm[1][C] = (int) (99.5 - reading[MINUS_X].current/10.0) % 100; // X- current [10]
tlm[1][D] = (int) (99.5 - reading[PLUS_Y].current/10.0) % 100; // +Y current [7]
tlm[2][A] = (int) (99.5 - reading[MINUS_Y].current/10.0) % 100; // -Y current [10]
tlm[2][B] = (int) (99.5 - reading[PLUS_Z].current/10.0) % 100; // +Z current [10] // was 70/2m transponder power, AO-7 didn't have a Z panel
tlm[2][C] = (int) (99.5 - reading[MINUS_Z].current/10.0) % 100; // -Z current (was timestamp)
tlm[2][D] = (int)(50.5 + reading[BAT].current/10.0) % 100; // NiMH Battery current
tlm[3][A] = abs((int)((reading[BAT].voltage * 10.0) - 65.5) % 100);
tlm[3][B] = (int)(reading[BUS].voltage * 10.0) % 100; // 5V supply to Pi
int count1;
char *token;
char cmdbuffer[1000];
FILE* file = popen(pythonStr, "r");
fgets(cmdbuffer, 1000, file);
// printf("result: %s\n", cmdbuffer);
pclose(file);
const char space[2] = " ";
token = strtok(cmdbuffer, space);
if (ax5043)
{
if (tempSensor.fd != OFF) {
int tempValue = wiringPiI2CReadReg16(tempSensor.fd, 0);
uint8_t upper = (uint8_t) (tempValue >> 8);
uint8_t lower = (uint8_t) (tempValue & 0xff);
float temp = (float)lower + ((float)upper / 0x100);
float voltage[9], current[9];
memset(voltage, 0, sizeof(voltage));
memset(current, 0, sizeof(current));
for (count1 = 0; count1 < 8; count1++)
{
if (token != NULL)
{
voltage[count1] = atof(token);
#ifdef DEBUG_LOGGING
printf("Temp Sensor Read: %6.1f\n", temp);
printf("voltage: %f ", voltage[count1]);
#endif
tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100;
}
}
token = strtok(NULL, space);
if (token != NULL)
{
current[count1] = atof(token);
if ((current[count1] < 0) && (current[count1] > -0.5))
current[count1] *= (-1.0);
#ifdef DEBUG_LOGGING
printf("current: %f\n", current[count1]);
#endif
token = strtok(NULL, space);
}
}
}
tlm[1][A] = (int)(voltage[map[BUS]] /15.0 + 0.5) % 100; // Current of 5V supply to Pi
tlm[1][B] = (int) (99.5 - current[map[PLUS_X]]/10.0) % 100; // +X current [4]
tlm[1][C] = (int) (99.5 - current[map[MINUS_X]]/10.0) % 100; // X- current [10]
tlm[1][D] = (int) (99.5 - current[map[PLUS_Y]]/10.0) % 100; // +Y current [7]
tlm[2][A] = (int) (99.5 - current[map[MINUS_Y]]/10.0) % 100; // -Y current [10]
tlm[2][B] = (int) (99.5 - current[map[PLUS_Z]]/10.0) % 100; // +Z current [10] // was 70/2m transponder power, AO-7 didn't have a Z panel
tlm[2][C] = (int) (99.5 - current[map[MINUS_Z]]/10.0) % 100; // -Z current (was timestamp)
tlm[2][D] = (int)(50.5 + current[map[BAT]]/10.0) % 100; // NiMH Battery current
tlm[3][A] = abs((int)((voltage[map[BAT]] * 10.0) - 65.5) % 100);
tlm[3][B] = (int)(voltage[map[BUS]] * 10.0) % 100; // 5V supply to Pi
batteryVoltage = voltage[map[BAT]];
FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (cpuTempSensor) {
double cpuTemp;
@ -913,23 +736,12 @@ if (payload == ON)
#ifdef DEBUG_LOGGING
printf("Tx LED On\n");
#endif
//printf("Before cmd\n");
//printf("CW telem String: %s\n", cw_str2);
// FILE* f;
if (mode == CW)
if (mode == CW)
system(cw_str2);
// printf("File %d \n", f);
// printf("close: %d \n", pclose(f)); // execute command and wait for termination before continuing
//printf("After command\n");
// sleep(7);
//printf("Before Write\n");
digitalWrite (txLed, txLedOn);
#ifdef DEBUG_LOGGING
printf("Tx LED On\n");
#endif
//printf("After Write\n");
//}
//printf("Done CW!\n");
if (ax5043)
{
@ -986,24 +798,18 @@ if (payload == ON)
printf("Tx LED On\n");
#endif
}
//digitalWrite (txLed, txLedOff);
}
}
//printf("End of get_tlm and rpitx =========================================================\n");
digitalWrite (txLed, txLedOff);
#ifdef DEBUG_LOGGING
printf("Tx LED Off\n");
#endif
digitalWrite (txLed, txLedOff);
#ifdef DEBUG_LOGGING
printf("Tx LED Off\n");
#endif
return;
}
int get_tlm_fox() {
// memset(b, 0, 64);
// Reading I2C voltage and current sensors
@ -1061,16 +867,6 @@ int get_tlm_fox() {
{
if (firstTime != ON)
/*
{// digitalWrite (3, HIGH);
if (mode == BPSK)
sleep(3);
// sleep(3.5);
// digitalWrite (3, LOW);
}
if (mode == FSK)
*/
{
// delay for sample period
digitalWrite (txLed, txLedOn);
@ -1090,31 +886,47 @@ if (firstTime != ON)
sampleTime = millis();
} else
printf("first time - no sleep\n");
int count1;
char *token;
char cmdbuffer[1000];
int count;
for (count = 0; count < 8; count++)
{
reading[count] = read_sensor_data(sensor[count]);
#ifdef DEBUG_LOGGING
// printf("Read sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// count, reading[count].voltage, reading[count].current, reading[count].power);
#endif
}
/*
if (tempSensor.fd != OFF) {
int tempValue = wiringPiI2CReadReg16(tempSensor.fd, 0);
uint8_t upper = (uint8_t) (tempValue >> 8);
uint8_t lower = (uint8_t) (tempValue & 0xff);
float temp = (float)lower + ((float)upper / 0x100);
FILE* file = popen(pythonStr, "r");
fgets(cmdbuffer, 1000, file);
// printf("result: %s\n", cmdbuffer);
pclose(file);
const char space[2] = " ";
token = strtok(cmdbuffer, space);
float voltage[9], current[9];
memset(voltage, 0, sizeof(voltage));
memset(current, 0, sizeof(current));
for (count1 = 0; count1 < 8; count1++)
{
if (token != NULL)
{
voltage[count1] = atof(token);
#ifdef DEBUG_LOGGING
printf("Temp Sensor Read: %6.1f\n", temp);
printf("voltage: %f ", voltage[count1]);
#endif
TxTemp = (int)((temp * 10.0) + 0.5);
encodeB(b, 34 + head_offset, TxTemp);
}
*/
token = strtok(NULL, space);
if (token != NULL)
{
current[count1] = atof(token);
if ((current[count1] < 0) && (current[count1] > -0.5))
current[count1] *= (-1.0);
#ifdef DEBUG_LOGGING
printf("current: %f\n", current[count1]);
#endif
token = strtok(NULL, space);
}
}
}
// printf("\n");
FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (cpuTempSensor) {
double cpuTemp;
@ -1156,25 +968,27 @@ if (firstTime != ON)
if (mode == BPSK)
h[6] = 99;
// posXv = reading[PLUS_X].current;
posXi = (int)reading[PLUS_X].current + 2048;
posYi = (int)reading[PLUS_Y].current + 2048;
posZi = (int)reading[PLUS_Z].current + 2048;
negXi = (int)reading[MINUS_X].current + 2048;
negYi = (int)reading[MINUS_Y].current + 2048;
negZi = (int)reading[MINUS_Z].current + 2048;
posXv = (int)(reading[PLUS_X].voltage * 100);
posYv = (int)(reading[PLUS_Y].voltage* 100);
posZv = (int)(reading[PLUS_Z].voltage * 100);
negXv = (int)(reading[MINUS_X].voltage * 100);
negYv = (int)(reading[MINUS_Y].voltage * 100);
negZv = (int)(reading[MINUS_Z].voltage * 100);
posXi = (int)current[map[PLUS_X]] + 2048;
posYi = (int)current[map[PLUS_Y]] + 2048;
posZi = (int)current[map[PLUS_Z]] + 2048;
negXi = (int)current[map[MINUS_X]] + 2048;
negYi = (int)current[map[MINUS_Y]] + 2048;
negZi = (int)current[map[MINUS_Z]] + 2048;
posXv = (int)(voltage[map[PLUS_X]] * 100);
posYv = (int)(voltage[map[PLUS_Y]] * 100);
posZv = (int)(voltage[map[PLUS_Z]] * 100);
negXv = (int)(voltage[map[MINUS_X]] * 100);
negYv = (int)(voltage[map[MINUS_Y]] * 100);
negZv = (int)(voltage[map[MINUS_Z]] * 100);
batt_c_v = (int)(voltage[map[BAT]] * 100);
battCurr = (int)current[map[BAT]] + 2048;
PSUVoltage = (int)(voltage[map[BUS]] * 100);
PSUCurrent = (int)current[map[BUS]] + 2048;
if (payload == ON)
STEMBoardFailure = 0;
batt_c_v = (int)(reading[BAT].voltage * 100);
battCurr = (int)reading[BAT].current + 2048;
PSUVoltage = (int)(reading[BUS].voltage * 100);
PSUCurrent = (int)reading[BUS].current + 2048;
batteryVoltage = voltage[map[BAT]];
// if (payload == ON)
// STEMBoardFailure = 0;
@ -1477,64 +1291,11 @@ if (payload == ON)
int error = 0;
int count;
// for (count = 0; count < DATA_LEN; count++) {
// for (count = 0; count < dataLen; count++) {
// printf("%02X", b[count]);
// }
// printf("\n");
// rpitx
/*
char cmdbuffer[1000];
FILE* txResult;
if ((rpitxStatus != mode)) // || ((loop % 1000) == 0))
{ // change rpitx mode
rpitxStatus = mode;
printf("Changing rpitx mode!\n");
// txResult = popen("ps -ef | grep rpitx | grep -v grep | awk '{print $2}' | sudo xargs kill -9 > /dev/null 2>&1", "r");
txResult = popen("sudo killall -9 rpitx > /dev/null 2>&1", "r");
pclose(txResult);
// printf("1\n");
// sleep(1);
// txResult = popen("ps -ef | grep sendiq | grep -v grep | awk '{print $2}' | sudo xargs kill -9 > /dev/null 2>&1", "r");
txResult = popen("sudo killall -9 sendiq > /dev/null 2>&1", "r");
pclose(txResult);
// printf("2\n");
// digitalWrite (txLed, txLedOn);
sleep(1);
txResult = popen("sudo fuser -k 8080/tcp > /dev/null 2>&1", "r");
pclose(txResult);
socket_open = 0;
// printf("3\n");
sleep(1);
// digitalWrite (txLed, txLedOff);
if (transmit)
{
if (mode == FSK) {
// txResult = popen("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.896e3&", "r");
txResult = popen("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | while true; do sudo timeout -k 1 60m /home/pi/rpitx/rpitx -i- -m RF -f 434.897e3; done &", "r");
pclose(txResult);
// printf("4\n");
} else if (mode == BPSK) {
// txResult = popen("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/CubeSatSim/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.8925e6 -t float 2>&1&", "r");
txResult = popen("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | while true; do sudo timeout -k 1 60m /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.8945e6 -t float 2>&1; done &", "r");
pclose(txResult); }
// fgets(cmdbuffer, 1000, txResult);
}
else
{
fprintf(stderr,"\nNo CubeSatSim Band Pass Filter detected. No transmissions after the CW ID.\n");
fprintf(stderr, " See http://cubesatsim.org/wiki for info about building a CubeSatSim\n\n");
}
sleep(2);
// printf("Results of transmit command: %s\n", cmdbuffer);
}
*/
// socket write
if (!socket_open && transmit)

@ -1,92 +0,0 @@
/*
* A sample application transmitting AFSK at 1200 baud
*
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "status.h"
#include "ax5043.h"
#include "ax25.h"
#include "spi/ax5043spi.h"
ax5043_conf_t hax5043;
ax25_conf_t hax25;
static void init_rf();
void config_x25();
void trans_x25();
int main(void) {
setSpiChannel(SPI_CHANNEL);
setSpiSpeed(SPI_SPEED);
initializeSpi();
int ret;
uint8_t data[1024];
// 0x03 is a UI frame
// 0x0F is no Level 3 protocol
const char *str = "\x03\x0fThis is an AX.25 Packet from CubeSatSim!!!";
/* Infinite loop */
for (;;) {
sleep(2);
// send X.25 packet
init_rf();
ax25_init(&hax25, (uint8_t *) "CQ", '2', (uint8_t *) "DX", '2',
AX25_PREAMBLE_LEN,
AX25_POSTAMBLE_LEN);
printf("INFO: Transmitting X.25 packet\n");
memcpy(data, str, strnlen(str, 256));
ret = ax25_tx_frame(&hax25, &hax5043, data, strnlen(str, 256));
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
ax5043_wait_for_transmit();
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit entire AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
}
return 0;
}
static void init_rf() {
int ret;
ret = ax5043_init(&hax5043, XTAL_FREQ_HZ, VCO_INTERNAL);
if (ret != PQWS_SUCCESS) {
fprintf(stderr,
"ERROR: Failed to initialize AX5043 with error code %d\n", ret);
exit(EXIT_FAILURE);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,125 +0,0 @@
/*
* transmits a frame of AO-7 telemetry as 1k2 AFSK in X.25 format
*
* Portions Copyright (C) 2018 Jonathan Brandenburg
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "status.h"
#include "ax5043.h"
#include "ax25.h"
#include "spi/ax5043spi.h"
ax5043_conf_t hax5043;
ax25_conf_t hax25;
static void init_rf();
void config_x25();
void trans_x25();
extern int upper_digit(int number);
extern int lower_digit(int number);
int config_afsk() {
init_rf();
printf("INFO: Initiating radio for X.25\n");
ax25_init(&hax25, (uint8_t *) "CQ", '2', (uint8_t *) "DX", '2',
AX25_PREAMBLE_LEN,
AX25_POSTAMBLE_LEN);
return(1);
}
int send_afsk(int tlm[][5]) {
// printf("INFO: Configuring rf for X.25\n");
// setSpiChannel(SPI_CHANNEL);
// setSpiSpeed(SPI_SPEED);
// initializeSpi();
int ret;
uint8_t data[1024];
// 0x03 is a UI frame
// 0x0F is no Level 3 protocol
// rest is dummy CubeSatSim telemetry in AO-7 format
//const char *str = "\x03\x0fhi hi 101 102 103 104 202 203 204 205 303 304 305 306 404 405 406 407 408 505 506 507 508 606 607 608 609\n";
/* Infinite loop */
// for (;;) {
// sleep(2);
// send X.25 packet
printf("INFO: Preparing X.25 packet\n");
char str[1000];
char tlm_str[1000];
char header_str[] = "\x03\x0fhi hi ";
strcpy(str, header_str);
int channel;
for (channel = 1; channel < 7; channel++) {
// printf("%d %d %d %d \n", tlm[channel][1], tlm[channel][2], tlm[channel][3], tlm[channel][4]);
sprintf(tlm_str, "%d%d%d %d%d%d %d%d%d %d%d%d ",
channel, upper_digit(tlm[channel][1]), lower_digit(tlm[channel][1]),
channel, upper_digit(tlm[channel][2]), lower_digit(tlm[channel][2]),
channel, upper_digit(tlm[channel][3]), lower_digit(tlm[channel][3]),
channel, upper_digit(tlm[channel][4]), lower_digit(tlm[channel][4]));
// printf("%s \n",tlm_str);
strcat(str, tlm_str);
}
printf("INFO: Transmitting X.25 packet\n");
memcpy(data, str, strnlen(str, 256));
ret = ax25_tx_frame(&hax25, &hax5043, data, strnlen(str, 256));
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
ax5043_wait_for_transmit();
if (ret) {
fprintf(stderr,
"ERROR: Failed to transmit entire AX.25 frame with error code %d\n",
ret);
exit(EXIT_FAILURE);
}
// }
// sleep(20);
return 0;
}
static void init_rf() {
printf("INFO: Before rf init\n");
int ret;
ret = ax5043_init(&hax5043, XTAL_FREQ_HZ, VCO_INTERNAL);
printf("INFO: After rf init\n");
if (ret != PQWS_SUCCESS) {
fprintf(stderr,
"ERROR: Failed to initialize AX5043 with error code %d\n", ret);
exit(EXIT_FAILURE);
}
}

@ -1 +0,0 @@
int send_afsk(int tlm[][5]);

@ -1,23 +1,6 @@
/*
* Generates telemetry for CubeSat Simulator
* Displays voltage and current sensors for CubeSatSim
*
* Copyright Alan B. Johnston
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code
* from https://github.com/adafruit/Adafruit_INA219.
*/
#include <fcntl.h>
@ -25,167 +8,24 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "status.h"
#include "ax5043.h"
#include "ax25.h"
#include "spi/ax5043spi.h"
#include <wiringPiI2C.h>
#include <wiringPi.h>
#include <time.h>
#include <math.h>
#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino
#define A 1
#define B 2
#define C 3
#define D 4
#define PLUS_X 0
#define PLUS_Y 1
#define PLUS_Z 2
#define BAT 3
#define BAT 2
#define BUS 3
#define MINUS_X 4
#define MINUS_Y 5
#define MINUS_Z 6
#define BUS 7
#define OFF -1
int twosToInt(int val, int len);
struct SensorConfig {
int fd;
uint16_t config;
int calValue;
int powerMultiplier;
int currentDivider;
};
struct SensorData {
double current;
double voltage;
double power;
};
/**
* @brief Read the data from one of the i2c current sensors.
*
* Reads the current data from the requested i2c current sensor configuration and
* stores it into a SensorData struct. An invalid file descriptor (i.e. less than zero)
* results in a SensorData struct being returned that has both its #current and #power members
* set to NAN.
*
* @param sensor A structure containing sensor configuration including the file descriptor.
* @return struct SensorData A struct that contains the current, voltage, and power readings
* from the requested sensor.
*/
struct SensorData read_sensor_data(struct SensorConfig sensor) {
struct SensorData data = {
.current = 0,
.voltage = 0,
.power = 0 };
if (sensor.fd < 0) {
return data;
}
// doesn't read negative currents accurately, shows -0.1mA
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CALIBRATION, sensor.calValue);
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CONFIG, sensor.config);
wiringPiI2CWriteReg16(sensor.fd, INA219_REG_CALIBRATION, sensor.calValue);
delay(1);
int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT);
if (value == -1)
{
sensor.fd = -1;
return data;
}
data.current = (float) twosToInt(value, 16) / (float) sensor.currentDivider;
wiringPiI2CWrite(sensor.fd, INA219_REG_BUSVOLTAGE);
delay(1); // Max 12-bit conversion time is 586us per sample
value = (wiringPiI2CRead(sensor.fd) << 8 ) | wiringPiI2CRead (sensor.fd);
data.voltage = ((float)(value >> 3) * 4) / 1000;
// power has very low resolution, seems to step in 512mW values
delay(1);
data.power = (float) wiringPiI2CReadReg16(sensor.fd, INA219_REG_POWER) * (float) sensor.powerMultiplier;
return data;
}
/**
* @brief Configures an i2c current sensor.
*
* Calculates the configuration values of the i2c sensor so that
* current, voltage, and power can be read using read_sensor_data.
* Supports 16V 400mA and 16V 2.0A settings.
*
* @param sensor A file descriptor that can be used to read from the sensor.
* @param milliAmps The mA configuration, either 400mA or 2A are supported.
* @return struct SensorConfig A struct that contains the configuraton of the sensor.
*/
//struct SensorConfig config_sensor(int sensor, int milliAmps) {
struct SensorConfig config_sensor(char *bus, int address, int milliAmps) {
struct SensorConfig data;
if (access(bus, W_OK | R_OK) < 0) { // Test if I2C Bus is missing
printf("ERROR: %s bus not present \n Check raspi-config Interfacing Options/I2C and /boot/config.txt \n", bus);
data.fd = OFF;
return (data);
}
char result[128];
int pos = strlen(bus) / sizeof(bus[0]) - 1;
// printf("Bus size %d \n", pos);
// printf("Bus value %d \n", atoi(&bus[pos]));
char command[50] = "timeout 10 i2cdetect -y ";
strcat (command, &bus[pos]);
FILE *i2cdetect = popen(command, "r");
while (fgets(result, 128, i2cdetect) != NULL) {
;
// printf("result: %s", result);
}
int error = pclose(i2cdetect)/256;
// printf("%s error: %d \n", &command, error);
if (error != 0)
{
printf("ERROR: %s bus has a problem \n Check I2C wiring and pullup resistors \n", bus);
data.fd = OFF;
return (data);
}
data.fd = wiringPiI2CSetupInterface(bus, address);
data.config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
if (milliAmps == 400) { // INA219 16V 400mA configuration
data.calValue = 8192;
data.powerMultiplier = 1;
data.currentDivider = 20; // 40; in Adafruit config
}
else { // INA219 16V 2A configuration
data.calValue = 40960;
data.powerMultiplier = 2;
data.currentDivider = 10; // 20; in Adafruit config
}
//#ifdef DEBUG_LOGGING
// printf("Sensor %s %x configuration: %d %d %d %d %d\n", bus, address, data.fd,
// data.config, data.calValue, data.currentDivider, data.powerMultiplier);
// printf("Sensor %s %x | ", bus, address);
//#endif
return data;
}
#define PLUS_Z 6
#define MINUS_Z 7
struct SensorConfig sensorV;
struct SensorData readingV;
struct SensorConfig tempSensor;
struct SensorConfig sensor[8]; // 8 current sensors in Solar Power PCB vB4/5
struct SensorData reading[8]; // 8 current sensors in Solar Power PCB vB4/5
#define OFF -1
#define ON 1
const char pythonCmd[] = "python3 /home/pi/CubeSatSim/python/voltcurrent.py ";
char pythonStr[100], pythonConfigStr[100], busStr[10];
int map[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int main(int argc, char *argv[]) {
@ -203,14 +43,12 @@ int main(int argc, char *argv[]) {
if (digitalRead(2) != HIGH)
{
printf("vB3 with TFB Present\n");
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[PLUS_Z] = config_sensor("/dev/i2c-1", 0x44, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x4a, 2000);
sensor[MINUS_X] = config_sensor("/dev/i2c-0", 0x40, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-0", 0x41, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-0", 0x44, 400); }
map[BUS] = MINUS_Z;
map[BAT] = BUS;
map[PLUS_Z] = BAT;
map[MINUS_Z] = PLUS_Z;
strcpy(busStr,"1 0");
}
else
{
pinMode (3, INPUT);
@ -219,14 +57,9 @@ int main(int argc, char *argv[]) {
if (digitalRead(3) != HIGH)
{
printf("vB4 Present\n");
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x44, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[PLUS_Z] = config_sensor("/dev/i2c-0", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-0", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-0", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-0", 0x45, 400);
map[BAT] = BUS;
map[BUS] = BAT;
strcpy(busStr,"1 0");
}
else
{
@ -235,118 +68,87 @@ int main(int argc, char *argv[]) {
if (digitalRead(26) != HIGH)
{
printf("vB5 Present\n"); // Don't print normal board detection
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x44, 400);
printf("vB5 Present\n"); // Don't print normal board detection
if (access("/dev/i2c-11", W_OK | R_OK) >= 0) { // Test if I2C Bus 11 is present
printf("/dev/i2c-11 is present\n\n");
sensor[PLUS_Z] = config_sensor("/dev/i2c-11", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-11", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-11", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-11", 0x45, 400);
} else {
sensor[PLUS_Z] = config_sensor("/dev/i2c-3", 0x40, 400);
sensor[MINUS_X] = config_sensor("/dev/i2c-3", 0x41, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-3", 0x44, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-3", 0x45, 400);
}
if (access("/dev/i2c-11", W_OK | R_OK) >= 0) { // Test if I2C Bus 11 is present
printf("/dev/i2c-11 is present\n\n");
strcpy(busStr,"1 11");
} else {
strcpy(busStr,"1 3");
}
}
else
{
printf("VB3 Present\n");
sensor[PLUS_X] = config_sensor("/dev/i2c-1", 0x40, 400);
sensor[PLUS_Y] = config_sensor("/dev/i2c-1", 0x41, 400);
sensor[PLUS_Z] = config_sensor("/dev/i2c-1", 0x44, 400);
sensor[BAT] = config_sensor("/dev/i2c-1", 0x45, 400);
sensor[BUS] = config_sensor("/dev/i2c-1", 0x4a, 2000);
sensor[MINUS_X] = config_sensor("/dev/i2c-0", 0x40, 400);
sensor[MINUS_Y] = config_sensor("/dev/i2c-0", 0x41, 400);
sensor[MINUS_Z] = config_sensor("/dev/i2c-0", 0x44, 400); }
}
map[BUS] = MINUS_Z;
map[BAT] = BUS;
map[PLUS_Z] = BAT;
map[MINUS_Z] = PLUS_Z;
strcpy(busStr,"1 0");
}
}
}
// Reading I2C voltage and current sensors
int count;
for (count = 0; count < 8; count++)
{
reading[count] = read_sensor_data(sensor[count]);
// printf("Read sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// count, reading[count].voltage, reading[count].current, reading[count].power);
}
printf("\n");
// sensorV = config_sensor("/dev/i2c-1", 0x40, 400);
// readingV = read_sensor_data(sensorV);
printf("+X | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// PLUS_X, readingV.voltage, readingV.current, readingV.power);
PLUS_X, reading[PLUS_X].voltage, reading[PLUS_X].current, reading[PLUS_X].power);
// printf("Starting\n");
strcpy(pythonStr, pythonCmd);
strcat(pythonStr, busStr);
strcat(pythonConfigStr, pythonStr);
strcat(pythonConfigStr, " c");
// sensorV = config_sensor("/dev/i2c-1", 0x41, 400);
// readingV = read_sensor_data(sensorV);
printf("+Y | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// PLUS_Y, readingV.voltage, readingV.current, readingV.power);
PLUS_Y, reading[PLUS_Y].voltage, reading[PLUS_Y].current, reading[PLUS_Y].power);
FILE* file1 = popen(pythonConfigStr, "r");
char cmdbuffer[1000];
fgets(cmdbuffer, 1000, file1);
// printf("pythonStr result: %s\n", cmdbuffer);
pclose(file1);
//sensorV = config_sensor("/dev/i2c-0", 0x40, 400);
//readingV = read_sensor_data(sensorV);
printf("+Z | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// PLUS_Z, readingV.voltage, readingV.current, readingV.power);
PLUS_Z, reading[PLUS_Z].voltage, reading[PLUS_Z].current, reading[PLUS_Z].power);
int count1;
char *token;
// sensorV = config_sensor("/dev/i2c-0", 0x41, 400);
// readingV = read_sensor_data(sensorV);
printf("-X | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// MINUS_X, readingV.voltage, readingV.current, readingV.power);
MINUS_X, reading[MINUS_X].voltage, reading[MINUS_X].current, reading[MINUS_X].power);
// sensorV = config_sensor("/dev/i2c-0", 0x44, 400);
// readingV = read_sensor_data(sensorV);
printf("-Y | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// MINUS_Y, readingV.voltage, readingV.current, readingV.power);
MINUS_Y, reading[MINUS_Y].voltage, reading[MINUS_Y].current, reading[MINUS_Y].power);
//sensorV = config_sensor("/dev/i2c-0", 0x45, 400);
// readingV = read_sensor_data(sensorV);
printf("-Z | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// MINUS_Z, readingV.voltage, readingV.current, readingV.power);
MINUS_Z, reading[MINUS_Z].voltage, reading[MINUS_Z].current, reading[MINUS_Z].power);
// sensorV = config_sensor("/dev/i2c-1", 0x45, 400);
// readingV = read_sensor_data(sensorV);
printf("Bat | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// BAT, readingV.voltage, readingV.current, readingV.power);
BAT, reading[BAT].voltage, reading[BAT].current, reading[BAT].power);
// sensorV = config_sensor("/dev/i2c-1", 0x44, 400);
// readingV = read_sensor_data(sensorV);
printf("Bus | sensor[%d] % 4.2fV % 6.1fmA % 6.1fmW \n",
// BUS, readingV.voltage, readingV.current, readingV.power);
BUS, reading[BUS].voltage, reading[BUS].current, reading[BUS].power);
/*
sensorV = config_sensor("/dev/i2c-3", 0x48, 0);
if (sensorV.fd != OFF) {
int tempValue = wiringPiI2CReadReg16(sensorV.fd, 0);
uint8_t upper = (uint8_t) (tempValue >> 8);
uint8_t lower = (uint8_t) (tempValue & 0xff);
float temp = (float)lower + ((float)upper / 0x100);
printf("T | % 4.1f C \n", temp);
}
*/
printf("\n\n");
FILE* file = popen(pythonStr, "r");
fgets(cmdbuffer, 1000, file);
// printf("result: %s\n", cmdbuffer);
pclose(file);
const char space[2] = " ";
token = strtok(cmdbuffer, space);
float voltage[9], current[9];
memset(voltage, 0, sizeof(voltage));
memset(current, 0, sizeof(current));
for (count1 = 0; count1 < 8; count1++)
{
if (token != NULL)
{
voltage[count1] = atof(token);
// #ifdef DEBUG_LOGGING
// printf("voltage: %f ", voltage[count1]);
// #endif
token = strtok(NULL, space);
if (token != NULL)
{
current[count1] = atof(token);
if ((current[count1] < 0) && (current[count1] > -1))
current[count1] *= (-1.0);
// #ifdef DEBUG_LOGGING
// printf("current: %f\n", current[count1]);
// #endif
token = strtok(NULL, space);
}
}
}
printf("\n");
printf("+X | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_X]], current[map[PLUS_X]]);
printf("+Y | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Y]], current[map[PLUS_Y]]);
printf("+Z | % 4.2f V % 5.0f mA \n", voltage[map[PLUS_Z]], current[map[PLUS_Z]]);
printf("-X | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_X]], current[map[MINUS_X]]);
printf("-Y | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Y]], current[map[MINUS_Y]]);
printf("-Z | % 4.2f V % 5.0f mA \n", voltage[map[MINUS_Z]], current[map[MINUS_Z]]);
printf("Bat | % 4.2f V % 5.0f mA \n", voltage[map[BAT]], current[map[BAT]]);
printf("Bus | % 4.2f V % 5.0f mA \n\n", voltage[map[BUS]], current[map[BUS]]);
return 0;
}
int twosToInt(int val,int len) { // Convert twos compliment to integer
// from https://www.raspberrypi.org/forums/viewtopic.php?t=55815
if(val & (1 << (len - 1)))
val = val - (1 << len);
return(val);
}

@ -2,6 +2,8 @@
echo -e "\nDemo of CubeSatSim at 434.9 MHz\n"
sleep 10
sudo systemctl restart rpitx
if [ "$1" = "a" ]; then

@ -1 +0,0 @@
These files are papers and presentations given about the CubeSat Simulator at the AMSAT Space Symposium and other places.

@ -0,0 +1,40 @@
"""Sample code and test for adafruit_in219"""
import sys
import board
import busio
from adafruit_extended_bus import ExtendedI2C as I2C
from adafruit_ina219 import ADCResolution, BusVoltageRange, INA219
if __name__ == "__main__":
# print 'Length: ', len(sys.argv)
if (len(sys.argv)) > 1:
# print("There are arguments!")
# if (('a' == sys.argv[1]) or ('afsk' in sys.argv[1])):
bus = int(sys.argv[1], base=10)
if (len(sys.argv)) > 2:
address = int(sys.argv[2], base=16)
else:
address = 0x40
else:
bus = 1
address = 0x40
try:
# Create library object using Extended Bus I2C port
i2c_bus = I2C(bus) # 1 Device is /dev/i2c-1
ina219 = INA219(i2c_bus, address)
# optional : change configuration to use 32 samples averaging for both bus voltage and shunt voltage
ina219.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S # 32S
ina219.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S # 32S
# optional : change voltage range to 16V
ina219.bus_voltage_range = BusVoltageRange.RANGE_16V
current = ina219.current # current in mA
print("{:9.1f}".format(current))
except:
print("0.0 Error")

@ -0,0 +1,62 @@
"""Sample code and test for adafruit_in219"""
import time
import board
import busio
#import smbus
#from adafruit_blinka.microcontroller.bcm283x import pin
from adafruit_extended_bus import ExtendedI2C as I2C
from adafruit_ina219 import ADCResolution, BusVoltageRange, INA219
#i2c_bus2 = smbus.SMBus(3) # 3
#b1 = i2c_bus2.read_i2c_block_data(0x45, 0x01, 2)
#print (b1)
#p = busio.I2C(scl, sda)
#p = busio.I2C(pin.D1,pin.D0)
#p = board.I2C(pin.D1,pin.D0)
#p.deinit()
# Create library object using our Extended Bus I2C port
i2c_bus = I2C(11) # 1 Device is /dev/i2c-1
#i2c_bus = board.I2C()
#i2c_bus = p
print(i2c_bus)
ina219 = INA219(i2c_bus, 0x45)
print("ina219 test")
# display some of the advanced field (just to test)
print("Config register:")
print(" bus_voltage_range: 0x%1X" % ina219.bus_voltage_range)
print(" gain: 0x%1X" % ina219.gain)
print(" bus_adc_resolution: 0x%1X" % ina219.bus_adc_resolution)
print(" shunt_adc_resolution: 0x%1X" % ina219.shunt_adc_resolution)
print(" mode: 0x%1X" % ina219.mode)
print("")
# optional : change configuration to use 32 samples averaging for both bus voltage and shunt voltage
ina219.bus_adc_resolution = ADCResolution.ADCRES_12BIT_32S
ina219.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_32S
# optional : change voltage range to 16V
ina219.bus_voltage_range = BusVoltageRange.RANGE_16V
# measure and display loop
while True:
bus_voltage = ina219.bus_voltage # voltage on V- (load side)
shunt_voltage = ina219.shunt_voltage # voltage between V+ and V- across the shunt
current = ina219.current # current in mA
# INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
print("PSU Voltage: {:6.3f} V".format(bus_voltage + shunt_voltage))
print("Shunt Voltage: {:9.6f} V".format(shunt_voltage))
print("Load Voltage: {:6.3f} V".format(bus_voltage))
print("Current: {:9.1f} mA".format(current))
print("")
time.sleep(2)

@ -0,0 +1,49 @@
"""Sample code and test for adafruit_in219"""
import time
import board
import smbus
from adafruit_ina219 import ADCResolution, BusVoltageRange, INA219
i2c_bus2 = smbus.SMBus(3)
b1 = i2c_bus2.read_i2c_block_data(0x45, 0x01, 2)
print (b1)
i2c_bus = board.I2C()
print(i2c_bus)
ina219 = INA219(i2c_bus, 0x45)
print("ina219 test")
# display some of the advanced field (just to test)
print("Config register:")
print(" bus_voltage_range: 0x%1X" % ina219.bus_voltage_range)
print(" gain: 0x%1X" % ina219.gain)
print(" bus_adc_resolution: 0x%1X" % ina219.bus_adc_resolution)
print(" shunt_adc_resolution: 0x%1X" % ina219.shunt_adc_resolution)
print(" mode: 0x%1X" % ina219.mode)
print("")
# optional : change configuration to use 32 samples averaging for both bus voltage and shunt voltage
ina219.bus_adc_resolution = ADCResolution.ADCRES_12BIT_32S
ina219.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_32S
# optional : change voltage range to 16V
ina219.bus_voltage_range = BusVoltageRange.RANGE_16V
# measure and display loop
while True:
bus_voltage = ina219.bus_voltage # voltage on V- (load side)
shunt_voltage = ina219.shunt_voltage # voltage between V+ and V- across the shunt
current = ina219.current # current in mA
# INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
print("PSU Voltage: {:6.3f} V".format(bus_voltage + shunt_voltage))
print("Shunt Voltage: {:9.6f} V".format(shunt_voltage))
print("Load Voltage: {:6.3f} V".format(bus_voltage))
print("Current: {:9.6f} A".format(current / 1000))
print("")
time.sleep(2)

@ -0,0 +1,44 @@
"""Sample code and test for adafruit_in219"""
import sys
import board
import busio
from adafruit_extended_bus import ExtendedI2C as I2C
from adafruit_ina219 import ADCResolution, BusVoltageRange, INA219
if __name__ == "__main__":
# print 'Length: ', len(sys.argv)
if (len(sys.argv)) > 1:
# print("There are arguments!")
# if (('a' == sys.argv[1]) or ('afsk' in sys.argv[1])):
bus = int(sys.argv[1], base=10)
if (len(sys.argv)) > 2:
address = int(sys.argv[2], base=16)
else:
address = 0x40
else:
bus = 1
address = 0x40
try:
# Create library object using Extended Bus I2C port
i2c_bus = I2C(bus) # 1 Device is /dev/i2c-1
ina219 = INA219(i2c_bus, address)
# print("ina219 test")
# optional : change configuration to use 32 samples averaging for both bus voltage and shunt voltage
ina219.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S # 32S
ina219.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S # 32S
# optional : change voltage range to 16V
ina219.bus_voltage_range = BusVoltageRange.RANGE_16V
bus_voltage = ina219.bus_voltage # voltage on V- (load side)
shunt_voltage = ina219.shunt_voltage # voltage between V+ and V- across the shunt
# current = ina219.current # current in mA
# INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
print("{:6.3f}".format(bus_voltage + shunt_voltage))
except:
print("0.0 Error")

@ -0,0 +1,63 @@
"""Sample code and test for adafruit_in219"""
# Reads all voltage and current sensors for two I2C buses
import sys
#import board
import busio
from adafruit_extended_bus import ExtendedI2C as I2C
from adafruit_ina219 import INA219
if __name__ == "__main__":
# print 'Length: ', len(sys.argv)
buses = [1, 3] # default I2C buses
config = False
if (len(sys.argv)) > 1:
# print("There are arguments!")
# if (('a' == sys.argv[1]) or ('afsk' in sys.argv[1])):
buses[0] = int(sys.argv[1], base=10)
if (len(sys.argv)) > 2:
buses[1] = int(sys.argv[2], base=10)
if (len(sys.argv)) > 3:
if sys.argv[3] == "c":
config = True
from adafruit_ina219 import ADCResolution, BusVoltageRange
addresses = [0x40, 0x41, 0x44, 0x45] #INA219 addresses on the bus
# print("buses: ", buses, " addr: ", addresses)
for x in buses:
i2c_bus = I2C(x) # Device is /dev/i2c-x
for y in addresses:
# print(x,y)
try:
# Create library object using Extended Bus I2C port
# print("bus: ", x, " addr: ", y)
if x == 0 and y == 0x45:
# print("Reading INA219 in MoPower Board")
i2c_bus = I2C(1)
ina219 = INA219(i2c_bus, 0x4a)
else:
ina219 = INA219(i2c_bus, y)
# print("ina219 test")
if config:
# print("Configuring")
# optional : change configuration to use 32 samples averaging for both bus voltage and shunt voltage
ina219.bus_adc_resolution = ADCResolution.ADCRES_12BIT_32S # 1S
ina219.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_32S # 1S
# optional : change voltage range to 16V
ina219.bus_voltage_range = BusVoltageRange.RANGE_16V
bus_voltage = ina219.bus_voltage # voltage on V- (load side)
# shunt_voltage = ina219.shunt_voltage # voltage between V+ and V- across the shunt
current = ina219.current # current in mA
if x == 0 and y == 0x45:
current = current * 10
# INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
# print("{:6.3f}".format(bus_voltage + shunt_voltage))
print("{:6.3f} ".format(bus_voltage), "{:6.3f} ".format(current) , end = '')
except:
print("{:6.3f} ".format(0), "{:6.3f} ".format(0), end = '')
# pass
print(" ")
Loading…
Cancel
Save

Powered by TurnKey Linux.