// Triple Pendulum controller, STM32F103C6T8 "BluePill"
// IDE Tools setup: "Generic STM32F103C series", upload method=serial, optimise=fastest (uses 43% flash)
// Additional Boards Managers URLs: http://dan.drown.org/stm32duino/package_STM32duino_index.json
// 0819 change state names
// 0820 led, restructure main loop
// 0821 big test pwb, change pin numbers
// 0822 working, but analog signals messed up - feedthrough
// 0823 add aux blank
// 0824 revert - timer1 ch2 either kills print or does not get evoked
// 0825 abandon timer1 ch2, use timer4 instead
// 0828 all working
// 0830 P3 startup
// 0831 rethink boost calculation = constant in STABLE state
// 0832 STABLE state: min constrain = sustain value
// 0833 P1 startup, two cases; captured by magnet or not, difficult if not, eval STARTUP exit criteria
// 0834 work on dead state
// 0840 new state names, new dead state algorithm
// 0842 working
// 0843 reset boost counter BOOST->STABLE
// 0844 P1 start conditions, PxperiodCmd is being reset to zero
// +-----------+
// scope T1BKIN |PB12 GND |
// T1C1N |PB13 GND |
// T1C2N |PB14 V3V |
// T1C3N |PB15 RST |
// T1C1 |PA8 PB11| RX3 SDA2
// IDE TX T1C2 |PA9 PB10| TX3 SCL2
// IDE RX T1C3 |PA10 PB1 | ADC9 T3C4
// USB- T1C4 |PA11 PB0 | ADC8 T3C3 scope
// USB+ T1ETR |PA12 PA7 | ADC7 MOSI1 T3C2 led
// T2C1E |PA15 PA6 | ADC6 MISO1 T3C1
// T2C2 |PB3 PA5 | ADC5 SCK1
// P1 blank T3C1 |PB4 PA4 | ADC4 NSS1 P3 signal
// P2 blank T2C2 |PB5 PA3 | ADC3 RX2 T2C4
// P3 blank T4C1 |PB6 PA2 | ADC2 TX2 T2C3
// P3 gate T4C2 |PB7 PA1 | ADC1 T2C2 P2 signal
// P2 gate SCL1 T4C3 |PB8 PA0 | ADC0 WKUP T2C1E P1 signal
// P1 gate SDA1 T4C4 |PB9 PC15 | OSC32
// +5 |5V PC14 | OSC32
// GND |GND PC13 | LED
// 3V3 |3V3 VBAT |
// +-----------+
// ------------------------- STM32F103C6 ----------------------
// ints are 4 bytes, +/-2,147,483,648
// STM32F pullup/down R ~40k Ohms
// Fault Tolerant; PA8-15, PB2-4, 6-15, PC6-9, 10-12
// Not Fault Tolerant; PA0-7, PB0-1, 5, PC0-5, 13-15
// ------------------------ Coil data --------------------------
// coil is ~20 mH, saturates in 7 mS @ boost level=15
// ~12 Ohms (32ga wire), 6 Ohms (28ga wire)
// .5" soft iron core, 3" long, ~600 turns
HardwareTimer pirTimer(1); // timer1, name=pirTimer, use channel 1
HardwareTimer P2timer(2); // timer2, name=P2timer, using channels 1,2,3
HardwareTimer P3timer(3); // timer3, name=P3timer, using channels 1,2,3
HardwareTimer P4timer(4); // timer4, name=P4timer, using channels 1,2,3
// ------------------------- Pins ------------------------------------
#define P1signalPin PA0 // P1 signal, analog
#define P2signalPin PA1 // P2 signal, analog
#define P3signalPin PA4 // P3 signal, analog
#define P1blankPin PB4 // P1 MOSFET blanking clamp
#define P2blankPin PB5 // P2 MOSFET blanking clamp
#define P3blankPin PB6 // P3 MOSFET blanking clamp
#define P1gatePin PB9 // P1 MOSFET coil power
#define P2gatePin PB8 // P2 MOSFET coil power
#define P3gatePin PB7 // P3 MOSFET coil power
#define ledPin PA7 // led, active high
#define scopePin PB0 // debug
// ------------------------------- Variables ---------------------------------------------
byte report; // which P to report on
byte lineCounter; // renew heading title line counter
uint32_t loops; // show main loops/second execution rate
uint16_t seconds; // seconds counter, very long time
char const TAB = 9; // tab
byte const STARTUP = 0; // all pendulums start in STARTUP state
byte const BOOST = 1; // BOOSTing, either being kicked by STARTUP isr or BOOST case
byte const STABLE = 2; // STABLE, kicked by STABLE case
byte const timex = 50; // supplimental blank transcient suppression, 1mS ticks
byte P1boostCount; // count after successfully exiting STARTUP state
byte P1state; // state of P1
byte P1startCount; // not used
uint16_t P1periodCmd; // desired period
uint16_t P1periodAct; // actual period
uint16_t P1signal; // signal from magnet approaching coil
uint16_t P1sigMax; // used to detect approaching magnet
uint16_t P1countA; // half period
uint16_t P1countB; // other half period
uint16_t P1boost; // amount of energization to deliver to coil
uint16_t P1blank; // time to clamp P1 signal to ground, greater than boost
int16_t P1periodErr; // signed, command - actual
boolean P1flip; // flipflop for period measurement
boolean P1blankFinished;// signal clamp released
boolean P1blankx; // brief blank active when another channel releases
boolean P1osc; // flag set by isr channel 3 to excite P1 at fundamental freq
float P1Kp=1; // proportional term of PID control loop
byte P2boostCount; // count after successfully exiting STARTUP state
byte P2state; // state of P2
byte P2startCount; // not used
uint16_t P2periodCmd; // desired period
uint16_t P2periodAct; // actual period
uint16_t P2signal; // signal from magnet approaching coil
uint16_t P2sigMax; // used to detect approaching magnet
uint16_t P2countA; // half period
uint16_t P2countB; // other half period
uint16_t P2boost; // amount of mag energization to deliver to coil
uint16_t P2blank; // time to clamp P1 signal to ground, greater than boost
int16_t P2periodErr; // signed, command - actual
uint16_t P2sigAveSave; // save for report
boolean P2flip; // flipflop for period measurement
boolean P2magDetect; // mag signal detected flag
boolean P2blankFinished;// signal clamp released
boolean P2blankx; // brief blank active when another channel releases
boolean P2osc; //
float P2Kp=.5; // proportional term of PID control loop
byte P3boostCount; // count after successfully exiting STARTUP state
byte P3state; // state of P3
byte P3startCount; //
uint16_t P3periodCmd; // desired period
uint16_t P3periodAct; // actual period
uint16_t P3signal; // signal from magnet approaching coil
uint16_t P3sigMax; //
uint16_t P3countA; // half period
uint16_t P3countB; // other half period
uint16_t P3boost; // amount of mag energization to deliver to coil
uint16_t P3blank; // time to clamp P1 signal to ground, greater than boost
int16_t P3periodErr; // signed, command - actual
uint16_t P3sigAveSave; // save for report
boolean P3flip; // flipflop for period measurement
boolean P3magDetect; // mag signal detected flag
boolean P3blankFinished;// signal clamp released
boolean P3blankx; // brief blank active when another channel releases
boolean P3osc;
float P3Kp=1; // proportional term of PID control loop
uint16_t volatile P1timex; // 3 timers control blanking of signal artifact generated
uint16_t volatile P2timex; // when a coil is switched off. Timers generate blanking on
uint16_t volatile P3timex; // other coil signals for brief period (~50ms).
// -------------------------- Timer1 ISR --------------------------------
void pirIsr(void) { // interrupt is called 1000x/sec
if(P1timex) { // decrement timer until=0
P1timex--; // if signal normal blanking is not active release clamp
if(!P1timex && P1blankFinished) digitalWrite(P1blankPin, LOW);// release signal clamp
}
if(P2timex) {
P2timex--;
if(!P2timex && P2blankFinished) digitalWrite(P2blankPin, LOW);
}
if(P3timex) {
P3timex--;
if(!P3timex && P3blankFinished) digitalWrite(P3blankPin, LOW);
}
}
// ------------------------- Timer4 ISRs --------------------------------
// Timer 1 channel 2 interacts with print, so must use timer 4
// Timer 4 is associated with Pendulum 1, Timer2->P2, Timer3->P3
// Channel 1 turns off coil MOSFET gate
// Channel 2 turns off signal blanking clamp MOSFET
// Channel 3 detects no activity -> issues kick to start moving
void P4chan1isr() { // coil off->induces spike on other analog channels
digitalWrite(P1gatePin,LOW); // turn off coil
digitalWrite(ledPin, LOW); // turn off led
digitalWrite(P2blankPin, HIGH); // inactive channels clamped
digitalWrite(P3blankPin, HIGH); // inactive channels clamped
P1timex = 0; // not this channel
P2timex = timex; // start blanking, short time
P3timex = timex; // start blanking
}
void P4chan2isr() { // channel 2 turns off signal blanking clamp P1
digitalWrite(P1blankPin,LOW); // turn off blanking clamp
P1blankFinished = true; // set flag -> blank finished
}
void P4chan3isr() { // channel 3 generates startup waveform then detects dead P1
P1startCount = 0; // not used
P1state = STARTUP; // P1 must be dead if this isr executes
report = 1;
lineCounter = 0;
P1osc = true;
}
// ----------------------- Timer2 ISRs -----------------------------------
void P2chan1isr() {
digitalWrite(P2gatePin,LOW); // kick off
digitalWrite(ledPin, LOW); // turn off led
digitalWrite(P1blankPin, HIGH);
digitalWrite(P3blankPin, HIGH);
P2timex = 0;
P1timex = timex;
P3timex = timex;
}
void P2chan2isr() {
digitalWrite(P2blankPin,LOW); // blank off
P2blankFinished = true;
}
void P2chan3isr() { //
P2startCount = 0;
P2state = STARTUP; // must clamp for 1.5sec after pulse finish
report = 2;
lineCounter = 0;
P2osc = true;
}
// -------------------------- Timer3 ISRs --------------------------------
void P3chan1isr() {
digitalWrite(P3gatePin,LOW); // kick off
digitalWrite(ledPin, LOW); // turn off led
digitalWrite(P2blankPin, HIGH);
digitalWrite(P1blankPin, HIGH);
P3timex = 0;
P2timex = timex;
P1timex = timex;
}
void P3chan2isr() {
digitalWrite(P3blankPin,LOW); // blank off
P3blankFinished = true;
}
void P3chan3isr() {
P3startCount = 0;
P3state = STARTUP;
report = 3;
lineCounter = 0;
P3osc = true;
}
//------------------------------- Setup ---------------------------------
void setup() {
disableDebugPorts(); // required to access PB3, PB4(!), PA13, PA14 & PA15
pinMode(P1signalPin,INPUT_ANALOG);// signal detection circuit
pinMode(P2signalPin,INPUT_ANALOG);//
pinMode(P3signalPin,INPUT_ANALOG);//
pinMode(P1gatePin, OUTPUT); // coil MOSFET gate pin
pinMode(P2gatePin, OUTPUT);
pinMode(P3gatePin, OUTPUT);
pinMode(P1blankPin, OUTPUT); // signal blanking MOSFET gate pin
pinMode(P2blankPin, OUTPUT);
pinMode(P3blankPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(scopePin, OUTPUT); // debug
digitalWrite(ledPin, HIGH); // led on
digitalWrite(P1gatePin, LOW); // turn off P1 coil
digitalWrite(P2gatePin, LOW);
digitalWrite(P3gatePin, LOW);
digitalWrite(P1blankPin,LOW); // P1 blanking off, allow P1 signal
digitalWrite(P2blankPin,LOW);
digitalWrite(P3blankPin,LOW);
Serial.begin(9600); // 9600 Baud to Arduino IDE monitor
// -------------------- Timer1, 1 mS timebase -----------------------
pirTimer.pause(); // pause timer4
pirTimer.setPrescaleFactor(72); // set timer 4 prescaler
pirTimer.setOverflow(1000); // period
pirTimer.setMode(1,TIMER_OUTPUT_COMPARE); // channel 1, generate interrupt on compare
pirTimer.setCompare(1,1); // interrupt at start
pirTimer.attachInterrupt(1,pirIsr); // attach interrupt
pirTimer.refresh(); // scope confirm 1mS timebase
pirTimer.resume(); // continue
// -------------------- Timer4, P1 timer -----------------------
P4timer.pause(); // pause timer4
P4timer.setPrescaleFactor(36000); // 72MHz/36000=2kHz, .5mS/tick
P4timer.setOverflow(65535); // period, 32.768 sec rollover
P4timer.refresh(); // refresh
P4timer.resume(); // continue
// -------------------- timer2, P2 timer -----------------------
P2timer.pause(); // pause timer2
P2timer.setPrescaleFactor(36000); // set timer 2 prescaler, .5mS/tick
P2timer.setOverflow(65535); // period, 32 sec
P2timer.refresh(); // refresh
P2timer.resume(); // continue
// -------------------- Timer3, P3 timer -------------------------
P3timer.pause(); // pause timer3
P3timer.setPrescaleFactor(36000); // set timer 3 prescaler
P3timer.setOverflow(65535); // period, 32 sec
P3timer.refresh(); // refresh
P3timer.resume(); // continue
P1periodCmd = 8100; // nominal periods for pendulums
P2periodCmd = 12500;
P3periodCmd = 6600;
P1blankFinished = true;
P2blankFinished = true;
P3blankFinished = true;
digitalWrite(P1blankPin, LOW);
digitalWrite(P2blankPin, LOW);
digitalWrite(P3blankPin, LOW);
P1osc = true;
P2osc = true;
P3osc = true;
report = 2;
}
// -------------------------------- Main ---------------------------------
// Each pendulum has 3 conditions; STARTUP, BOOSTing and STABLE
// Pendulum starts STARTUP. Channel 3 kicks after timeout. Random kicks will get it moving.
// Dead kick recurring timeout should be greater than natural period.
// After STARTUP kick, pendulm enters BOOST state where signal determines kick timing.
// After several swings->STABLE state. Amount of kick in STABLE state is closed loop control.
// P1 P2 P3
// -- -- --
// 240 420 200 millisec period during startup (magnetic capture) phase
// 7800 11800 6200 timer ticks period during stable running state
// 8300 12500 6750 max period of pendulums
// 7650 11500 6100 min period
// digitalWrite(scopePin, !digitalRead(scopePin));
// digitalWrite(ledPin, !digitalRead(ledPin));
void loop() {
loops++; // execution rate 66k (P3) to 120k (P2)loops/kick
if(P2state==STABLE) P1(); // start P2 after P1 is STABLE
P2(); // P2 is hardest to start, goes longest, start first
if(P1state==STABLE) P3(); // P3 is easiest to start, sustains least, start last
// P1();
// P2();
// P3();
if(Serial.available()) opCom(); // get operator command
}
// --------------------------- P1 state machine --------------------------------
void P1() {
P1signal = analogRead(P1signalPin); // read signal for this pendulum
P1sigMax = max(P1signal,P1sigMax); // looking for max signal level
switch(P1state) { // STABLE, BOOST, STARTUP
case STABLE: // steady state - works perfectly
if((P1sigMax>3000)&&(P1signal<10)&&P1blankFinished) {
P1periodErr = P1periodCmd - P1periodAct;// error
P1boost = 10 + (P1Kp*P1periodErr); // calc P term
P1boost = constrain(P1boost,9,80); // "9" is sustain
P1blank = 2600; // period is ~3900, blank 2600 good
P1kick(P1boost, P1blank,10000); // blank for 1 second, STARTUP after 30 sec
}
break;
case BOOST: // tricky->low signal level, ADC noise
if((P1sigMax>2000)&&(P1signal<10)&&P1blankFinished) {
P1boostCount++; // count successful kicks
if(P1boostCount>10) {
P1boostCount = 0;
P1state = STABLE; // change state
}
P1boost = 100; // must synch with rapid freq period
P1blank = 300; // during BOOST phase (captive of magnet), else 2700
P1kick(P1boost,P1blank,5000); //
}
break;
case STARTUP: // signal goes to zero only when
if(P1sigMax>3500) P1state = BOOST; // magnet swings past coil
if(P1osc) { // BOOST state does not trigger
P1osc = false; // if magnet recaptures pendulum
P1kick(200, 250, random(1050,1150)); // after exiting STARTUP state
} // 1100 works
break;
}
}
// ----------------------------- P2 state machine -----------------------------------
void P2() {
P2signal = analogRead(P2signalPin); // read signal for this pendulum
P2sigMax = max(P2signal,P2sigMax); // recored max sig for this cycle
switch(P2state) { // STARTUP or STABLE
case STABLE: // steady state
if((P2sigMax>3000)&&(P2signal<10)&&P2blankFinished) {
P2periodErr = P2periodCmd - P2periodAct;// error
P2boost = 14 + (P2Kp*P2periodErr); // calc P term
P2boost = constrain(P2boost,9,80); // "9" is sustain
P2blank = 5000; // period ~5900, 5000 good for period>10800
P2kick(P2boost,P2blank,20000); // blank for 1 second, STARTUP after 5 sec
}
break;
case BOOST: // tricky->low signal level, ADC noise
if((P2sigMax>2000)&&(P2signal<10) && P2blankFinished) {
P2boostCount++; // count successsful kicks
if(P2boostCount>10) {
P2boostCount = 0;
P2state = STABLE; // change state
}
P2boost = 100;
P2blank = 1000; // high freq, captive of magnet
P2kick(P2boost,P2blank,20000); // big kick, blank 1.5s, STARTUP after 10s
}
break;
case STARTUP: //
if(P2sigMax>3500) P2state = BOOST; // magnet swings past coil
if(P2osc) { // BOOST state does not trigger
P2osc = false; // if magnet recaptures pendulum
P2kick(400, 450, random(2700,2800)); // after exiting STARTUP state
} // 2750 works
break;
}
}
// ----------------------------- P3 state machine -----------------------------------
void P3() {
P3signal = analogRead(P3signalPin); // read signal for this pendulum
P3sigMax = max(P3signal,P3sigMax); // record max signal
switch(P3state) { // STARTUP, BOOST, STABLE
case STABLE: // steady state - works perfectly
if((P3sigMax>3000)&&(P3signal<10)&&P3blankFinished) {
P3periodErr = P3periodCmd - P3periodAct;// error
P3boost = 10 + (P3Kp*P3periodErr); // calc P term
P3boost = constrain(P3boost,7,80); // "7" is sustain
P3blank = 2400; // period ~3100 (2400 good)
P3kick(P3boost,P3blank,10000); // blank for 1 second, STARTUP after 10 sec
}
break;
case BOOST: // getting started, constant kick
if((P3sigMax>2000)&&(P3signal<10)&&P3blankFinished) {
P3boostCount++; // count successful kicks
if(P3boostCount>10) {
P3boostCount = 0;
P3state = STABLE; // change state
}
P3boost = 100; // constant, large kick in boost phase
P3blank = 500; // blank should be brief in case wrong trigger
P3kick(P3boost,P3blank,4000); // big kick
}
break;
case STARTUP: // tricky->low signal level, ADC noise
if(P3sigMax>3500) P3state = BOOST; // magnet swings past coil
if(P3osc) { // BOOST state does not trigger
P3osc = false; // if magnet recaptures pendulum
P3kick(400, 600, random(1500,2600)); // after exiting STARTUP state
} // random(1500,2600) works
break;
}
}
// -------------------------- P1 coil control ----------------------------
void P1kick(uint16_t bst, uint16_t blnk, uint16_t ded) {
if(report==1) digitalWrite(ledPin,HIGH);// turn on led if report to this P is active
P1flip = !P1flip; // flip flop
P4timer.pause(); // stop timer
if(P1flip) P1countA = P4timer.getCount();// calc period of P4
else P1countB = P4timer.getCount();// get half count
P1periodAct = P1countA + P1countB; // add two halves
P4timer.setCount(0); // restart timer at zero count
P4timer.attachInterrupt(1,P4chan1isr); // isr will turn off boost
P4timer.attachInterrupt(2,P4chan2isr); // isr will turn off blanking
P4timer.attachInterrupt(3,P4chan3isr); // isr will detect STARTUP condition
P4timer.setMode(1,TIMER_OUTPUT_COMPARE);// channel 1, generate interrupt on compare
P4timer.setMode(2,TIMER_OUTPUT_COMPARE);// channel 4, generate interrupt on compare
P4timer.setMode(3,TIMER_OUTPUT_COMPARE);// channel 3, generate interrupt on compare
P4timer.setCompare(TIMER_CH1,bst); // boost
P4timer.setCompare(TIMER_CH2,blnk); // blank
P4timer.setCompare(TIMER_CH3,ded); // STARTUP
P4timer.refresh(); // update
P4timer.resume(); // start timer
digitalWrite(P1gatePin, HIGH); // turn on magnet
digitalWrite(P1blankPin,HIGH); // turn on signal blanking
P1blankFinished = false; // reset blank finished flag
if(report==1) report1(); // report to IDE monitor
P1sigMax = 0;
}
// -------------------------- P2 coil control ----------------------------
void P2kick(uint16_t bst, uint16_t blnk, uint16_t ded) {
if(report==2) digitalWrite(ledPin,HIGH); // turn on led if report to this P is active
P2flip = !P2flip; // calculate period of P2
P2timer.pause(); // stop timer
if(P2flip) P2countA = P2timer.getCount();
else P2countB = P2timer.getCount();// get half count
P2periodAct = P2countA + P2countB; // add two halves
P2timer.setCount(0); // reset
P2timer.attachInterrupt(1,P2chan1isr);// isr will turn off boost
P2timer.attachInterrupt(2,P2chan2isr);// isr will turn off blanking
P2timer.attachInterrupt(3,P2chan3isr);// isr will detect STARTUP condition
P2timer.setMode(1,TIMER_OUTPUT_COMPARE); // channel 1, generate interrupt on compare
P2timer.setMode(2,TIMER_OUTPUT_COMPARE); // channel 2, generate interrupt on compare
P2timer.setMode(3,TIMER_OUTPUT_COMPARE); // channel 3, generate interrupt on compare
P2timer.setCompare(TIMER_CH1,bst); // boost
P2timer.setCompare(TIMER_CH2,blnk); // blank
P2timer.setCompare(TIMER_CH3,ded); // STARTUP
P2timer.refresh(); // update
P2timer.resume(); // start timer
digitalWrite(P2gatePin, HIGH); // turn on magnet
digitalWrite(P2blankPin,HIGH); // turn on signal blanking
P2blankFinished = false; // reset blank finished flag
if(report==2) report2(); // report to IDE monitor
P2sigMax = 0;
}
// -------------------------- P3 coil control ----------------------------
void P3kick(uint16_t bst, uint16_t blnk, uint16_t ded) {
if(report==3) digitalWrite(ledPin,HIGH); // turn on led if report to this P is active
P3flip = !P3flip; // calculate period of P3
P3timer.pause(); // stop timer
if(P3flip) P3countA = P3timer.getCount();
else P3countB = P3timer.getCount();// get half count
P3periodAct = P3countA + P3countB; // add two halves
P3timer.setCount(0); // reset
P3timer.attachInterrupt(1,P3chan1isr); // isr will turn off boost
P3timer.attachInterrupt(2,P3chan2isr); // isr will turn off blanking
P3timer.attachInterrupt(3,P3chan3isr); // isr will detect STARTUP condition
P3timer.setMode(1,TIMER_OUTPUT_COMPARE);// channel 1, generate interrupt on compare
P3timer.setMode(2,TIMER_OUTPUT_COMPARE);// channel 2, generate interrupt on compare
P3timer.setMode(3,TIMER_OUTPUT_COMPARE);// channel 3, generate interrupt on compare
P3timer.setCompare(TIMER_CH1,bst); // boost
P3timer.setCompare(TIMER_CH2,blnk); // blank
P3timer.setCompare(TIMER_CH3,ded); // STARTUP
P3timer.refresh(); // update
P3timer.resume(); // start timer
digitalWrite(P3gatePin, HIGH); // turn on magnet
digitalWrite(P3blankPin,HIGH); // turn on signal blanking
P3blankFinished = false; // reset blank finished flag
if(report==3) report3(); // report to IDE monitor
P3sigMax = 0;
}
// ------------------------------- operator interface -------------------------------------
void opCom() {
int inNum;
char inChar;
inChar = Serial.read(); // get char from incoming serial stream
if((inChar==13)||(inChar==10)) return; // ignore trailing <CR> <LF> last command
inChar = toupper(inChar);
switch(inChar) {
case 'R': // (R)eport, select which pendulum
report = Serial.parseInt(); // activate selected report
lineCounter = 0;
break;
case 'P': // Set period of selected pendulum
inNum = Serial.parseInt(); // get number
Serial.println();
Serial.print("P"); // (P)eriod
Serial.print(report); //
Serial.print(" Period "); //
Serial.println(inNum); // <LF><CR>
if(report==1) P1periodCmd = inNum;
if(report==2) P2periodCmd = inNum;
if(report==3) P3periodCmd = inNum;
break;
default:
Serial.print(" ?");
inNum = inChar;
Serial.println(char(inNum));
break;
}
}
void plot() {
Serial.println(P2sigAveSave); // change baud to 115200
delay(10);
}
// ---------------------------- reports ---------------------------------------------
void report1() {
if(!(lineCounter%20)){
Serial.println();
Serial.println("P1State Psigmax Pact Pcmd Err Boost Loops");
}
lineCounter++;
if(P1state==STARTUP) Serial.print("STARTUP");
if(P1state==BOOST) Serial.print("BOOST");
if(P1state==STABLE) Serial.print("STABLE");
Serial.print(TAB);
Serial.print(P1sigMax);
Serial.print(TAB);
Serial.print(P1periodAct);
Serial.print(TAB);
Serial.print(P1periodCmd);
Serial.print(TAB);
Serial.print(P1periodErr);
Serial.print(TAB);
Serial.print(P1boost);
Serial.print(TAB);
Serial.print(loops);
Serial.println();
loops = 0;
}
void report2() {
if(!(lineCounter%20)){
Serial.println();
Serial.println("P2State Psigmax Pact Pcmd Err Boost Loops");
}
lineCounter++;
if(P2state==STARTUP) Serial.print("STARTUP");
if(P2state==BOOST) Serial.print("BOOST");
if(P2state==STABLE) Serial.print("STABLE");
Serial.print(TAB);
Serial.print(P2sigMax);
Serial.print(TAB);
Serial.print(P2periodAct);
Serial.print(TAB);
Serial.print(P2periodCmd);
Serial.print(TAB);
Serial.print(P2periodErr);
Serial.print(TAB);
Serial.print(P2boost);
Serial.print(TAB);
Serial.print(loops);
Serial.println();
loops = 0;
}
void report3() {
if(!(lineCounter%20)){
Serial.println();
Serial.println("P3State Psigmax Pact Pcmd Err Boost Loops");
}
lineCounter++;
if(P3state==STARTUP) Serial.print("STARTUP");
if(P3state==BOOST) Serial.print("BOOST");
if(P3state==STABLE) Serial.print("STABLE");
Serial.print(TAB);
Serial.print(P3sigMax);
Serial.print(TAB);
Serial.print(P3periodAct);
Serial.print(TAB);
Serial.print(P3periodCmd);
Serial.print(TAB);
Serial.print(P3periodErr);
Serial.print(TAB);
Serial.print(P3boost);
Serial.print(TAB);
Serial.print(loops);
Serial.println();
loops = 0;
}
Comments
Please log in or sign up to comment.