diff --git a/Makefile b/Makefile index 5688ac1c..147c4e26 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index 7a09fe68..5d9f9c8d 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/afsk/Adafruit_INA219.h b/afsk/Adafruit_INA219.h deleted file mode 100644 index 1e8c0c63..00000000 --- a/afsk/Adafruit_INA219.h +++ /dev/null @@ -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 - -/** 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); diff --git a/afsk/make_wav.h b/afsk/TelemEncoding.h similarity index 96% rename from afsk/make_wav.h rename to afsk/TelemEncoding.h index 4b78c660..fcd7f2e8 100644 --- a/afsk/make_wav.h +++ b/afsk/TelemEncoding.h @@ -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, } }; - diff --git a/afsk/ina219.h b/afsk/ina219.h deleted file mode 100644 index 0a7372e3..00000000 --- a/afsk/ina219.h +++ /dev/null @@ -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 diff --git a/afsk/main.c b/afsk/main.c index 9fa7aff7..f3822f6e 100644 --- a/afsk/main.c +++ b/afsk/main.c @@ -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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. */ #include @@ -36,8 +33,7 @@ #include #include #include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" +#include "TelemEncoding.h" #include #include #include @@ -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) diff --git a/afsk/main.c.bk b/afsk/main.c.bk deleted file mode 100644 index a85269dc..00000000 --- a/afsk/main.c.bk +++ /dev/null @@ -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 . - */ - -#include -#include -#include -#include -#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); - } -} - diff --git a/afsk/main2.c b/afsk/main2.c deleted file mode 100644 index 96083285..00000000 --- a/afsk/main2.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ - -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define DUV 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -/* -// DUV Settings -#define BIT_RATE 200 -#define DUV 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 -*/ - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -#define FRAME_CNT 33 // Add 3 frames to the count - -//#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[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif - - char cmdbuffer[1000]; - FILE* transmit; - if (DUV == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); - - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors -/* - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); -*/ - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN * PAYLOADS]; // for each payload -// memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; -// memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - - if ((ctr3 % DATA_LEN) == 0) - { - // sleep - // clear b and h - // get uptime and encode in h - // read telem data and encode in b - sleep(1); - - memset(b, 0, sizeof(b)); - memset(h, 0, sizeof(h)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } -// sleep(1); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - } - - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - - for (i = 1; i <= SYNC_BITS * SAMPLES; i++) - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i/SAMPLES + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr/SAMPLES, i, frames, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * SAMPLES); i++) // 572 - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ (SAMPLES * 10)); - int bit = 10 - (i - symbol * SAMPLES * 10) / SAMPLES + 1; - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j ++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - } - write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i) -{ - if (DUV) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buffer[ctr++] = 0.25 * amplitude * phase; - } - else - { - if ((ctr - flip_ctr) < smaller) - buffer[ctr++] = (int)(amplitude * 0.4 * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - else - buffer[ctr++] = (int)(amplitude * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } -// printf("%d %d \n", i, buffer[ctr - 1]); - -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/main3.c b/afsk/main3.c deleted file mode 100644 index 5e344633..00000000 --- a/afsk/main3.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ - -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define DUV 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -/* -// DUV Settings -#define BIT_RATE 200 -#define DUV 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 -*/ - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -long int ptr = 0; - -void copy_samples(); -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -#define FRAME_CNT 33 // Add 3 frames to the count - -//#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 phase0[SAMPLES], phase1[SAMPLES]; -int size_of_phase; -short int data10[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif - - char cmdbuffer[1000]; - FILE* transmit; - if (DUV == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); - - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors - - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); - - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN]; - memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; - memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } - sleep(1); - - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - ptr = 0; - size_of_phase = sizeof(phase0); - - phase = 1; - for (i = 0; i < SAMPLES; i++) - { - write_wave(i, phase1); - } - phase = 0 - for (i = 0; i < SAMPLES; i++) - { - write_wave(i, phase0); - } - - for (i = 1; i <= SYNC_BITS; i++) - { - copy_samples(); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr, i, frames, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; -// if ( (ctr - smaller) > 0) -// { -// for (int j = 1; j <= smaller; j++) -// buffer[ctr - j] = buffer[ctr - j] * 0.4; -// } -// flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * 1); i++) // 572 - { - copy_samples(); -// if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ 10); - int bit = 10 - (i - symbol * 10); - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; -// if ( (ctr - smaller) > 0) -// { -// for (int j = 1; j <= smaller; j ++) -// buffer[ctr - j] = buffer[ctr - j] * 0.4; -// } -// flip_ctr = ctr; - } - } -// } - } - } - write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i, short int *buf) -{ - if (DUV) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buf[i] = 0.25 * amplitude * phase; - } - else - { -// if ((ctr - flip_ctr) < smaller) - // buffer[ctr++] = (int)(amplitude * 0.4 * phase * - // sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - // else - buf[i] = (int)(amplitude * phase * sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } - printf("%d %d \n", i, buf[i]); -} - -void copy_samples() -{ - if (phase == 0) - memcpy(buffer[ptr], phase0, size_of_phase); - else - memcpy(buffer[ptr], phase1, size_of_phase); - - ptr += size_of_phase; -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/main4.c b/afsk/main4.c deleted file mode 100644 index 9b03fc06..00000000 --- a/afsk/main4.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ - -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define DUV 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -/* -// DUV Settings -#define BIT_RATE 200 -#define DUV 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 -*/ - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -#define FRAME_CNT 33 // Add 3 frames to the count - -//#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[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif - - char cmdbuffer[1000]; - FILE* transmit; - if (DUV == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); - - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors - - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); - - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN]; - memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; - memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } - sleep(1); - - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - - for (i = 1; i <= SYNC_BITS * SAMPLES; i++) - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i/SAMPLES + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr/SAMPLES, i, frames, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * SAMPLES); i++) // 572 - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ (SAMPLES * 10)); - int bit = 10 - (i - symbol * SAMPLES * 10) / SAMPLES + 1; - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j ++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - } - write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i) -{ - if (DUV) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buffer[ctr++] = 0.25 * amplitude * phase; - } - else - { - if ((ctr - flip_ctr) < smaller) - buffer[ctr++] = (int)(amplitude * 0.4 * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - else - buffer[ctr++] = (int)(amplitude * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } -// printf("%d %d \n", i, buffer[ctr - 1]); - -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/main_memcpy.c b/afsk/main_memcpy.c deleted file mode 100644 index fc935697..00000000 --- a/afsk/main_memcpy.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire codeF - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ - -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define DUV 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -/* -// DUV Settings -#define BIT_RATE 200 -#define DUV 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 -*/ - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -long int ptr = 0; - -void copy_samples(); -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -#define FRAME_CNT 33 // Add 3 frames to the count - -//#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 phase0[SAMPLES], phase1[SAMPLES]; -int size_of_phase; -short int data10[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - - ptr = 0; - size_of_phase = sizeof(phase0); - int j; - phase = 1; - for (j = 0; j < SAMPLES; j++) - { - write_wave(j, phase1); - } - phase = -1; - for (j = 0; j < SAMPLES; j++) - { - write_wave(j, phase0); - } - - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif - - char cmdbuffer[1000]; - FILE* transmit; - if (DUV == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); - - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors - - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); - - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN]; - memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; - memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 5, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } - sleep(1); - - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - - for (i = 1; i <= SYNC_BITS; i++) - { - copy_samples(); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr, i, frames, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; -// if ( (ctr - smaller) > 0) -// { -// for (int j = 1; j <= smaller; j++) -// buffer[ctr - j] = buffer[ctr - j] * 0.4; -// } -// flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * 1); i++) // 572 - { - copy_samples(); -// if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ 10); - int bit = 10 - (i - symbol * 10); - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (DUV) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; -// if ( (ctr - smaller) > 0) -// { -// for (int j = 1; j <= smaller; j ++) -// buffer[ctr - j] = buffer[ctr - j] * 0.4; -// } -// flip_ctr = ctr; - } - } -// } - } - } - write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i, short int *buf) -{ - if (DUV) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buf[i] = 0.25 * amplitude * phase; - } - else - { -// if ((ctr - flip_ctr) < smaller) - // buffer[ctr++] = (int)(amplitude * 0.4 * phase * - // sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - // else - buf[i] = (int)(amplitude * phase * sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } - printf("%d %d \n", i, buf[i]); -} - -void copy_samples() -{ - if (phase == 0) - memcpy(&buffer[ptr], &phase0, size_of_phase); - else - memcpy(&buffer[ptr], &phase1, size_of_phase); - - ptr += size_of_phase; -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/main_not_working.c b/afsk/main_not_working.c deleted file mode 100644 index 05629dd8..00000000 --- a/afsk/main_not_working.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" -#include -#include -#include -#include -#include -#define PORT 8080 - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ -/* -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define FSK 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -*/ -// FSK Settings -#define BIT_RATE 200 -#define FSK 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 - - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -int sock = 0; - -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -<<<<<<< HEAD -#define FRAME_CNT 60// 11 //33 // Add 3 frames to the count -======= -#define FRAME_CNT 11// //33 // Add 3 frames to the count ->>>>>>> 363442c3e93a3058a0bb88473dc4fa192b6425ad - -//#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[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - -// socket open - int error = 0; - struct sockaddr_in address; - int valread; - struct sockaddr_in serv_addr; -// char *hello = "Hello from client"; -// char buffer[1024] = {0}; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - printf("\n Socket creation error \n"); - error = 1; - } - - memset(&serv_addr, '0', sizeof(serv_addr)); - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) - { - printf("\nInvalid address/ Address not supported \n"); - error = 1; - } - - if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) - { - printf("\nConnection Failed \n"); - error = 1; - } - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif -/* - char cmdbuffer[1000]; - FILE* transmit; - if (FSK == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); -*/ - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors - - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); - - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN]; - memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; - memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 7, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 7, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } - sleep(1); - - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - ctr = 0; - flip_ctr = 0; - phase = 1; - - for (i = 1; i <= SYNC_BITS * SAMPLES; i++) - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i/SAMPLES + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr/SAMPLES, i, frames, bit, (data > 0) ); - if (FSK) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * SAMPLES); i++) // 572 - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ (SAMPLES * 10)); - int bit = 10 - (i - symbol * SAMPLES * 10) / SAMPLES + 1; - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (FSK) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j ++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - } -// write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int error = 0; - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -// socket write - - if (!error) - { - printf("Sending buffer over socket!\n"); - send(sock, buffer, sizeof(buffer), 0); - } - -sleep(20); - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i) -{ - if (FSK) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buffer[ctr++] = 0.25 * amplitude * phase; - } - else - { - if ((ctr - flip_ctr) < smaller) - buffer[ctr++] = (int)(amplitude * 0.4 * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - else - buffer[ctr++] = (int)(amplitude * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } -// printf("%d %d \n", i, buffer[ctr - 1]); - -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/main_old.c b/afsk/main_old.c deleted file mode 100644 index 5d43b46f..00000000 --- a/afsk/main_old.c +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * Transmits CubeSat Telemetry at 434.9MHz in AO-7 format - * - * Copyright Alan B. Johnston - * - * 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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. - */ - -#include -#include -#include -#include -#include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" -#include -#include -#include -#include -#include "Adafruit_INA219.h" // From Adafruit INA219 library for Arduino -#include "make_wav.h" -#include -#include -#include -#include -#include -#define PORT 8080 - -#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 MINUS_X 4 -#define MINUS_Y 5 -#define MINUS_Z 6 -#define BUS 7 -#define OFF -1 - -uint32_t tx_freq_hz = 434900000 + FREQUENCY_OFFSET; -uint32_t tx_channel = 0; - -ax5043_conf_t hax5043; -ax25_conf_t hax25; - -static void init_rf(); -int twosToInt(int val, int len); -int get_tlm(char *str); -int get_tlm_fox(); -int encodeA(short int *b, int index, int val); -int encodeB(short int *b, int index, int val); -void config_x25(); -void trans_x25(); -int upper_digit(int number); -int lower_digit(int number); - -#define S_RATE (48000) // (44100) -#define BUF_SIZE (S_RATE*10) /* 2 second buffer */ -/* -// BPSK Settings -#define BIT_RATE 1200 // 200 for DUV -#define FSK 0 // 1 for DUV -#define RS_FRAMES 3 // 3 frames for BPSK, 1 for DUV -#define PAYLOADS 6 // 1 for DUV -#define DATA_LEN 78 // 56 for DUV -#define RS_FRAME_LEN 159 // 64 for DUV -#define SYNC_BITS 31 // 10 for DUV -#define SYNC_WORD 0b1000111110011010010000101011101 // 0b0011111010 for DUV -#define HEADER_LEN 8 // 6 for DUV -*/ -// FSK Settings -#define BIT_RATE 200 -#define FSK 1 -#define RS_FRAMES 1 -#define PAYLOADS 1 -#define RS_FRAME_LEN 64 -#define HEADER_LEN 6 -#define DATA_LEN 58 -#define SYNC_BITS 10 -#define SYNC_WORD 0b0011111010 - - -#define PARITY_LEN 32 - -float amplitude = 32767/3; // 20000; // 32767/(10%amp+5%amp+100%amp) -float freq_Hz = 3000; // 1200 - -int smaller; -int flip_ctr = 0; -int phase = 1; -int ctr = 0; -void write_to_buffer(int i, int symbol, int val); -void write_wave(); -#define SAMPLES (S_RATE / BIT_RATE) -#define FRAME_CNT 60// 11 //33 // Add 3 frames to the count - -//#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[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -short int data8[8 + RS_FRAMES * (RS_FRAME_LEN + PARITY_LEN)]; -int reset_count; -float uptime_sec; -long int uptime; -char call[5]; - -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 = NAN, - .voltage = NAN, - .power = NAN }; - - 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); - int value = wiringPiI2CReadReg16(sensor.fd, INA219_REG_CURRENT); - 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", 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]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorData reading[8]; // 7 current sensors in Solar Power PCB plus one in MoPower UPS V2 -struct SensorConfig tempSensor; - -char src_addr[5] = ""; -char dest_addr[5] = "CQ"; - -int main(int argc, char *argv[]) { - - if (argc > 1) { - strcpy(src_addr, argv[1]); - } - - wiringPiSetup (); - pinMode (0, OUTPUT); - - //setSpiChannel(SPI_CHANNEL); - //setSpiSpeed(SPI_SPEED); - //initializeSpi(); - - FILE* config_file = fopen("sim.cfg","r"); - if (config_file == NULL) - { - printf("Creating config file."); - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", "KU2Y", 100); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - } - - char* cfg_buf[100]; - fscanf(config_file, "%s %d", call, &reset_count); - fclose(config_file); - printf("%s %d\n", call, reset_count); - - reset_count = (reset_count + 1) % 0xffff; - - config_file = fopen("sim.cfg","w"); - fprintf(config_file, "%s %d", call, reset_count); - fclose(config_file); - config_file = fopen("sim.cfg","r"); - - tempSensor = config_sensor("/dev/i2c-3", 0x48, 0); - - 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); - - int ret; - uint8_t data[1024]; - - tx_freq_hz -= tx_channel * 50000; - - //init_rf(); - - ax25_init(&hax25, (uint8_t *) dest_addr, '1', (uint8_t *) src_addr, '1', - AX25_PREAMBLE_LEN, - AX25_POSTAMBLE_LEN); - - /* Infinite loop */ - //for (;;) - - { - // sleep(1); // Delay 1 second - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting TLM Data\n"); - #endif - - char str[1000]; - // uint8_t b[64]; - char header_str[] = "\x03\xf0"; - strcpy(str, header_str); - - printf("%s-1>%s-1:", (uint8_t *)src_addr, (uint8_t *)dest_addr); - -// get_tlm(str); - get_tlm_fox(); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Getting ready to send\n"); - #endif -/* - char cmdbuffer[1000]; - FILE* transmit; - if (FSK == 1) { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/CubeSatSim/rpitx/rpitx -i- -m RF -f 434.9e3 2>&1", "r"); - } else { - transmit = popen("sudo cat /home/pi/CubeSatSim/transmit.wav | 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.9e6 -t float 2>&1", "r"); - } - fgets(cmdbuffer, 1000, transmit); - pclose(transmit); - printf("Results of transmit command: %s\n", cmdbuffer); -*/ - - -// printf("%s \n", b); -/* - digitalWrite (0, LOW); - - #ifdef DEBUG_LOGGING - fprintf(stderr,"INFO: Transmitting X.25 packet\n"); - #endif - 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(); - - digitalWrite (0, HIGH); - - 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; - #ifdef DEBUG_LOGGING - fprintf(stderr,"Initializing AX5043\n"); - #endif - 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); - } -} - -// Returns lower digit of a number which must be less than 99 -// -int lower_digit(int number) { - - int digit = 0; - if (number < 100) - digit = number - ((int)(number/10) * 10); - else - fprintf(stderr,"ERROR: Not a digit in lower_digit!\n"); - return digit; -} - -// Returns upper digit of a number which must be less than 99 -// -int upper_digit(int number) { - - int digit = 0; - if (number < 100) - digit = (int)(number/10); - else - fprintf(stderr,"ERROR: Not a digit in upper_digit!\n"); - return digit; -} - -int get_tlm(char *str) { - - int tlm[7][5]; - 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 - - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - tlm[4][A] = (int)((95.8 - temp)/1.48 + 0.5) % 100; - } - - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - tlm[4][B] = (int)((95.8 - cpuTemp)/1.48 + 0.5) % 100; - fclose (cpuTempSensor); - } - - tlm[6][B] = 0 ; - tlm[6][D] = 49 + rand() % 3; - - #ifdef DEBUG_LOGGING -// Display tlm - int k, j; - for (k = 1; k < 7; k++) { - for (j = 1; j < 5; j++) { - printf(" %2d ", tlm[k][j]); - } - printf("\n"); - } - #endif - - char tlm_str[1000]; - - char header_str[] = "hi hi "; - strcpy(str, header_str); -// printf("%s-1>%s-1:hi hi ", (uint8_t *)src_addr, (uint8_t *)dest_addr); - - int channel; - for (channel = 1; channel < 7; channel++) { - 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",tlm_str); - strcat(str, tlm_str); - } -// printf("\n"); - -return; -} - -int get_tlm_fox() { - -// memset(b, 0, 64); - -// Reading I2C voltage and current sensors - - FILE* uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - fclose(uptime_file); - - int i; - long int sync = SYNC_WORD; - - smaller = S_RATE/(2 * freq_Hz); -/* - short int b[DATA_LEN] = {0x00,0x7E,0x03, - 0x00,0x00,0x00,0x00,0xE6,0x01,0x00,0x27,0xD1,0x02, - 0xE5,0x40,0x04,0x18,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - short int h[HEADER_LEN] = {0x05,0x00,0x00,0x00,0x00,0x10,0x00,0x00}; -*/ - - short int b[DATA_LEN]; - memset(b, 0, sizeof(b)); - - short int h[HEADER_LEN]; - memset(h, 0, sizeof(h)); - - short int b10[DATA_LEN], h10[HEADER_LEN]; - short int rs_frame[RS_FRAMES][223]; - unsigned char parities[RS_FRAMES][PARITY_LEN],inputByte; -/* - int id = 7, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 8.95 * 100, battCurr = 48.6 * 10; - int posXv = 296, negXv = 45, posYv = 220, negYv = 68, - posZv = 280, negZv = 78; -*/ - int id = 7, frm_type = 0x01, TxTemp = 0, IHUcpuTemp = 0; - int batt_a_v = 0, batt_b_v = 0, batt_c_v = 0, battCurr = 0; - int posXv = 0, negXv = 0, posYv = 0, negYv = 0, - posZv = 0, negZv = 0; - int head_offset = 0; - - for (int frames = 0; frames < FRAME_CNT; frames++) - { - 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); - - #ifdef DEBUG_LOGGING - printf("Temp Sensor Read: %6.1f\n", temp); - #endif - - TxTemp = (int)((temp * 10.0) + 0.5); - encodeB(b, 34 + head_offset, TxTemp); - } -*/ - FILE *cpuTempSensor = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); - if (cpuTempSensor) { - double cpuTemp; - fscanf (cpuTempSensor, "%lf", &cpuTemp); - cpuTemp /= 1000; - - #ifdef DEBUG_LOGGING - printf("CPU Temp Read: %6.1f\n", cpuTemp); - #endif - - IHUcpuTemp = (int)((cpuTemp * 10.0) + 0.5); - encodeA(b, 39 + head_offset, IHUcpuTemp); - } - sleep(1); - - memset(rs_frame,0,sizeof(rs_frame)); - memset(parities,0,sizeof(parities)); - - FILE *uptime_file = fopen("/proc/uptime", "r"); - fscanf(uptime_file, "%f", &uptime_sec); - uptime = (int) uptime_sec; - fclose(uptime_file); - printf("Reset Count: %d Uptime since Reset: %ld \n", reset_count, uptime); - - h[0] = (h[0] & 0xf8) | (id & 0x07); // 3 bits - printf("h[0] %x\n", h[0]); - h[0] = (h[0] & 0x07)| ((reset_count & 0x1f) << 3); - printf("h[0] %x\n", h[0]); - h[1] = (reset_count >> 5) & 0xff; - printf("h[1] %x\n", h[1]); - h[2] = (h[2] & 0xf8) | ((reset_count >> 13) & 0x07); - printf("h[2] %x\n", h[2]); - h[2] = (h[2] & 0x0e) | ((uptime & 0x1f) << 3); - printf("h[2] %x\n", h[2]); - h[3] = (uptime >> 5) & 0xff; - h[4] = (uptime >> 13) & 0xff; - h[5] = (h[5] & 0xf0) | ((uptime >> 21) & 0x0f); - h[5] = (h[5] & 0x0f) | (frm_type << 4); - - posXv = reading[PLUS_X].current * 10; - posYv = reading[PLUS_Y].current * 10; - posZv = reading[PLUS_Z].current * 10; - negXv = reading[MINUS_X].current * 10; - negYv = reading[MINUS_Y].current * 10; - negZv = reading[MINUS_Z].current * 10; - - batt_c_v = reading[BAT].voltage * 100; - battCurr = reading[BAT].current * 10; - - encodeA(b, 0 + head_offset, batt_a_v); - encodeB(b, 1 + head_offset, batt_b_v); - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); - encodeA(b, 12 + head_offset,posXv); - encodeB(b, 13 + head_offset,posYv); - encodeA(b, 15 + head_offset,posZv); - encodeB(b, 16 + head_offset,negXv); - encodeA(b, 18 + head_offset,negYv); - encodeB(b, 19 + head_offset,negZv); - -/* batt_c_v += 10; - battCurr -= 10; - encodeA(b, 3 + head_offset, batt_c_v); - encodeA(b, 9 + head_offset, battCurr); -*/ - int ctr1 = 0; - int ctr3 = 0; - for (i = 0; i < RS_FRAME_LEN; i++) - { - for (int j = 0; j < RS_FRAMES ; j++) - { - if (!((i == (RS_FRAME_LEN - 1)) && (j == 2))) // skip last one for BPSK - { - if (ctr1 < HEADER_LEN) - { - rs_frame[j][i] = h[ctr1]; - update_rs(parities[j], h[ctr1]); - // printf("header %d rs_frame[%d][%d] = %x \n", ctr1, j, i, h[ctr1]); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - } - else - { - rs_frame[j][i] = b[ctr3 % DATA_LEN]; - update_rs(parities[j], b[ctr3 % DATA_LEN]); - // printf("%d rs_frame[%d][%d] = %x %d \n", - // ctr1, j, i, b[ctr3 % DATA_LEN], ctr3 % DATA_LEN); - data8[ctr1++] = rs_frame[j][i]; - // printf ("data8[%d] = %x \n", ctr1 - 1, rs_frame[j][i]); - ctr3++; - } - } - } - } - - printf("Parities "); - for (int m = 0; m < PARITY_LEN; m++) { - printf("%d ", parities[0][m]); - } - printf("\n"); - - int ctr2 = 0; - memset(data10,0,sizeof(data10)); - int rd = 0; - int nrd; - - for (i = 0; i < DATA_LEN * PAYLOADS + HEADER_LEN; i++) // 476 for BPSK - { - data10[ctr2] = (Encode_8b10b[rd][((int)data8[ctr2])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)data8[ctr2])] >> 10) & 1; - // printf ("data10[%d] = encoded data8[%d] = %x \n", - // ctr2, ctr2, data10[ctr2]); - - rd = nrd; // ^ nrd; - ctr2++; - } - - for (i = 0; i < PARITY_LEN; i++) - { - for (int j = 0; j < RS_FRAMES; j++) - { - data10[ctr2++] = (Encode_8b10b[rd][((int)parities[j][i])] & 0x3ff); - nrd = (Encode_8b10b[rd][((int)parities[j][i])] >> 10) & 1; - // printf ("data10[%d] = encoded parities[%d][%d] = %x \n", - // ctr2 - 1, j, i, data10[ctr2 - 1]); - - rd = nrd; - } - } - - int data; - int val; - int offset = 0; - - for (i = 1; i <= SYNC_BITS * SAMPLES; i++) - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int bit = SYNC_BITS - i/SAMPLES + 1; - val = sync; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d sync bit %d = %d \n", - // ctr/SAMPLES, i, frames, bit, (data > 0) ); - if (FSK) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - - for (i = 1; - i <= (10 * (HEADER_LEN + DATA_LEN * PAYLOADS + RS_FRAMES * PARITY_LEN) * SAMPLES); i++) // 572 - { - write_wave(ctr); - if ( (i % SAMPLES) == 0) { - int symbol = (int)((i - 1)/ (SAMPLES * 10)); - int bit = 10 - (i - symbol * SAMPLES * 10) / SAMPLES + 1; - val = data10[symbol]; - data = val & 1 << (bit - 1); - // printf ("%d i: %d new frame %d data10[%d] = %x bit %d = %d \n", - // ctr/SAMPLES, i, frames, symbol, val, bit, (data > 0) ); - if (FSK) - { - phase = ((data != 0) * 2) - 1; - // printf("Sending a %d\n", phase); - } - else - { - if (data == 0) { - phase *= -1; - if ( (ctr - smaller) > 0) - { - for (int j = 1; j <= smaller; j ++) - buffer[ctr - j] = buffer[ctr - j] * 0.4; - } - flip_ctr = ctr; - } - } - } - } - } -// write_wav("transmit.wav", BUF_LEN, buffer, S_RATE); - - int error = 0; - int count; - for (count = 0; count < DATA_LEN; count++) { - printf("%02X", b[count]); - } - printf("\n"); - -// socket write - - struct sockaddr_in address; - int sock = 0, valread; - struct sockaddr_in serv_addr; -// char *hello = "Hello from client"; -// char buffer[1024] = {0}; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - printf("\n Socket creation error \n"); - error = 1; - } - - memset(&serv_addr, '0', sizeof(serv_addr)); - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) - { - printf("\nInvalid address/ Address not supported \n"); - error = 1; - } - - if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) - { - printf("\nConnection Failed \n"); - error = 1; - } - - if (!error) - { - printf("Sending buffer over socket!\n"); - send(sock, buffer, sizeof(buffer), 0); - } - -return 0; -} - -// wav file generation code - -/* make_wav.c - * Creates a WAV file from an array of ints. - * Output is monophonic, signed 16-bit samples - * copyright - * Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus - * Creative Commons license Attribution-NonCommercial - * http://creativecommons.org/licenses/by-nc/3.0/ - * - * Edited by Dolin Sergey. dlinyj@gmail.com - * April 11 12:58 2014 - */ - - // gcc -o make_enc_wav make_enc_wav.c -lm - // ./make_enc_wav - - /* - * TelemEncoding.h - * - * Created on: Feb 3, 2014 - * Author: fox - */ - -#include -#include -#include -#include -#include -#include - -//#include "make_wav.h" - -#define false 0 -#define true 1 - -//static int twosToInt(int val,int len); -//static int encodeB(short int *b, int index, int val); -//static int encodeA(short int *b, int index, int val); - - static int NOT_FRAME = /* 0fa */ 0xfa & 0x3ff; - static int FRAME = /* 0fa */ ~0xfa & 0x3ff; - -/* - * TelemEncoding.c - * - Fox-1 telemetry encoder - January 2014 Phil Karn KA9Q - - This file has two external functions: - void update_rs(unsigned char parity[32],unsigned char data); - int encode_8b10b(int *state,int data). - - update_rs() is the Reed-Solomon encoder. Its first argument is the 32-byte - encoder shift register, the second is the 8-bit data byte being encoded. It updates - the shift register in place and returns void. At the end of each frame, it contains - the parities ready for transmission, starting with parity[0]. - Be sure to zero this array before each new frame! - - encode_8b10b() is the 8b10b encoder. Its first argument is a pointer to a single integer - with the 1-bit encoder state (the current run disparity, or RD). Initialize it to 0 - JUST ONCE at startup (not between frames). - The second argument is the data byte being encoded. It updates the state and returns - an integer containing the 10-bit encoded word, right justified. - Transmit this word from left to right. - - The data argument is an int so it can hold the special value -1 to indicate end of frame; - it generates the 8b10b control word K.28.5, which is used as an inter-frame flag. - - Some assert() calls are made to verify legality of arguments. These can be turned off in - production code. - - - sample frame transmission code: - - unsigned char data[64]; // Data block to be sent - unsigned char parity[32]; // RS parities - void transmit_word(int); // User provided transmit function: 10 bits of data in bits 9....0 - int state,i; - - state = 0; // Only once at startup, not between frames - memset(parity,0,sizeof(parity); // Do this before every frame - // Transmit the data, updating the RS encoder - for(i=0;i<64;i++){ - update_rs(parity,data[i]); - transmit_word(encode_8b10b(&state,data[i]); - } - // Transmit the RS parities - for(i=0;i<32;i++) - transmit_word(encode_8b10b(&state,parity[i]); - - transmit_word(encode_8b10b(&state,-1); // Transmit end-of-frame flag -*/ - - -#include -//#include "Fox.h" -//#include "TelemEncoding.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define NN (0xff) // Frame size in symbols -#define A0 (NN) // special value for log(0) - - -// GF Antilog lookup table table -static unsigned char CCSDS_alpha_to[NN+1] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -// GF log lookup table. Special value represents log(0) -static unsigned char CCSDS_index_of[NN+1] = { - A0, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -// Only half the coefficients are given here because the -// generator polynomial is palindromic; G0 = G32, G1 = G31, etc. -// Only G16 is unique -static unsigned char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, -}; - - -static inline int modnn(int x){ - while (x >= NN) { - x -= NN; - x = (x >> 8) + (x & NN); - } - return x; -} - - -// Update Reed-Solomon encoder -// parity -> 32-byte reed-solomon encoder state; clear this to zero before each frame -void update_rs( - unsigned char parity[32], // 32-byte encoder state; zero before each frame - unsigned char c) // Current data byte to update -{ - unsigned char feedback; - int j,t; - - assert(parity != NULL); - feedback = CCSDS_index_of[c ^ parity[0]]; - if(feedback != A0){ // only if feedback is non-zero - // Take advantage of palindromic polynomial to halve the multiplies - // Do G1...G15, which is the same as G17...G31 - for(j=1;j0) - { buf = word & 0xff; - fwrite(&buf, 1,1, wav_file); - num_bytes--; - word >>= 8; - } -} - -/* information about the WAV file format from - -http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - - */ - -void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) -{ - FILE* wav_file; - unsigned int sample_rate; - unsigned int num_channels; - unsigned int bytes_per_sample; - unsigned int byte_rate; - unsigned long i; /* counter for samples */ - - num_channels = 1; /* monoaural */ - bytes_per_sample = 2; - - if (s_rate<=0) sample_rate = 44100; - else sample_rate = (unsigned int) s_rate; - - byte_rate = sample_rate*num_channels*bytes_per_sample; - - wav_file = fopen(filename, "w"); - assert(wav_file); /* make sure it opened */ - - /* write RIFF header */ - fwrite("RIFF", 1, 4, wav_file); - write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); - fwrite("WAVE", 1, 4, wav_file); - - /* write fmt subchunk */ - fwrite("fmt ", 1, 4, wav_file); - write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ - write_little_endian(1, 2, wav_file); /* PCM is format 1 */ - write_little_endian(num_channels, 2, wav_file); - write_little_endian(sample_rate, 4, wav_file); - write_little_endian(byte_rate, 4, wav_file); - write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ - write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ - - /* write data subchunk */ - fwrite("data", 1, 4, wav_file); - write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); - - for (i=0; i< num_samples; i++) - { write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); - } - - fclose(wav_file); -} - - - -//int main(int argc, char * argv[]) -//{ - -// return 0; -//} - -void write_wave(int i) -{ - if (FSK) - { -// if ((ctr - flip_ctr) < smaller) -// buffer[ctr++] = 0.1 * phase * (ctr - flip_ctr) / smaller; -// else - buffer[ctr++] = 0.25 * amplitude * phase; - } - else - { - if ((ctr - flip_ctr) < smaller) - buffer[ctr++] = (int)(amplitude * 0.4 * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - else - buffer[ctr++] = (int)(amplitude * phase * - sin((float)(2*M_PI*i*freq_Hz/S_RATE))); - } -// printf("%d %d \n", i, buffer[ctr - 1]); - -} - -/** - * - * FOX 1 Telemetry Decoder - * @author chris.e.thompson g0kla/ac2cz - * - * Copyright (C) 2015 amsat.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General 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 License for more details. - * - * You should have received a copy of the GNU General License - * along with this program. If not, see . - * - * - * Static variables and methods to encode and decode 8b10b - * - * - */ - -int encodeA(short int *b, int index, int val) { -// printf("Encoding A\n"); - b[index] = val & 0xff; - b[index + 1] = (b[index + 1] & 0xf0) | ((val >> 8) & 0x0f); - return 0; -} - -int encodeB(short int *b, int index, int val) { -// printf("Encoding B\n"); - b[index] = (b[index] & 0x0f) | ((val << 4) & 0xf0); - b[index + 1] = (val >> 4 ) & 0xff; - 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); -} diff --git a/afsk/send_afsk.c b/afsk/send_afsk.c deleted file mode 100644 index 4c551b50..00000000 --- a/afsk/send_afsk.c +++ /dev/null @@ -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 . - */ - -#include -#include -#include -#include -#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); - } -} - diff --git a/afsk/send_afsk.h b/afsk/send_afsk.h deleted file mode 100644 index 27c69d95..00000000 --- a/afsk/send_afsk.h +++ /dev/null @@ -1 +0,0 @@ -int send_afsk(int tlm[][5]); diff --git a/afsk/telem.c b/afsk/telem.c index 0e956f0e..42ef098a 100644 --- a/afsk/telem.c +++ b/afsk/telem.c @@ -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 . - * - * INA219 Raspberry Pi wiringPi code is based on Adafruit Arduino wire code - * from https://github.com/adafruit/Adafruit_INA219. */ #include @@ -25,167 +8,24 @@ #include #include #include -#include "status.h" -#include "ax5043.h" -#include "ax25.h" -#include "spi/ax5043spi.h" #include #include -#include -#include -#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); -} diff --git a/demo.sh b/demo.sh index 20aef361..bf29c4ce 100755 --- a/demo.sh +++ b/demo.sh @@ -2,6 +2,8 @@ echo -e "\nDemo of CubeSatSim at 434.9 MHz\n" +sleep 10 + sudo systemctl restart rpitx if [ "$1" = "a" ]; then diff --git a/documentation/readme.txt b/documentation/readme.txt deleted file mode 100644 index 978a68dc..00000000 --- a/documentation/readme.txt +++ /dev/null @@ -1 +0,0 @@ -These files are papers and presentations given about the CubeSat Simulator at the AMSAT Space Symposium and other places. diff --git a/python/current.py b/python/current.py new file mode 100644 index 00000000..409ca7ba --- /dev/null +++ b/python/current.py @@ -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") diff --git a/python/ina219_both_bus.py b/python/ina219_both_bus.py new file mode 100644 index 00000000..f6ee90d0 --- /dev/null +++ b/python/ina219_both_bus.py @@ -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) diff --git a/python/ina219_test.py b/python/ina219_test.py new file mode 100644 index 00000000..38435a84 --- /dev/null +++ b/python/ina219_test.py @@ -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) diff --git a/python/voltage.py b/python/voltage.py new file mode 100644 index 00000000..dc00ff81 --- /dev/null +++ b/python/voltage.py @@ -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") diff --git a/python/voltcurrent.py b/python/voltcurrent.py new file mode 100644 index 00000000..51d4444e --- /dev/null +++ b/python/voltcurrent.py @@ -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(" ")