I am currently doing a project that involves running 2 interrupts. One interrupt is for the zero-cross detection that always runs while the other is for serial interrupt. I made a separate code for each one of those. I want to merge these two programs such that the zero-cross detection should be running in parallel with the other events. May I ask how I can be able to make it using mbed?
Here is the code for the zero-cross detection (intended for the ac phase control circuitry):
#include "mbed.h"
//PwmOut led(LED1); // led 1 indicates T1 value
// pin for ZeroCross tail input
// An external 1K pullup required
InterruptIn zerocross(PC_0); //ZC DETECT A5
// pin for Triac Gate output
DigitalOut TriacGate(PA_0); //TriacGate A0
//use timer interrupts to control the power
Timeout TriactriggerOn;
// power control value 0.0=off and 1.0=full on
const float T1 = 0.450;
// AC power line frequency
const float powerlinefrequency=60.000;
// this interrupt routine is activated after a time delay set by T1 value
void triggerOn()
{
TriacGate = 1;
// wait_ms(1);
// TriacGate = 0;
}
// this interrupt routine is activated by every AC line zero crossing
// it is needed to synchronize the Triac turnon time delay to the AC line
void zeroCrossingInterrupt()
{
// turn off Triac at zero crossing
TriacGate = 0;
// compute time delay using T1 value and set timer interrupt
// triggers Triac after a small post zero crossing time delay
TriactriggerOn.attach(&triggerOn, (1.001f-T1)/(2*powerlinefrequency)); // setup TriactriggerOn to call triggerOn after
//(1.001f-T1)/(2*powerlinefrequency) seconds
}
int main()
{
//set up interrupt routine to detect AC line zero crossings
zerocross.mode(PullUp);
wait(.2);
zerocross.rise(&zeroCrossingInterrupt);
while(1) {
}
}
and here is for the serial part:
#include "mbed.h"
#include <iostream>
#include <string>
#include "atoh.h"
PwmOut LSU1(PA_1);
DigitalOut LSU1_Start(PB_0);
DigitalOut myled(LED1);
RawSerial pc(USBTX, USBRX);
volatile char bufferA[100];
uint16_t buffer1;
uint16_t checkStart;
int buf_index = 0;
void Rx_interrupt(void)
{
while(pc.readable())
{
bufferA[buf_index] = pc.getc();
buf_index++;
}
}
int main() {
pc.baud(9600);
//char c;
//char buffer[128];
pc.printf("program started \r\n");
//LSU1.period_ms(1/0.55);// set PWM period to 10 ms; frequency to 100 Hz
LSU1.period((float)1/1000); //set your period as the inverse of frequency
//LSU1.period(1/1000.0); //set your period as the inverse of frequency
//LSU1.period(1/frequency); //set your period as the inverse of frequency
//LSU1.write(0.50f); // 50% duty cycle, relative to period
LSU1=0.5; // set duty cycle to 50%
LSU1_Start=1; // set LSU1_Start pin to high
//LSU1_Start.write(0); // set LSU1_Start pin to low
pc.attach(&Rx_interrupt);
while(1) {
if (buf_index > 2)
{
//pc.printf("%s \n",bufferA);
buffer1 = atoh<uint16_t> ((char*)bufferA);
//pc.printf("%d \n",buffer1);
checkStart = buffer1 >> 8;
pc.printf("%d \n",checkStart);
if(checkStart == 1)
{
myled = 1;
}
if(checkStart == 2)
{
myled = 0;
}
//pc.printf("%d\n",bufferA[buf_index]);
//pc.printf("Size of bufferA is %d \n", sizeof(bufferA));
//pc.printf("I got '%s'\n", bufferA);
for (int i=0; i<sizeof(bufferA); i++){
bufferA[i] = 0;
}
buf_index = 0;
}
//pc.printf("Nucleo is still awake! \r\n");
//pc.printf("%i", sizeof(char));
}
}
Thank you. I believe that it is something to do with RTOS. I hope you can give me a quick start and ideas on how I should be able to combine these programs.
By the way, I am running this on nucleo-f303re board.
I think I made it somewhat working. Here is my code:
#include "mbed.h"
#include "atoh.h"
Thread ISRthread(osPriorityAboveNormal);
osThreadId ISRthreadId;
RawSerial pc(USBTX, USBRX);
DigitalOut myled(LED1);
PwmOut LSU(PA_6); // frequency generator pin D12
DigitalOut LSU1_Start(PA_7); // LSU1 start pin D11
void newInput();
void ISR_thread();
volatile char bufferA[3];
volatile uint16_t buffer1;
volatile uint16_t checkStart;
volatile uint16_t rpmData;
volatile int buf_index = 0;
//zero cross
// pin for ZeroCross tail input
// An external 1K pullup required
InterruptIn zerocross(PC_0); //ZC DETECT A5
// pin for Triac Gate output
DigitalOut TriacGate(PA_0); //TriacGate A0
//use timer interrupts to control the power
Timeout TriactriggerOn;
// power control value 0.0=off and 1.0=full on
const float T1 = 0.450;
// AC power line frequency
const float powerlinefrequency=60.000;
// this interrupt routine is activated after a time delay set by T1 value
void triggerOn()
{
TriacGate = 1;
// wait_ms(1);
// TriacGate = 0;
}
// this interrupt routine is activated by every AC line zero crossing
// it is needed to synchronize the Triac turnon time delay to the AC line
void zeroCrossingInterrupt()
{
// turn off Triac at zero crossing
TriacGate = 0;
// compute time delay using T1 value and set timer interrupt
// triggers Triac after a small post zero crossing time delay
TriactriggerOn.attach(&triggerOn, (1.001f-T1)/(2*powerlinefrequency)); // setup TriactriggerOn to call triggerOn after
//(1.001f-T1)/(2*powerlinefrequency) seconds
}
int main() {
ISRthread.start(callback(ISR_thread));
pc.attach(&newInput); //interrupt to catch input
//set up interrupt routine to detect AC line zero crossings
zerocross.mode(PullUp);
wait(.2);
zerocross.rise(&zeroCrossingInterrupt);
while(1) {
}
}
void newInput() {
pc.attach(NULL); //deatch the ISR to prevent recursive calls
osSignalSet(ISRthreadId,0x01);
}
void ISR_thread() {
ISRthreadId = osThreadGetId();
LSU.period((float)1/1000); //set your period as the inverse of frequency
LSU=0.5; // set duty cycle to 50%
for(;;) {
osSignalWait(0x01, osWaitForever);
while (pc.readable()) {
//pc.putc(pc.getc()); //echo input back to terminal
bufferA[buf_index] = pc.getc();
buf_index++;
//pc.printf("%s \n",bufferA);
if (buf_index > 2)
{
//pc.printf("%s \n",bufferA);
buffer1 = atoh<uint16_t> ((char*)bufferA);
checkStart = buffer1 >> 8;
rpmData = buffer1 & 0xFF;
//pc.printf("%d \n",checkStart);
pc.printf("%d \n",rpmData);
if(checkStart == 1)
{
myled = 1;
LSU1_Start=1; // set LSU1_Start pin to high
}
if(checkStart == 2)
{
myled = 0;
LSU1_Start=0; // set LSU1_Start pin to high
}
for (int i=0; i<sizeof(bufferA); i++){
bufferA[i] = 0;
}
buf_index = 0;
//pc.attach(&newInput); //re-attach the ISR
}
pc.attach(&newInput); //re-attach the ISR
}
//myled = 1;
//osDelay(50);
//myled = 0;
}
}
With this code comes another problem but it is not somehow related to this thread (question). I can create another one if you may but if it is okay, I can just tell you about it here.
My challenge/problem is on the serial data received. I want to receive something that starts with a character, say $. Whenever the serial program encounters that, the program will start to store the next data received until such time that it will encounter again an end character, say #. I believe that in this way I can make sure that I am really getting the right data. How can I revise my program to cater this?