mirror of
https://github.com/cosmic-pi-deprecated/cosmicpi-arduino_V1.6.git
synced 2026-05-12 16:09:25 +00:00
You need to connect the raspberry pi over a cable! Otherwise the EMC breaks events.
566 lines
14 KiB
C++
566 lines
14 KiB
C++
//Cosmic Pi software for Arduino - modified for STM32,
|
|
//J. Devine
|
|
//July 2019.
|
|
//Licensed under GPL V3 or later.
|
|
//cosmicpi.org
|
|
|
|
#include <Wire.h>
|
|
// LPS lib from here: https://github.com/pololu/lps-arduino
|
|
#include "src/LPS.h"
|
|
// LSM9DS1 lib from here: https://github.com/adafruit/Adafruit_LSM9DS1
|
|
//with some address tweaks
|
|
|
|
//#include "src/Adafruit_Sensor.h"
|
|
#include "src/Adafruit_LSM9DS1.h"
|
|
// HTU21D lib from here: https://github.com/adafruit/Adafruit_HTU21DF_Library
|
|
#include "src/SparkFunHTU21D.h"
|
|
|
|
|
|
//counter for how long the leds stay on.
|
|
int last_event_LED = 0;
|
|
|
|
|
|
// i2c
|
|
Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1();
|
|
|
|
//declare pressure sensor
|
|
LPS ps;
|
|
|
|
//Create an instance of the object
|
|
HTU21D myHumidity;
|
|
|
|
|
|
|
|
// string used for passing data from the dump routines
|
|
static const int TXTLEN = 512;
|
|
static char txt[TXTLEN]; //internal buffer
|
|
static char txts[TXTLEN]; //sensor buffer
|
|
|
|
|
|
//pinouts
|
|
/*
|
|
PA0 - Pin 14 - Shaped Signal 1
|
|
PA1 - Pin 15 - Shaped Signal 2
|
|
PA2 - Pin 16 - TX0
|
|
PA3 - Pin 16 - RX0
|
|
PA4 - Pin 20 - LED1 - Power/GPS
|
|
PA5 - Pin 21 - LED2 - Event
|
|
PA6 - Pin 22 - Injection leds
|
|
PA7 - Pin 23 - Bias FB1
|
|
PA8 - Pin 41 - SCL_Slave
|
|
PA9 - Pin 42 - USB_OTG_VBUS
|
|
PA10 - Pin 43 - GPSTX
|
|
PA11 - Pin 44 - USBOTG DM
|
|
PA12 - Pin 45 - USBOTG DP
|
|
PA13 - Pin 46 - SWDIO
|
|
PA14 - Pin 49 - SWCLK
|
|
PA15 - Pin 50 - GPSPPS Input
|
|
PB0 - Pin 26 - Bias FB2
|
|
PB1 - Pin 27 - Flag to RPi
|
|
PB2 Pin 28 - NC
|
|
PB 3 - Pin 55 - NC
|
|
PB4 - Pin 56 - SDA_Slave
|
|
PB5 - Pin 57 - NC
|
|
PB6 - Pin 58 - GPSRX
|
|
PB7 - Pin 59 - SDA0
|
|
PB8 - Pin 61 - SCL0
|
|
PB9 - Pin 62 - NC
|
|
PB10 - Pin 29 - Trigout (input to STM)
|
|
PB12 - Pin 33 - NC
|
|
PB13 - Pin 34 0 HVPSU SCLK (Clock to MAX1932)
|
|
PB14, PB15 - NC
|
|
PC0 - Pin 8 - NC
|
|
PC1 - Pin 9 - HVPSU CL1
|
|
PC2 - Pin 10 - HVPSU CL2
|
|
PC3 - Pin 11 - HV PSU DIN
|
|
PC4, PC5, PC6- NC
|
|
PC7 - Pin 38 - HVPSU CS2
|
|
PC8 - Pin 39 - HVPSU CS1
|
|
PC9 - Pin 40 - Mag Interrupt
|
|
PC10 - Pin 51 - NC
|
|
PC11 - Pin 52 - STRIGOUT B
|
|
PC12 - Pin 53 - STRIGOUT A
|
|
PC13 - Pin 2 - Baro Int
|
|
PC14 - Pin 3 - Accelint 1
|
|
PC15 - Pin 4 - Accelint 2.
|
|
|
|
*/
|
|
|
|
//eeprom writing table
|
|
/*
|
|
eeprom status byte - 00
|
|
channel 0 high byte - 01
|
|
channel 0 low byte - 02
|
|
channel 1 high byte - 03
|
|
channel 1 low byte - 04
|
|
HV bias ch 0 value - 05
|
|
HV bias ch 1 value - 06
|
|
|
|
if eeprom status byte = 1 then only one set of values are stored
|
|
if =2 then a backup set are located higher in memory, not used at the moment
|
|
*/
|
|
|
|
|
|
#include <Wire.h>
|
|
#include <EEPROM.h>
|
|
static const int SERIAL_BAUD_RATE = 19200; // Serial baud rate for version 1.5 production
|
|
static const int GPS_BAUD_RATE = 9600; // GPS and Serial1 line
|
|
|
|
// LED pins
|
|
#define PPS_PIN PA4 // PPS (Pulse Per Second) and LED
|
|
#define EVT_PIN PA5 // Cosmic ray event detected
|
|
|
|
char numconvbuff[16];
|
|
|
|
// Leds flag
|
|
bool leds_on = true;
|
|
|
|
// How long the event LED should light up (in ms)
|
|
static int event_LED_time = 15;
|
|
|
|
long eventCount = 0;
|
|
int eventStack = 0;
|
|
unsigned long pps_micros = 0;
|
|
unsigned long pps_micros_old = 0;
|
|
unsigned long micros_since_pps = 0;
|
|
|
|
#define maxevent 100 //we don't expect more events than this
|
|
unsigned long evttime [maxevent];
|
|
|
|
//set up serial output buffer
|
|
#define OutBuffSize 1024 //we don't expect more chars than this in the buffer
|
|
char outputbuffer[OutBuffSize]; //1024 character output buffer
|
|
int writeincounter = 0; //the place for writing to the buffer
|
|
int readoutcounter = 0; //the place for reading out from the buffer
|
|
|
|
void WriteToOutputBuff(char *outstring)
|
|
{
|
|
int stringlengthmax = strlen(outstring);
|
|
|
|
for (int addchar = 0; addchar < stringlengthmax; addchar++) {
|
|
outputbuffer[writeincounter] = outstring[addchar];
|
|
writeincounter++;
|
|
}
|
|
}
|
|
|
|
void ReadFromOutputBuff()
|
|
{
|
|
char digitout[2];
|
|
if (writeincounter > readoutcounter)
|
|
{
|
|
digitout[0] = outputbuffer[readoutcounter];
|
|
digitout[1] = '\0';
|
|
Serial.print(digitout);
|
|
readoutcounter++;
|
|
}
|
|
if (readoutcounter == writeincounter) {
|
|
readoutcounter = 0;
|
|
writeincounter = 0;
|
|
//Serial.println("BUFFERCLEAR");
|
|
}
|
|
}
|
|
|
|
void setupSensor()
|
|
{
|
|
// 1.) Set the accelerometer range
|
|
lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_2G);
|
|
//lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_4G);
|
|
//lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_8G);
|
|
//lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_16G);
|
|
|
|
// 2.) Set the magnetometer sensitivity
|
|
lsm.setupMag(lsm.LSM9DS1_MAGGAIN_4GAUSS);
|
|
//lsm.setupMag(lsm.LSM9DS1_MAGGAIN_8GAUSS);
|
|
//lsm.setupMag(lsm.LSM9DS1_MAGGAIN_12GAUSS);
|
|
//lsm.setupMag(lsm.LSM9DS1_MAGGAIN_16GAUSS);
|
|
|
|
// 3.) Setup the gyroscope
|
|
lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_245DPS);
|
|
//lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_500DPS);
|
|
//lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_2000DPS);
|
|
}
|
|
|
|
|
|
|
|
// GPS and time flags
|
|
boolean gps_ok = false; // Chip OK flag
|
|
boolean pps_recieved = false;
|
|
|
|
|
|
|
|
// ------------------------- Arudino Functions
|
|
|
|
// Arduino setup function, initialize hardware and software
|
|
// This is the first function to be called when the sketch is started
|
|
|
|
//setup serials
|
|
HardwareSerial GPS(PA10, PB6);
|
|
|
|
void setup() {
|
|
Serial.begin(SERIAL_BAUD_RATE);
|
|
Serial.print("ON");
|
|
|
|
//init pins that aren't used for stability
|
|
pinMode(PA0, INPUT);
|
|
pinMode(PA1, INPUT);
|
|
pinMode(PA6, OUTPUT);
|
|
pinMode(PA7, INPUT);
|
|
pinMode(PA8, INPUT);
|
|
pinMode(PB0, INPUT);
|
|
pinMode(PB1, OUTPUT);
|
|
pinMode(PB4, INPUT);
|
|
|
|
pinMode(PC9, INPUT);
|
|
pinMode(PC11, INPUT);
|
|
pinMode(PC12, INPUT);
|
|
pinMode(PC13, INPUT);
|
|
pinMode(PC14, INPUT);
|
|
pinMode(PC15, INPUT);
|
|
|
|
|
|
if (leds_on) {
|
|
pinMode(EVT_PIN, OUTPUT); // Pin for the cosmic ray event
|
|
pinMode(PPS_PIN, OUTPUT); // Pin for the PPS (LED pin)
|
|
}
|
|
if (leds_on) {
|
|
digitalWrite(PPS_PIN, HIGH); // Turn on led
|
|
}
|
|
|
|
// start the GPS
|
|
GPS.begin(GPS_BAUD_RATE);
|
|
GpsSetup();
|
|
|
|
// start the i2c bus
|
|
Wire.begin();
|
|
Wire.setSDA(PB7);
|
|
Wire.setSCL(PB8);
|
|
|
|
//setup the thresholds
|
|
//initialise to values from EEPROM, else use defaults.
|
|
|
|
int eeprom_read = 0;
|
|
|
|
eeprom_read = EEPROM.read(0x00);
|
|
if (eeprom_read > 0) {
|
|
|
|
Serial.println("Found existing settings for Thresholds and HV, these will be applied");
|
|
Serial.print("First channel threshold settings: 0x");
|
|
Serial.print(EEPROM.read(0x01), HEX);
|
|
Serial.println(EEPROM.read(0x02), HEX);
|
|
Serial.print("Second channel threshold settings: 0x");
|
|
Serial.print(EEPROM.read(0x03), HEX);
|
|
Serial.println(EEPROM.read(0x04), HEX);
|
|
|
|
|
|
|
|
Wire.begin();
|
|
Wire.beginTransmission(byte(0x60)); // transmit to device #112
|
|
Wire.write(byte(0x00)); //sets value to the first channel
|
|
eeprom_read = EEPROM.read(0x01);
|
|
Wire.write(byte(eeprom_read));
|
|
eeprom_read = EEPROM.read(0x02);
|
|
Wire.write(byte(eeprom_read));
|
|
Wire.endTransmission(); // stop transmitting
|
|
|
|
Wire.beginTransmission(byte(0x60)); // transmit to device #112
|
|
Wire.write(byte(0x01)); //sets value to the first channel
|
|
eeprom_read = EEPROM.read(0x03);
|
|
Wire.write(byte(eeprom_read));
|
|
eeprom_read = EEPROM.read(0x04);
|
|
Wire.write(byte(eeprom_read));
|
|
Wire.endTransmission(); // stop transmitting
|
|
Serial.println("Threshold settings complete");
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
Serial.println("No existing settings for Thresholds and HV found, using defaults");
|
|
Serial.print("First channel threshold settings: 0x");
|
|
Serial.print(0x22F, HEX);
|
|
Serial.print("Second channel threshold settings: 0x");
|
|
Serial.print(0x22F, HEX);
|
|
|
|
|
|
Wire.begin();
|
|
Wire.beginTransmission(byte(0x60)); // transmit to device #112
|
|
Wire.write(byte(0x00)); //sets value to the first channel
|
|
Wire.write(byte(0x02));
|
|
Wire.write(byte(0x2F));
|
|
Wire.endTransmission(); // stop transmitting
|
|
|
|
Wire.beginTransmission(byte(0x60)); // transmit to device #112
|
|
Wire.write(byte(0x01)); //sets value to the first channel
|
|
Wire.write(byte(0x02));
|
|
Wire.write(byte(0x2F));
|
|
Wire.endTransmission(); // stop transmitting
|
|
|
|
Serial.println("Threshold settings complete");
|
|
|
|
|
|
}
|
|
|
|
//set the high voltage
|
|
|
|
//config SPI pins
|
|
pinMode(PC7, OUTPUT);
|
|
pinMode(PC8, OUTPUT);
|
|
pinMode(PC3, OUTPUT);
|
|
pinMode(PB13, OUTPUT);
|
|
|
|
|
|
eeprom_read = EEPROM.read(0x00);
|
|
if (eeprom_read > 0) {
|
|
Serial.println("Applying stored values for HV channels");
|
|
|
|
Serial.print("HV channel settings Ch1: ");
|
|
Serial.print(EEPROM.read(0x05), HEX);
|
|
Serial.print(" Ch2: ");
|
|
Serial.println(EEPROM.read(0x06), HEX);
|
|
|
|
//set HV channel 1
|
|
eeprom_read = EEPROM.read(0x05);
|
|
digitalWrite(PC7, LOW);
|
|
setHV(byte(eeprom_read));
|
|
digitalWrite(PC7, HIGH);
|
|
//set HV channel 2
|
|
eeprom_read = EEPROM.read(0x06);
|
|
digitalWrite(PC8, LOW);
|
|
setHV(byte(eeprom_read));
|
|
digitalWrite(PC8, HIGH);
|
|
|
|
Serial.println("HV channels set");
|
|
|
|
}
|
|
else
|
|
{
|
|
Serial.println("Applying default values for HV channels");
|
|
|
|
Serial.print("HV channel settings Ch1: ");
|
|
Serial.print(0xAC, HEX);
|
|
Serial.print(" Ch2: ");
|
|
Serial.println(0xAC, HEX);
|
|
|
|
digitalWrite(PC7, LOW);
|
|
setHV(0xAC);
|
|
digitalWrite(PC7, HIGH);
|
|
//set HV channel 2
|
|
digitalWrite(PC8, LOW);
|
|
setHV(0xAC);
|
|
digitalWrite(PC8, HIGH);
|
|
Serial.println("HV channels set");
|
|
|
|
}
|
|
|
|
|
|
|
|
//init the sensor suite
|
|
|
|
Serial.println("Cosmic Pi V1.6 sensor init routine");
|
|
//init LSM9DS1
|
|
//lsm.begin();
|
|
|
|
if (!lsm.begin())
|
|
{
|
|
Serial.println("Oops ... unable to initialize the LSM9DS1. Check your wiring!");
|
|
while (1);
|
|
}
|
|
setupSensor();
|
|
lsm.read(); /* ask it to read in the data */
|
|
|
|
/* Get a new sensor event */
|
|
sensors_event_t a, m, g, temp;
|
|
|
|
lsm.getEvent(&a, &m, &g, &temp);
|
|
|
|
//init lps
|
|
ps.init();
|
|
ps.enableDefault();
|
|
|
|
//init htu21d
|
|
myHumidity.begin();
|
|
|
|
Serial.println("INFO: Sensor setup complete\n");
|
|
//attach the interrupts
|
|
attachInterrupt(digitalPinToInterrupt(PA15), GPS_PPS, RISING);
|
|
attachInterrupt(digitalPinToInterrupt(PB10), Event_Int, RISING);
|
|
|
|
//Serial.println();
|
|
sprintf(txt, "INFO: Running\n");
|
|
WriteToOutputBuff(txt);
|
|
}
|
|
|
|
|
|
void GPS_PPS()
|
|
{
|
|
//now PPS is coming through, we can switch off the internal timer.
|
|
pps_recieved = true;
|
|
|
|
//stop listening for events while we process this interrupt
|
|
detachInterrupt(digitalPinToInterrupt(PB10));
|
|
|
|
//now PPS is coming through, we can switch off the internal timer.
|
|
//pps_recieved = true;
|
|
|
|
//set the pps micros value as the micro time now, and buffer the last value;
|
|
pps_micros_old = pps_micros;
|
|
pps_micros = micros();
|
|
//how many microseconds since the last pps? (just in case we're running fast/slow)
|
|
micros_since_pps = pps_micros - pps_micros_old;
|
|
|
|
if (leds_on) {
|
|
digitalWrite(PPS_PIN, !digitalRead(PPS_PIN)); // Toggle led
|
|
}
|
|
|
|
|
|
//Serial.println("pps");
|
|
//process all events to the event buffer now that the second has ended
|
|
//Serial.print("Dumping Event Buffer");
|
|
//print out the event stack
|
|
for (int i = 0; i < eventStack; i++) {
|
|
sprintf(txt, "Event: sub second micros:%d/%d; Event Count:%d\n", evttime[i], micros_since_pps, (eventCount - eventStack + i));
|
|
WriteToOutputBuff(txt);
|
|
}
|
|
sprintf(txt, "PPS: GPS lock:1;\n");
|
|
WriteToOutputBuff(txt);
|
|
|
|
|
|
//now print the sensors
|
|
//Serial.print("Sensor section");
|
|
lsm.read(); /* ask it to read in the data */
|
|
//debug cmd
|
|
//sprintf(txt, "readfail;\n");
|
|
//WriteToOutputBuff(txt);
|
|
/* Get a new sensor event */
|
|
|
|
sensors_event_t a, m, g, temp;
|
|
lsm.getEvent(&a, &m, &g, &temp);
|
|
|
|
float pressure = ps.readPressureMillibars();
|
|
float altitude = ps.pressureToAltitudeMeters(pressure);
|
|
float temperature = ps.readTemperatureC();
|
|
|
|
float humd = myHumidity.readHumidity();
|
|
float temphum = myHumidity.readTemperature();
|
|
|
|
Serial.print("Altitude: ");
|
|
Serial.print(altitude, 6);
|
|
Serial.println(';');
|
|
Serial.print("TemperatureCBaro: ");
|
|
Serial.print(temperature, 6);
|
|
Serial.println(';');
|
|
|
|
Serial.print("AccelX: ");
|
|
Serial.print(a.acceleration.x, 6);
|
|
Serial.println(';');
|
|
Serial.print("AccelY: ");
|
|
Serial.print(a.acceleration.y, 6);
|
|
Serial.println(';');
|
|
Serial.print("AccelZ: ");
|
|
Serial.print(a.acceleration.z, 6);
|
|
Serial.println(';');
|
|
|
|
Serial.print("MagX: ");
|
|
Serial.print(m.magnetic.x, 6);
|
|
Serial.println(';');
|
|
Serial.print("MagY: ");
|
|
Serial.print(m.magnetic.y, 6);
|
|
Serial.println(';');
|
|
Serial.print("MagZ: ");
|
|
Serial.print(m.magnetic.z, 6);
|
|
Serial.println(';');
|
|
|
|
Serial.print("TemperatureCHumid: ");
|
|
Serial.print(temphum, 6);
|
|
Serial.println(';');
|
|
|
|
Serial.print("Humidity: ");
|
|
Serial.print(humd, 6);
|
|
Serial.println(';');
|
|
|
|
//average temp from all 3 sensors
|
|
float out = 0;
|
|
out = temphum + temperature;
|
|
out = out / 2;
|
|
Serial.print("TemperatureC: ");
|
|
Serial.print(out, 6);
|
|
Serial.println(';');
|
|
//Serial.print(txts);
|
|
|
|
|
|
|
|
|
|
//now we can reset the event stack and listen for events again
|
|
eventStack=0;
|
|
attachInterrupt(digitalPinToInterrupt(PB10), Event_Int, RISING);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
pipeGPS();
|
|
ReadFromOutputBuff();
|
|
|
|
//turn off the event led after the set time
|
|
if (millis() >= (last_event_LED + event_LED_time)){
|
|
if (leds_on) {
|
|
digitalWrite(EVT_PIN, LOW);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Event_Int()
|
|
{
|
|
detachInterrupt(digitalPinToInterrupt(PB10));
|
|
|
|
|
|
//only count if we've got a PPS
|
|
if (pps_recieved == true){
|
|
|
|
/* WriteToOutputBuff("evtx:");
|
|
ltoa(eventCount,numconvbuff,10);
|
|
WriteToOutputBuff(numconvbuff);
|
|
|
|
//Serial.print(name);
|
|
Serial.print("count=");
|
|
Serial.print(eventCount);
|
|
Serial.print(" ");
|
|
Serial.println(micros()-pps_micros);
|
|
*/
|
|
eventCount++;
|
|
//Serial.println("e");
|
|
//write this event to the stack of times
|
|
evttime[eventStack] = micros() - pps_micros;
|
|
//increment the stack counter
|
|
eventStack++;
|
|
|
|
//turn on the event led
|
|
last_event_LED = millis();
|
|
if (leds_on) {
|
|
digitalWrite(EVT_PIN, HIGH);
|
|
}
|
|
|
|
attachInterrupt(digitalPinToInterrupt(PB10), Event_Int, RISING);
|
|
}
|
|
}
|
|
|
|
byte setHV(byte _send) // This function is what bitbangs the data
|
|
{
|
|
if (_send > 0x5F) {
|
|
for (int i = 0; i < 8; i++) // There are 8 bits in a byte
|
|
{
|
|
digitalWrite(PC3, bitRead(_send, 7 - i)); // Set MOSI
|
|
//delay(1);
|
|
digitalWrite(PB13, HIGH); // SCK high
|
|
//bitWrite(_receive, i, digitalRead(MISO_pin)); // Capture MISO
|
|
digitalWrite(PB13, LOW); // SCK low
|
|
//digitalWrite(MOSI_pin, LOW); // Set MOSI
|
|
|
|
}
|
|
//digitalWrite(SS_pin[j], HIGH); // SS high again
|
|
}
|
|
}
|
|
;
|