run this here

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351

main.cpp

Committer:
trhackett
Date:
2018-04-27
Revision:
0:2b94f7017e4e
Child:
1:b965810f9bb3

File content as of revision 0:2b94f7017e4e:

#include "mbed.h"
#include "Ticker.h"
#include <stdlib.h>

InterruptIn catchChange(PTD2);
Serial pc(USBTX, USBRX);

// software PWM using DigitalOut
DigitalOut pulse(PTA10);

float PERIOD = 0.06f;
float DUTYCYCLE = 0.50f;

// period and duty cycle that we'll be changing
float currentPeriod = PERIOD;
float currentDutyCycle = DUTYCYCLE;

// period is the time between the previous rising edge
// and the current one, so recompute each time you
// encounter a rising edge
float period;
Timer t;

// D is fraction of time that was high during the preceding interval
float D;
Timer highTime;
Timer lowTime;

// every 10 rising edges, print T and D
int risingEdges = 0;

// add in a thread that will do printing so it 
// doesn't interfere with my measurements
EventQueue q1;
Thread t1;

// ticker to change from low to high and one to change from high to low
Ticker lowToHigh; // low to high every period seconds
Ticker highToLow; // high to low every period + period * duty_cycle seconds

// switch the digital signal whenever the ticker goes off
void tickerHandle() {
    if (pulse.read() == 1) {
        pulse.write(0);   
    } else {
        pulse.write(1);
    }
}

void printData() {
    // this does not run in the ISR
    pc.printf("mbed> %i, %.3f\n\r",(int)(period*1000000.0f),D);
}

void riseHandle() {
    // recompute the period
    period = t.read();
    t.reset();
    t.start();
    
    // if it's the first rising edge of a 10 edge interval,
    // then reset both timers
    if (risingEdges == 0) {
        lowTime.reset();
        highTime.reset();
        lowTime.stop();
        highTime.start();
        
        // and you're in high time on the first rising edge
        risingEdges++;
    }
    
    // if it's the tenth, then store D so that someone else can
    // print it out. reset the timers and rising edge count
    else if (risingEdges >= 9) {
        float h = highTime.read();
        float l = lowTime.read();
        D = h / (h + l);
        
        lowTime.reset();
        highTime.reset();
        lowTime.stop();
        highTime.start();
        
        risingEdges++;
    }
    
    // if it's rising edge 2 ... 9, then just increment and start
    // the high timer and stop the low timer
    else {
        risingEdges++;
        lowTime.stop();
        highTime.start(); 
    }
    
    // then defer the possible printf call to the other thread
    if (risingEdges == 10) {
        q1.call(&printData);
        risingEdges = 0;
    }
}

// when you come to a falling edge, you should stop the high timer and
// start the low timer
void fallHandle() {
    lowTime.start();
    highTime.stop();   
}

void inputHandle() {
    char buff[256];
    gets(buff);
    
    // extract out the values from the character array
    int i = 0;
    char p[20];
    while (buff[i] != ',') {
        p[i] = buff[i];
        ++i;
    }
    p[i] = '\0';
    
    i += 2;
    int j = 0;
    char dc[20];
    while (buff[i] != '\0') {
        dc[j] = buff[i];
        ++i;
        ++j;
    }
    
    int T_temp = atoi(p);
    float D_temp = atof(dc);
   
    // make the changes to the period and duty cycle as long
    // as they are within range
    if ((T_temp >= 1000.0f && T_temp <= 60000.0f) &&
        (D_temp >= 0.0f && D_temp <= 1.0f))
    {
        currentPeriod = ((float)T_temp) / 1000000.0f;
        currentDutyCycle = D_temp;
        // set to low
        pulse.write(0);
        // reset the low to high ticker
        lowToHigh.detach();
        lowToHigh.attach(&tickerHandle, currentPeriod);
        highToLow.detach();
        // wait period * duty cycle
        wait(currentPeriod * currentDutyCycle);
        // reset the high to low ticker
        highToLow.attach(&tickerHandle, currentPeriod);
    }
    
    // print an error, non-blocking, if they input bad values
    else {
        q1.call(printf,"mbed> ERROR\r\n");   
    }
}

// main() runs in its own thread in the OS
int main() {
    
    // each time you see a rising edge, recompute the period
    // and stop timing the low signal
    catchChange.rise(&riseHandle);
    catchChange.fall(&fallHandle);
    
    // when the user inputs something
    pc.attach(&inputHandle);
    
    // start low
    pulse.write(0);
    
    // ticker that goes from low to high every period seconds
    lowToHigh.attach(&tickerHandle, currentPeriod);
    // wait period * duty cycle
    wait(currentPeriod * currentDutyCycle);
    // ticker that goes from high to low every period seconds
    highToLow.attach(&tickerHandle, currentPeriod);
    
    t1.start(callback(&q1, &EventQueue::dispatch_forever));
    
    wait(osWaitForever);
}









//#include "mbed.h"
//#include <string>
//#include <sstream>
//#include "Ticker.h"
//
//
//InterruptIn catchChange(PTD2);
//// printing from the device
//Serial pc(USBTX, USBRX);
//
//// software PWM using DigitalOut
//DigitalOut pulse(PTA10);
//
//// some defaults
//float DEFAULT_PERIOD = 0.1f;
//float DEFAULT_DUTYCYCLE = 0.5f;
//float currentPeriod;
//float currentDutyCycle;
//
//// ticker to change from low to high and one to change from high to low
//Ticker lowToHigh;
//Ticker highToLow;
//
//// every 10 rising edges, print T and D
//int risingEdges = 0;
//
//// T is time between current edge and the previous one
//int T_prev = -1;
//int T_curr = -1;
//int T;
//
//// D is fraction of time that was high during the preceding interval
//float D;
//Timer highTime;
//Timer lowTime;
//
//
//// when you come on a rising edge, you should increment the rising edges
//// and count the time as high, meaning stop the low timer and start the 
//// high timer
//void riseHandle() {
//    // every time, manage the time difference between the previous rising
//    // edge and the one that came after it
//    T_prev = T_curr;
//    T_curr = (int)(highTime.read() * 1000000.0f);
//    
//    // if it's the first rising edge of a 10 edge interval,
//    // then reset both timers
//    if (risingEdges == 0) {        
//        lowTime.stop();
//        highTime.start();
//        lowTime.reset();
//        highTime.reset();
//        
//        // and you're in high time on the first rising edge
//        risingEdges++;
//    }
//    
//    // if it's the tenth, then store D so that someone else can
//    // print it out. reset the timers and rising edge count
//    else if (risingEdges == 9) {
//        float h = highTime.read();
//        float l = lowTime.read();
//        D = h / (h + l);
//        
//        T = T_curr - T_prev;
//        
////        pc.printf("previous rising edge: %i, this rising edge: %i\n\r",T_prev,T_curr);
//        
//        lowTime.stop();
//        highTime.start();
//        lowTime.reset();
//        highTime.reset();
//        
//        risingEdges++;
//    }
//    
//    // if it's rising edge 2 ... 9, then just increment and start
//    // the high timer and stop the low timer
//    else {
//        risingEdges++;
//        lowTime.stop();
//        highTime.start(); 
//    }
//}
//
//// when you come to a falling edge, you should stop the high timer and
//// start the low timer
//void fallHandle() {
//    lowTime.start();
//    highTime.stop();   
//}
//
//void inputHandle() {
//   int T_temp;
//   float D_temp;
//   pc.scanf("%i, %f",&T_temp,&D_temp);
//   pc.printf("read in T as %i, D as %f\r\n",T_temp,D_temp);
//   
//    // make the changes to the period and duty cycle as long
//    // as they are within range
//    if ((T_temp >= 1000 && T_temp <= 60000) &&
//        (D_temp >= 0.0f && D_temp <= 1.0f))
//    {
//        currentPeriod = (float)T_temp / 1000000.0f;
//        currentDutyCycle = D_temp;
//        
//        pc.printf("period is now %f, duty cycle is now %f\n\r",(float)T_temp/1000000.0f,D_temp);
//    }
//    
//    else {
//        pc.printf("mbed> ERROR\n\r");
//    }
//}
//
//void tickerHandle() {
//    if (pulse.read() == 1) {
//        pulse.write(0);   
//    } else {
//        pulse.write(1);
//    }
//}
//    
//int main() {
//    catchChange.rise(&riseHandle);
//    catchChange.fall(&fallHandle);
//    pc.attach(&inputHandle);
//    
//    currentPeriod = DEFAULT_PERIOD;
//    currentDutyCycle = DEFAULT_DUTYCYCLE;
//    
//    // start at a low signal
//    pulse.write(0);
//    
//    // go from low to high every period seconds
//    float riseInterval = currentPeriod;
//    // go from high to low every period + period*dutyCycle seconds
//    float fallInterval = riseInterval + currentPeriod * currentDutyCycle;
//    
//    // set ticker to change signal given intervals above
//    lowToHigh.attach(&tickerHandle, riseInterval);
//    highToLow.attach(&tickerHandle, fallInterval);
//    
//    pc.printf("Starting main function!!!\n\r");
//    
//    pc.printf("rise interval: %f, fall interval: %f\n\r",riseInterval,fallInterval);
//    
//    while (1) {
//        if (risingEdges >= 10) {
//            risingEdges = 0;
//            pc.printf("mbed> %u, %.3f\n\r", T, D);
//        }   
//        
//    }
//}