/* STM32 Blue Pill project using the STM32 Arduino Core (stm32duino) */
//Interface touch dro
//Pailpoe, 2020
//Bernique mods, 2024 =====>>> 2024/03/08, status: NOK
#include "HardwareTimer.h"
#define OUT_LED PC13
//Hard timer 1 for X scale : T1C1 (PA8) and T1C2 (PA9)
HardwareTimer timer_X(1);
//Hard timer 3 for Y scale : T3C1 (PA6) and T3C2 (PA7)
HardwareTimer timer_Y(3);
//Hard timer 2 for Z scale : T2C1 (PA0) and T2C2 (PA1)
HardwareTimer timer_Z(2);
//Hard timer 2 for W scale : T4C1 (PB6) and T4C2 (PB7)
HardwareTimer timer_W(4);
//Variable overflow counter
long lOverflowX = 0;
long lOverflowY = 0;
long lOverflowZ = 0;
long lOverflowW = 0;
/**** Bernique mod_start ****/
static volatile uint32_t ms_ticks = 0; // counter for Systick timer
static volatile bool tick_elapsed = false; // flag, true when reaching time limite for counting
static volatile int scrutation = 1000; // duration for counting ticks from spindle, in milli-seconds
int spindle = PB15; // interrupt pin for spindle sensor counting ticks; https://www.stm32duino.com/viewtopic.php?p=2404#p2404
volatile int spindleCount; // spindle ticks count
int TickPerTurn = 24; // ticks quantity per spindle turn, based on CHANGE parameter for interrupt (= FALLING + RISING events)
long Evalue; // has to be a global variable not be be cleared between refreshes!
/**** Bernique mod_end ****/
//****************** IT function
void IT_Handler_Quadrature_X()
{
if (timer_X.getDirection()) lOverflowX--;
else lOverflowX++;
}
void IT_Handler_Quadrature_Y()
{
if (timer_Y.getDirection())lOverflowY--;
else lOverflowY++;
}
void IT_Handler_Quadrature_Z()
{
if (timer_Z.getDirection())lOverflowZ--;
else lOverflowZ++;
}
void IT_Handler_Quadrature_W()
{
if (timer_W.getDirection())lOverflowW--;
else lOverflowW++;
}
void SysTick_Handler()
{
//TestSys++;
/**** Bernique mod_start ****/
ms_ticks++; // one millisecond has gone!
if (ms_ticks > (scrutation-1)) { // time to sumup spindle rotation quantity
tick_elapsed = true;
ms_ticks = 0;
}
/**** Bernique mod_end ****/
}
void setup()
{
/* Systick */
systick_attach_callback(SysTick_Handler);
/* IO config */
pinMode(OUT_LED, OUTPUT);
digitalWrite(OUT_LED, LOW);
pinMode(PA8, INPUT_PULLUP);
pinMode(PA9, INPUT_PULLUP);
pinMode(PA6, INPUT_PULLUP);
pinMode(PA7, INPUT_PULLUP);
pinMode(PA0, INPUT_PULLUP);
pinMode(PA1, INPUT_PULLUP);
pinMode(PB6, INPUT_PULLUP);
pinMode(PB7, INPUT_PULLUP);
/* Quadratrure decoder */
SetTimerAsQuadratureEncoder(&timer_X,IT_Handler_Quadrature_X);
SetTimerAsQuadratureEncoder(&timer_Y,IT_Handler_Quadrature_Y);
SetTimerAsQuadratureEncoder(&timer_Z,IT_Handler_Quadrature_Z);
SetTimerAsQuadratureEncoder(&timer_W,IT_Handler_Quadrature_W);
/* USB serial */
Serial.begin();
/* Serial 2 for bluetooth module */
Serial2.begin(9600); // Start at 9600 bauds
/* Bluetooth configuration */
delay(500);
Serial2.print("AT+BAUD6");//38400
delay(1500);
Serial2.begin(38400); //Switch to 38400 bauds
delay(1500);
// while(1)
// {
// //Write data from HC06 to Serial Monitor
// if (Serial2.available()){
// Serial.write(Serial2.read());
// }
// //Write from Serial Monitor to HC06
// if (Serial.available()){
// Serial2.write(Serial.read());
// }
// }
/**** Bernique mod_start ****/
pinMode(spindle, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(spindle), spindle_ISR, CHANGE);
/**** Bernique mod_end ****/
}
void loop()
{
long Xvalue;
long Yvalue;
long Zvalue;
long Wvalue;
/**** Bernique mod_start ****/
// long Evalue; // has to be a global variable not be be cleared between refreshes!
/**** Bernique mod_end ****/
char bufferChar[100];
//Update encoder
Xvalue = (long)timer_X.getCount() + lOverflowX * 65536;
Yvalue = (long)timer_Y.getCount() + lOverflowY * 65536;
Zvalue = (long)timer_Z.getCount() + lOverflowZ * 65536;
Wvalue = (long)timer_W.getCount() + lOverflowW * 65536;
/**** Bernique mod_start ****/
if (tick_elapsed) {
Evalue = 60*1000*spindleCount/TickPerTurn/scrutation;
tick_elapsed = false;
spindleCount = 0;
}
/**** Bernique mod_end ****/
delay(50);
digitalWrite(OUT_LED, !digitalRead(OUT_LED)); //Toggle pin led
/**** Bernique mod_start ****/
// sprintf(bufferChar,"X%ld;Y%ld;Z%ld;W%ld;",Xvalue,Yvalue,Zvalue,Wvalue);
sprintf(bufferChar,"X%ld;Y%ld;Z%ld;W%ld;E%ld;",Xvalue,Yvalue,Zvalue,Wvalue,Evalue);
/**** Bernique mod_end ****/
Serial2.print(bufferChar);
if(Serial.isConnected())
{
Serial.print(bufferChar);
}
}
void SetTimerAsQuadratureEncoder(HardwareTimer *timerConf,voidFuncPtr handler)
{
timerConf->pause(); //stop...
timerConf->setMode(0, TIMER_ENCODER); //set mode, the channel is not used when in this mode.
timerConf->setPrescaleFactor(1); //normal for encoder to have the lowest or no prescaler.
timerConf->setOverflow(0xFFFF);
timerConf->setCount(0); //reset the counter.
timerConf->setEdgeCounting(TIMER_SMCR_SMS_ENCODER3); //or TIMER_SMCR_SMS_ENCODER1 or TIMER_SMCR_SMS_ENCODER2. This uses both channels to count and ascertain direction.
timerConf->attachInterrupt(0, handler); //Overflow interrupt
timerConf->resume(); //start the encoder...
}
/**** Bernique mod_start ****/
void spindle_ISR()
{
spindleCount ++;
}
/**** Bernique mod_end ****/