-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Labels
Description
Hardware: STM32 Blue Pill (STM32F103C8)
Boot using STLINK V2
Board Manger: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_
The error: The "Timer1" was not declared in this scope
My code:
#include "Arduino.h"
#include "LMP91000.h"
#include <Wire.h>
#include <HardwareTimer.h>
#include <Adafruit_MCP4725.h>
#define VOUT PA0 // 36
#define WE PA1
#define RE PA2
#define LMPADDR 0x48
#define DACADDR 0x60
#define SECOND 1000 // how many ms in 1 second
#define MINUTE 60000 // how many ms in 1 minute
#define RTIA_DEFAULT 4 // 5
Adafruit_MCP4725 DAC;
LMP91000 pstat = LMP91000();
short fixedRTIA = 0;
short rtia = 5;
short rload = 0;
bool DPV_start = false;
bool SWV_start = false;
uint8_t RTIA = RTIA_DEFAULT;
uint32_t limit = 0;
float sampling_delay = 0.0;
unsigned long lastTime = 0;
float target_bias_prev = 0.0;
bool CV_start = false;
bool CA_start = false;
bool spike = false;
short CA_unit = 0;
//--user define start CV
short Vmax = 0; // unit: mV
short Vmin = 0;
short scan_rate = 0; // unit: mV/s
short v_start = 0;
short v_end = 0;
int technique = 0;
int step_increase = 0; // resolution (mV)
int stop_crossing = 0; // no. of times voltage crosses 0mV
bool Vdirection = true;
//--user define end
//--user define start CA
short sampling_rate = 0; // Hz
short v_step = 0;
short t_start = 0;
unsigned long t_step = 0;
short t_end = 0;
//--user define end
short v_end_2 = 0;
short Estep = 0;
short Epulse = 0;
short Pwidth = 0;
short Period = 0;
short Tquiet = 0;
short Trelax = 0;
//CV
short target_bias = 0;
int dac = 0;
double vout = 0;
double tmp = 0.000;
double Vcheck = 0.00;
int stop_crossing_index = 0;
float percentage = 0.0;
uint32_t interruptCounter = 0;
uint32_t interruptCounter_prev = 0;
//--Reset after completion
bool getTechnique = false;
bool getParams = false;
//CA
int timer_divider = 0;
bool complete = false;
void VariableReset() {
Vmax = 0; // unit: mV
Vmin = 0;
scan_rate = 0; // unit: mV/s
v_start = 0;
v_end = 0;
technique = 0;
step_increase = 0; // resolution (mV)
stop_crossing = 0;
Vdirection = true;
sampling_rate = 0;
v_step = 0;
t_start = 0; //ms
t_step = 0; //ms
t_end = 0; //ms
v_end_2 = 0;
Estep = 0;
Epulse = 0;
Pwidth = 0;
Period = 0;
Tquiet = 0;
Trelax = 0;
target_bias = 0.0;
dac = 0;
vout = 0;
tmp = 0.000;
Vcheck = 0.00;
stop_crossing_index = 0;
percentage = 0.0;
interruptCounter = 0;
interruptCounter_prev = 0;
timer_divider = 0;
complete = false;
sampling_delay = 0.0;
target_bias_prev = 0.0;
CV_start = false;
CA_start = false;
DPV_start = false;
SWV_start = false;
spike = false;
RTIA = RTIA_DEFAULT;
limit = 0;
Wire.beginTransmission(0x48);
pstat.standby();
pstat.disableFET();
pstat.setRLoad(rload); //0
pstat.setRefSource(1);
pstat.setBias(9); //5 -- 8 // 3
pstat.setGain(rtia); // TIA GAIN
pstat.setIntZ(1); //
pstat.setPosBias();
pstat.setThreeLead();
Wire.endTransmission();
delay(2000); //warm-up time for gas sensor
}
void onTimer() {
interruptCounter++;
}
// applyBias sets Pos/Neg bias, DAC value, and the percentage
void applyBias2(float target_bias) {
float percentage = 0.0;
int LMP_percentage = 0;
if (abs(target_bias) <= 793.0 && abs(target_bias) >= 726.0) {
LMP_percentage = 13;
percentage = 0.24;
} else if (abs(target_bias) <= 726.0 && abs(target_bias) >= 660.0) {
LMP_percentage = 12;
percentage = 0.22;
} else if (abs(target_bias) <= 660.0 && abs(target_bias) >= 594.0) {
LMP_percentage = 11;
percentage = 0.2;
} else if (abs(target_bias) <= 594.0 && abs(target_bias) >= 528.0) {
LMP_percentage = 10;
percentage = 0.18;
} else if (abs(target_bias) <= 528.0 && abs(target_bias) >= 462.0) {
LMP_percentage = 9;
percentage = 0.16;
} else if (abs(target_bias) <= 462.0 && abs(target_bias) >= 396.0) {
LMP_percentage = 8;
percentage = 0.14;
} else if (abs(target_bias) <= 396.0 && abs(target_bias) >= 330.0) {
LMP_percentage = 7;
percentage = 0.12;
} else if (abs(target_bias) <= 330.0 && abs(target_bias) >= 264.0) {
LMP_percentage = 6;
percentage = 0.10;
} else if (abs(target_bias) <= 264.0 && abs(target_bias) >= 198.0) {
LMP_percentage = 5;
percentage = 0.08;
} else if (abs(target_bias) <= 198.0 && abs(target_bias) >= 132.0) {
LMP_percentage = 4;
percentage = 0.06;
} else if (abs(target_bias) <= 132.0 && abs(target_bias) >= 66.0) {
LMP_percentage = 3;
percentage = 0.04;
} else if (abs(target_bias) <= 66.0 && abs(target_bias) >= 33.0) {
LMP_percentage = 2;
percentage = 0.02;
} else if (abs(target_bias) <= 33.0 && abs(target_bias) >= 15.0) {
LMP_percentage = 1;
percentage = 0.01;
} else {
LMP_percentage = 0;
percentage = 0.0;
}
if (target_bias >= 0) {
Wire.beginTransmission(0x48);
pstat.setPosBias();
Wire.endTransmission();
} else {
Wire.beginTransmission(0x48);
pstat.setNegBias();
Wire.endTransmission();
}
if (abs(target_bias) < 15) {
if (abs(target_bias) >= 7.5) {
target_bias = 15;
} else { // less than 7.5mV ---> become 0
dac = 1860; // 1.5V
Wire.beginTransmission(0x48); // LMP91000 address = 0x48
pstat.setBias(0);
Wire.endTransmission();
}
} else {
dac = int((target_bias * 4096) / (1000 * percentage * 3.3));
}
Wire.beginTransmission(0x60);
DAC.setVoltage(int(abs(dac)), false);
Wire.endTransmission();
// apply bias percentage at LMP
Wire.beginTransmission(0x48);
pstat.setBias(LMP_percentage);
Wire.endTransmission();
}
uint16_t avgAnalogRead() {
uint32_t sum = 0;
uint32_t avgVOUT = 0;
int samples = 5;
for (int x = 0; x < samples; x++) {
sum += analogRead(VOUT);
}
avgVOUT = (sum / samples) * 3.3 * 1000 / 4095; //mV
return avgVOUT;
}
double ReadCurrent(float target_bias, int dac) {
spike = false;
float tmp = 0.0;
int avgV = avgAnalogRead();
Wire.beginTransmission(0x48);
float IntZ = pstat.getIntZ();
float Gain = pstat.getGain();
Wire.endTransmission();
float v_intz = 1000 * IntZ * 3.3 * dac / 4095;
if (fixedRTIA == 0){
if (abs(target_bias) > 15) { //try omit this?
if ((avgV < 50) || (avgV > 3250)) {
if (interruptCounter - limit > 5) {
if (RTIA > 1) {
RTIA -= 1;
spike = true;
limit = interruptCounter;
}
}
} else if (abs(avgV - v_intz) < 50) { //< 200 ){
if (interruptCounter - limit > 5) {
if (RTIA > 0 && RTIA < 7) {
RTIA += 1;
spike = true;
limit = interruptCounter;
} else if (RTIA == 0) {
RTIA = 0;
}
}
}
}
}
else {
RTIA = rtia;
}
if (RTIA == 0) {
Wire.beginTransmission(0x48);
pstat.setGain(RTIA); // rtia
Wire.endTransmission();
tmp = 1000 * (avgV - 1000 * (abs(dac) * 3.3 / 4095) * IntZ) / 2000000; //Gain;
} else {
Wire.beginTransmission(0x48);
pstat.setGain(RTIA);
IntZ = pstat.getIntZ();
Wire.endTransmission();
tmp = 1000 * (avgV - 1000 * (abs(dac) * 3.3 / 4095) * IntZ) / Gain; //Gain;
}
return tmp; // in micro amps
}
void CV(short Vmax, short Vmin, short scan_rate, short v_start, short v_end, short step_increase, short stop_crossing, short target_bias, short timer_divider) {
lastTime = millis();
Timer1.setPeriod(1000 * timer_divider); // in microseconds
Timer1.resume();
Timer1.attachInterrupt(TIMER_CH1, onTimer);
delay(50);
while (stop_crossing_index != stop_crossing) {
if (Vdirection == true && stop_crossing_index != stop_crossing) {
while (target_bias < Vmax) {
digitalWrite(PC13, HIGH);
delay(1);
if (interruptCounter > interruptCounter_prev) {
interruptCounter_prev = interruptCounter;
target_bias_prev = target_bias;
target_bias += step_increase;
Vcheck = 1000 * analogRead(WE) / 4096 * 3.3 - 1000 * analogRead(RE) / 4096 * 3.3;
tmp = ReadCurrent(target_bias_prev, dac);
applyBias2(target_bias);
if (CV_start == true && spike == false) {
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias_prev);
Serial.print(",");
Serial.print(tmp);
Serial.print(",");
Serial.print(Vcheck);
Serial.print(",");
Serial.println(avgAnalogRead());
}
if (target_bias == v_end) {
stop_crossing_index++;
if (stop_crossing_index == stop_crossing) {
break;
}
}
CV_start = true;
}
}
}
Vdirection = false;
if (Vdirection == false && stop_crossing_index != stop_crossing) {
while (target_bias > Vmin) {
delay(1);
if (interruptCounter > interruptCounter_prev) {
interruptCounter_prev = interruptCounter;
target_bias_prev = target_bias;
target_bias -= step_increase;
Vcheck = 1000 * analogRead(WE) / 4096 * 3.3 - 1000 * analogRead(RE) / 4096 * 3.3;
tmp = ReadCurrent(target_bias_prev, dac);
applyBias2(target_bias);
if (CV_start == true && spike == false) {
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias_prev);
Serial.print(",");
Serial.print(tmp);
Serial.print(",");
Serial.print(Vcheck);
Serial.print(",");
Serial.println(avgAnalogRead());
}
if (target_bias == v_end) {
stop_crossing_index++;
if (stop_crossing_index == stop_crossing) {
break;
}
}
CV_start = true;
}
}
}
Vdirection = true;
if (stop_crossing_index == stop_crossing) {
Timer1.pause();
break;
}
}
Serial.println("complete");
Timer1.pause();
}
void CA(short sampling_rate, short v_start, short v_step, short v_end, short t_start, unsigned long t_step, short t_end, short target_bias, short timer_divider) {
lastTime = millis();
Timer1.setPeriod(timer_divider * 1000); // ISR period in microseconds
Timer1.attachInterrupt(TIMER_CH1, onTimer);
Timer1.resume();
while (complete == false) {
delay(1);
if (interruptCounter > interruptCounter_prev) {
interruptCounter_prev = interruptCounter;
target_bias_prev = target_bias;
tmp = ReadCurrent(target_bias, dac);
if (interruptCounter == 1) { // to prevent applying bias multiple times (apply bias once only)
target_bias = v_start;
applyBias2(target_bias);
} else if (interruptCounter == t_start * sampling_rate / 1000 + 1) {
target_bias = v_step;
applyBias2(target_bias);
} else if (interruptCounter == (t_start + t_step) * sampling_rate / 1000 + 1) {
target_bias = v_end;
applyBias2(target_bias);
} else if (interruptCounter == (t_start + t_step + t_end) * sampling_rate / 1000 + 1) {
complete = true;
}
Vcheck = 1000 * analogRead(WE) / 4096 * 3.3 - 1000 * analogRead(RE) / 4096 * 3.3;
if (CA_start == true && spike == false) {
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias_prev);
Serial.print(",");
Serial.print(tmp);
Serial.print(",");
Serial.println(Vcheck);
}
CA_start = true;
}
}
complete = false;
Serial.println("complete");
Timer1.pause();
}
void DPV(short sampling_rate, short v_start, short v_end, short v_end_2, short Estep, short Epulse, short Pwidth, short Period, short Tquiet, short Trelax, short target_bias, short timer_divider) {
bool dpv_done = false;
lastTime = millis();
Timer1.setPeriod(timer_divider * 1000); // ISR period in microseconds
Timer1.attachInterrupt(TIMER_CH1, onTimer);
Timer1.resume();
int ctr = 0;
float i1 = 0.0;
float i2 = 0.0;
short target_bias_plot = 0;
while (dpv_done == false) {
delay(1);
if (interruptCounter > interruptCounter_prev) {
interruptCounter_prev = interruptCounter;
ctr++;
if (DPV_start == false) { // 1st cycle
target_bias -= Epulse;
applyBias2(target_bias); //, findPercentage(target_bias));
DPV_start = true;
} else if (ctr == Pwidth * sampling_rate / 1000 + 1) { // completed "ON" time
if (v_end < v_start) {
if (target_bias + (Epulse - Estep) <= v_end) { // last pulse
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias = v_end;
applyBias2(target_bias);
dpv_done = true;
} else { // not last pulse
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias = target_bias + (Epulse - Estep);
applyBias2(target_bias);
}
} else {
if (target_bias + Epulse - Estep <= v_end) { // last pulse
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias = v_end;
dpv_done = true;
applyBias2(target_bias); //, findPercentage(target_bias));
} else { // not last pulse
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias = target_bias - (Epulse - Estep);
applyBias2(target_bias); //, findPercentage(target_bias));
}
}
} else if (ctr == Period * sampling_rate / 1000 + 1) { // completed full period
i2 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias -= Epulse;
applyBias2(target_bias); //, findPercentage(target_bias));
if (DPV_start == true) { //&& spike == false && abs(target_bias) > 15){
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias_plot);
Serial.print(",");
Serial.print(i2 - i1);
Serial.print(",");
Serial.println(target_bias_plot);
}
ctr = 0;
}
}
}
Serial.println("complete");
Timer1.pause();
}
void SWV(short sampling_rate, short v_start, short v_end, short Estep, short Epulse, short Period, short Tquiet, short Trelax, short target_bias, short timer_divider) {
bool swv_done = false;
lastTime = millis();
applyBias2(target_bias);
delay(Tquiet);
Timer1.setPeriod(timer_divider * 1000); // ISR period in microseconds
Timer1.attachInterrupt(TIMER_CH1, onTimer);
Timer1.resume();
int ctr = 0;
float i1 = 0.0;
float i2 = 0.0;
short target_bias_plot = 0;
while (swv_done == false) {
delay(1);
if (interruptCounter > interruptCounter_prev) {
interruptCounter_prev = interruptCounter;
ctr++;
// Serial.println("what");
if (SWV_start == false) {
target_bias += Epulse;
applyBias2(target_bias);
SWV_start = true;
} else {
if (v_start < v_end) {
if (target_bias + Epulse <= v_end) {
if (ctr == (Period * sampling_rate) / (2 * 1000) + 1) { // half a period
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias -= 2 * Epulse;
applyBias2(target_bias);
}
if (ctr == (Period * sampling_rate) / (1000) + 1) { //end of period
i2 = ReadCurrent(target_bias, dac);
target_bias += 2 * Epulse + Estep;
applyBias2(target_bias);
ctr = 0;
if (SWV_start == false) {
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias);
Serial.print(",");
Serial.print(i2 - i1);
Serial.print(",");
Serial.println(target_bias_plot);
}
}
} else {
Serial.println("complete");
Timer1.pause();
swv_done = true;
break;
}
if (target_bias >= v_end) {
Serial.print("complete");
swv_done = true;
}
} else {
if (target_bias + Epulse >= v_end) {
if (ctr == (Period * sampling_rate) / (2 * 1000) + 1) { // half a period
i1 = ReadCurrent(target_bias, dac);
target_bias_plot = target_bias;
target_bias -= (2 * Epulse + Estep);
applyBias2(target_bias);
}
if (ctr == (Period * sampling_rate) / (1000) + 1) { //end of period
i2 = ReadCurrent(target_bias, dac);
target_bias += (2 * Epulse);
applyBias2(target_bias);
ctr = 0;
if (SWV_start == true && spike == false) {
Serial.print(millis() - lastTime);
Serial.print(",");
Serial.print(target_bias);
Serial.print(",");
Serial.print(i1 - i2);
Serial.print(",");
Serial.println(target_bias_plot);
}
}
} else {
Serial.println("complete");
Timer1.pause();
swv_done = true;
break;
}
if (target_bias <= v_end) {
Serial.print("complete");
swv_done = true;
}
}
}
}
}
}
void setup()
{
pinMode(PC13, OUTPUT);
pinMode(PA0, INPUT);
pinMode(PA1, INPUT);
pinMode(PA2, INPUT);
pinMode(PA5, OUTPUT);
digitalWrite(PA5,LOW);
analogReadResolution(12);
Serial.begin(9600);
while (!Serial) {
delay(1);//won't run code until serial monitor is open
}
Wire.setSDA(PB9);
Wire.setSCL(PB8);
Wire.begin();
DAC.begin(0x60); //I have my ADDR pin connected to GND so address is 0x60
delay(50);
Wire.beginTransmission(0x48);
pstat.standby();
pstat.disableFET();
pstat.setRLoad(0); //11=100ohm; 0=10ohm
pstat.setRefSource(1);
pstat.setBias(9);
pstat.setGain(RTIA_DEFAULT); //chnage your gain as necessary. Bigger number higher gain. Lower number, lower gain.
pstat.setIntZ(1);
pstat.setPosBias();
pstat.setThreeLead();
Wire.endTransmission();
delay(3000); //warm-up time for the gas sensor
}
void loop()
{
digitalWrite(PC13, LOW);
}