diff --git a/Makefile b/Makefile index 8c378f36..6ea66e39 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,7 @@ radioafsk: libax5043.a radioafsk: afsk/ax25.o radioafsk: afsk/ax5043.o radioafsk: afsk/main.o +radioafsk: afsk/ina219.h gcc -o radioafsk -pedantic -Wall -Wextra -L./ afsk/ax25.o afsk/ax5043.o afsk/main.o -lwiringPi -lax5043 diff --git a/afsk/ax5043.c b/afsk/ax5043.c index 2beb4d66..a6ae071e 100644 --- a/afsk/ax5043.c +++ b/afsk/ax5043.c @@ -222,11 +222,12 @@ int ax5043_init(ax5043_conf_t *conf, uint32_t f_xtal, vco_mode_t vco) { } /* Setup TX only related parameters */ +/* ret = ax5043_conf_tx_path(conf); if (ret) { return ret; } - +*/ /* Set an internal copy for the ax5042_wait_for_transmit function */ __ax5043_conf = conf; diff --git a/afsk/ina219.h b/afsk/ina219.h new file mode 100644 index 00000000..0a7372e3 --- /dev/null +++ b/afsk/ina219.h @@ -0,0 +1,80 @@ +/* + * 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 diff --git a/afsk/main.c b/afsk/main.c index 6a332eb3..4f90184a 100644 --- a/afsk/main.c +++ b/afsk/main.c @@ -32,7 +32,9 @@ #include "ax25.h" #include "spi/ax5043spi.h" #include +#include #include +#include "ina219.h" // Put your callsign here #define CALLSIGN "KU2Y" @@ -76,9 +78,29 @@ int charging = 0; uint16_t config = (0x2000 | 0x1800 | 0x0180 | 0x0018 | 0x0007 ); +int x_fd; // I2C bus 0 address 0x40 +int x_powerMultiplier; +int x_currentDivider; +int x_calValue; +int y_fd; // I2C bus 0 address 0x41 +int z_fd; // I2C bos 0 address 0x44 + + int main(void) { + + wiringPiSetup () ; + pinMode (0, OUTPUT) ; + int blink; + for (blink = 1; blink < 2 ;blink++) + { + digitalWrite (0, HIGH) ; delay (500) ; + digitalWrite (0, LOW) ; delay (500) ; + } +// digitalWrite (0, HIGH) ; -// sleep(20); + setSpiChannel(SPI_CHANNEL); + setSpiSpeed(SPI_SPEED); + initializeSpi(); int tlm[7][5]; int i, j; @@ -93,23 +115,67 @@ int main(void) { //char *filenam1e = (char*)"/dev/i2c-3"; if ((file_i2c = open("/dev/i2c-3", O_RDWR)) < 0) { - printf("ERROR: /dev/ic2-3 bus not present\n"); + fprintf(stderr,"ERROR: /dev/ic2-3 bus not present\n"); tempSensor = -1; } else { tempSensor = wiringPiI2CSetupInterface("/dev/i2c-3", 0x48); } - printf("tempSensor: %d \n",tempSensor); - - int arduinoI2C = wiringPiI2CSetupInterface("/dev/i2c-0", 0x4c); - printf("Arduio write: %d \n", wiringPiI2CWrite(arduinoI2C,42)); - printf("Arduio: %d \n", wiringPiI2CRead(arduinoI2C)); - - setSpiChannel(SPI_CHANNEL); - setSpiSpeed(SPI_SPEED); - initializeSpi(); + fprintf(stderr,"tempSensor: %d \n",tempSensor); + int arduinoI2C; + if ((arduinoI2C = open("/dev/i2c-0", O_RDWR)) < 0) + { + fprintf(stderr,"ERROR: /dev/i2c-0 bus not present\n"); + } else { + arduinoI2C = wiringPiI2CSetupInterface("/dev/i2c-0", 0x4c); + fprintf(stderr,"arduinoI2C: %d\n", arduinoI2C); + if (arduinoI2C > 0) { + // for (blink = 1; blink < 20 ;blink++) { + sleep(1); + fprintf(stderr,"Arduio: %d \n", wiringPiI2CReadReg16(arduinoI2C,0)); + sleep(1); + fprintf(stderr,"Arduio: %d \n", wiringPiI2CRead(arduinoI2C)); + sleep(1); + printf("Arduio: %d \n", wiringPiI2CReadReg16(arduinoI2C,1)); + sleep(1); + printf("Arduio: %d \n", wiringPiI2CReadReg16(arduinoI2C,2)); + sleep(1); +// } + } else { + fprintf(stderr,"Arduino payload not present\n"); + } + } + +// new INA219 current reading code + + x_calValue = 8192; + x_powerMultiplier = 1; + x_currentDivider = 20; + config = INA219_CONFIG_BVOLTAGERANGE_16V | + INA219_CONFIG_GAIN_40MV | + INA219_CONFIG_BADCRES_12BIT | + INA219_CONFIG_SADCRES_12BIT_4S_2130US | + //INA219_CONFIG_SADCRES_12BIT_1S_532US | + INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; + + if ((file_i2c = open("/dev/i2c-0", O_RDWR)) < 0) + { + fprintf(stderr,"ERROR: /dev/ic2-0 bus not present\n"); + x_fd = -1; + y_fd = -1; + z_fd = -1; + } else + { + x_fd = wiringPiI2CSetupInterface("/dev/i2c-0", 0x40); + fprintf("stderr,Opening of -X fd %d\n", x_fd); + y_fd = wiringPiI2CSetupInterface("/dev/i2c-0", 0x41); + printf("Opening of -Y fd %d\n", y_fd); + z_fd = wiringPiI2CSetupInterface("/dev/i2c-0", 0x44); + printf("Opening of -Z fd %d\n", z_fd); + } + int ret; uint8_t data[1024]; @@ -133,18 +199,18 @@ int main(void) { // AX25_PREAMBLE_LEN, // AX25_POSTAMBLE_LEN); - printf("INFO: Getting TLM Data\n"); + fprintf(stderr,"INFO: Getting TLM Data\n"); - get_tlm(tlm); + //get_tlm(tlm); - printf("INFO: Preparing X.25 packet\n"); + fprintf(stderr,"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]); @@ -155,8 +221,9 @@ int main(void) { channel, upper_digit(tlm[channel][4]), lower_digit(tlm[channel][4])); // printf("%s \n",tlm_str); strcat(str, tlm_str); - } - + } +*/ +/* char cmdbuffer[1000]; if (charging) { @@ -166,7 +233,8 @@ int main(void) { // printf("LED state: %s\n", cmdbuffer); } - printf("INFO: Transmitting X.25 packet\n"); +*/ + fprintf(stderr,"INFO: Transmitting X.25 packet\n"); memcpy(data, str, strnlen(str, 256)); ret = ax25_tx_frame(&hax25, &hax5043, data, strnlen(str, 256)); @@ -177,12 +245,13 @@ int main(void) { exit(EXIT_FAILURE); } ax5043_wait_for_transmit(); +/* FILE* file2 = popen("/home/pi/mopower/mpcmd LED_STAT=0", "r"); fgets(cmdbuffer, 999, file2); pclose(file2); // printf("LED state: %s\n", cmdbuffer); - +*/ if (ret) { fprintf(stderr, "ERROR: Failed to transmit entire AX.25 frame with error code %d\n", @@ -196,6 +265,8 @@ int main(void) { static void init_rf() { int ret; + fprintf(stderr,"Initializing AX5043\n"); + ret = ax5043_init(&hax5043, XTAL_FREQ_HZ, VCO_INTERNAL); if (ret != PQWS_SUCCESS) { fprintf(stderr, @@ -212,7 +283,7 @@ int lower_digit(int number) { if (number < 100) digit = number - ((int)(number/10) * 10); else - printf("ERROR: Not a digit in lower_digit!\n"); + fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); return digit; } @@ -224,7 +295,7 @@ int upper_digit(int number) { if (number < 100) digit = (int)(number/10); else - printf("ERROR: Not a digit in upper_digit!\n"); + fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); return digit; } int get_tlm(int tlm[][5]) { @@ -235,7 +306,7 @@ int get_tlm(int tlm[][5]) { FILE* file = popen("sudo python /home/pi/CubeSatSim/python/readcurrent.py 2>&1", "r"); fgets(cmdbuffer, 999, file); pclose(file); - printf("I2C Sensor data: %s\n", cmdbuffer); + fprintf(stderr,"I2C Sensor data: %s\n", cmdbuffer); char ina219[16][20]; // voltage, currents, and power from the INA219 current sensors x4a, x40, x41, x44, and x45. int i = 0; @@ -249,9 +320,11 @@ int get_tlm(int tlm[][5]) { } // Reading MoPower telemetry info - +/* file = popen("/home/pi/mopower/mpcmd show data", "r"); - fgets(cmdbuffer, 999 file); + + fgets(cmdbuffer, 999, file); + pclose(file); // printf("MoPower data: %s\n", cmdbuffer); @@ -279,16 +352,41 @@ int get_tlm(int tlm[][5]) { printf("Charging off\n"); } +*/ +// read i2c current sensors // + double current = 0, power = 0, y_current = 0, y_power = 0, z_current = 0, z_power = 0; + if (x_fd != -1) { + wiringPiI2CWriteReg16(x_fd, INA219_REG_CALIBRATION, x_calValue); + wiringPiI2CWriteReg16(x_fd, INA219_REG_CONFIG, config); + wiringPiI2CWriteReg16(x_fd, INA219_REG_CALIBRATION, x_calValue); + current = wiringPiI2CReadReg16(x_fd, INA219_REG_CURRENT) / x_currentDivider; + power = wiringPiI2CReadReg16(x_fd, INA219_REG_POWER) * x_powerMultiplier; + wiringPiI2CWriteReg16(y_fd, INA219_REG_CALIBRATION, x_calValue); + wiringPiI2CWriteReg16(y_fd, INA219_REG_CONFIG, config); + wiringPiI2CWriteReg16(y_fd, INA219_REG_CALIBRATION, x_calValue); + y_current = wiringPiI2CReadReg16(y_fd, INA219_REG_CURRENT) / x_currentDivider; + y_power = wiringPiI2CReadReg16(y_fd, INA219_REG_POWER) * x_powerMultiplier; + wiringPiI2CWriteReg16(z_fd, INA219_REG_CALIBRATION, x_calValue); + wiringPiI2CWriteReg16(z_fd, INA219_REG_CONFIG, config); + wiringPiI2CWriteReg16(z_fd, INA219_REG_CALIBRATION, x_calValue); + z_current = wiringPiI2CReadReg16(y_fd, INA219_REG_CURRENT) / x_currentDivider; + z_power = wiringPiI2CReadReg16(y_fd, INA219_REG_POWER) * x_powerMultiplier; + } + printf("-X 0x40 current %4.2f power %4.2f -Y 0x41 current %4.2f power %4.2f -Z 0x44 current %4.2f power %4.2f \n", + current, power, y_current, y_power, z_current, z_power); // printf("1B: ina219[%d]: %s val: %f \n", SENSOR_40 + CURRENT, ina219[SENSOR_40 + CURRENT], strtof(ina219[SENSOR_40 + CURRENT], NULL)); tlm[1][A] = (int)(strtof(ina219[SENSOR_4A + CURRENT], NULL) / 15 + 0.5) % 100; // Current of 5V supply to Pi tlm[1][B] = (int) (99.5 - strtof(ina219[SENSOR_40 + CURRENT], NULL)/10) % 100; // +X current [4] + tlm[1][C] = (int) (99.5 - current/10) % 100; // X- current [10] tlm[1][D] = (int) (99.5 - strtof(ina219[SENSOR_41 + CURRENT], NULL)/10) % 100; // +Y current [7] - tlm[1][C] = (int) (99.5 - strtof(ina219[SENSOR_44 + CURRENT], NULL)/10) % 100; // +Z current [10] (actually -X current, AO-7 didn't have a Z solar panel?) - tlm[2][A] = 99; - tlm[2][C] = (int)((time(NULL) - timestamp) / 15) % 100; + tlm[2][A] = (int) (99.5 - y_current/10) % 100; // -Y current [10] + tlm[2][B] = (int) (99.5 - strtof(ina219[SENSOR_44 + CURRENT], NULL)/10) % 100; // +Z current [10] // was 70/2m transponder power, AO-7 didn't have a Z panel + tlm[2][C] = (int) (99.5 - z_current/10) % 100; // -Z current (was timestamp) + +// tlm[2][C] = (int)((time(NULL) - timestamp) / 15) % 100; tlm[2][D] = (int)(50.5 + strtof(ina219[SENSOR_45 + CURRENT], NULL)/10.0) % 100; // NiMH Battery current tlm[3][A] = abs((int)((strtof(ina219[SENSOR_45 + VOLTAGE], NULL) * 10) - 65.5) % 100); diff --git a/demo.sh b/demo.sh index 7d0274d0..ce5328df 100755 --- a/demo.sh +++ b/demo.sh @@ -1,17 +1,20 @@ #!/bin/bash +exit 0 echo -e "\nDemo of CubeSatSim sends AFSK telemetry at 440 MHz continuously\n\n" -sleep 30 +sleep 60 #echo 'sleep over' >> /home/pi/CubeSatSim/log.txt echo $(date '+%Y %b %d %H:%M') Starting Hostname $HOSTNAME >> /home/pi/CubeSatSim/log.txt -/home/pi/CubeSatSim/radioafsk >> /home/pi/CubeSatSim/log.txt +/home/pi/CubeSatSim/radioafsk >> /home/pi/CubeSatSim/log.txt #/home/pi/DigitalTxRxRPi/testafsktx >> /home/pi/CubeSatSim/log.txt -echo $(date '+%Y %b %d %H:%M') Stopping Hostname $HOSTNAME >> /home/pi/CubeSatSim/log.txt +#echo $(date '+%Y %b %d %H:%M') Stopping Hostname $HOSTNAME >> /home/pi/CubeSatSim/log.txt -/home/pi/mopower/mpcmd LED_STAT=0 +#/home/pi/mopower/mpcmd LED_STAT=0 +#sleep 30 +#/home/pi/CubeSatSim/configax diff --git a/python/readdata.py b/python/readdata.py index 1e2929cf..5a5bd294 100644 --- a/python/readdata.py +++ b/python/readdata.py @@ -1,3 +1,5 @@ +import time + SHUNT_OHMS = 0.01 MAX_EXPECTED_AMPS = 2.5 SHUNT_OHMS45 = 0.1 @@ -26,6 +28,8 @@ try: INA219DISABLE=-1 except: INA219DISABLE=1 + +print "+X v\t+X i\t+X p\t+Y v\t+Y i\t+Y p\t+Z v\t+Z i\t+Z p\tVbatt\tibatt\tpbatt\tV5\ti5\tp5\t+X v\t+X i\t+X p\t" while True: time.sleep(1) @@ -59,7 +63,8 @@ while True: ina44.busnum = 1; ina44v = ina44.voltage() ina44i = ina44.current() - ina44p = ina44.power() + ina44p = ina44.power() + ina44.sleep(); except: FAIL = 1 @@ -72,7 +77,7 @@ while True: ina45i = ina45.current() ina45p = ina45.power() ina45.sleep(); - except: + except: FAIL = 1 try: ina4a = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, 0x4a) @@ -85,4 +90,5 @@ while True: ina4a.sleep(); except: FAIL = 1 - print ina40v, ",", ina40i,",", ina40p,",", ina41v,",", ina41i,",", ina41p,",", ina44v,",", ina44i,",", ina44p,",", ina45v,",", ina45i,",", ina45p,",", ina4av,",", ina4ai,",", ina4ap + print ina40v, "\t", ina40i,"\t", ina40p,"\t", ina41v,"\t", ina41i,"\t", ina41p,"\t", ina44v,"\t", ina44i,"\t", ina44p,"\t", ina45v,"\t", ina45i,"\t", ina45p,"\t", ina4av,"\t", ina4ai,"\t", ina4ap +