AC dimmer

Dependencies:   mbed tsi_sensor

main.cpp

Committer:
iulian_radu
Date:
2014-12-13
Revision:
0:e77768001bf6
Child:
1:513c1ae9298f

File content as of revision 0:e77768001bf6:

#include "mbed.h"
#include "tsi_sensor.h"

union message{
    unsigned short body;
    struct {
        char data:8;
        char cmd:8;
    };
};

//defines
#define ERROR_CMD(x) x = x | 0xC0
#define ERROR_MSG(x) x = x | 0xC000
#define MSG_DEFAULT 0x8000 | MIN_DIMM_VALUE

#define MAX_PERIOD 9600 // us // teoretic 10ms 
#define TRIAC_ON_TIME 25 //us // latimea pulsului pentru activarea triacului.
#define DIMM_RX_BUFFER 6
#define CONNECTION 3 // 1-PC // 2 - BT // 3 - PC + BT

char STEPS = 255;
signed char AUTO_DIMM_STEP = 1;
float AUTO_DIMM_PERIOD = 0.01;
char MIN_DIMM_VALUE = 1;
char MAX_DIMM_VALUE = STEPS;

PwmOut LED(LED_GREEN); // on board LED
DigitalOut triacOut(PTD5); //output to Opto Triac
InterruptIn zerroCross(PTA13); // only port A or D
TSIAnalogSlider tsi(9, 10, 39); // board slider
Serial pc(USBTX, USBRX);
Serial bt(PTA2,PTA1);

Ticker cycling;
Timeout timer;

char buffer[DIMM_RX_BUFFER]; // rx buffer
signed char direction = AUTO_DIMM_STEP; 
char dimmingLevel = MIN_DIMM_VALUE;
char regDimmingLevel = MIN_DIMM_VALUE;
union message msg, aux;

void setTriacOff(void){
    triacOut = 0;
    timer.detach();
}

void setTriacOn(void){
    triacOut = 1;
    timer.detach();
    timer.attach_us(&setTriacOff,TRIAC_ON_TIME);
}

void changeDimmingLevel(int val){
    if(val >= MIN_DIMM_VALUE && val <= MAX_DIMM_VALUE)
        dimmingLevel = val;
}

void dimmingInterval(){
    if(dimmingLevel < msg.data)
        changeDimmingLevel(dimmingLevel + AUTO_DIMM_STEP);  // direction up
    else if (dimmingLevel > msg.data)
        changeDimmingLevel(dimmingLevel - AUTO_DIMM_STEP); // direccion down
    else{
        cycling.detach();
        direction = 0;
    }
}

void printMessage(message msg, char *s, char err){
    switch(CONNECTION){
        case 1:
            if(!err)
                pc.printf("%s#    MSG: %u    CMD: %u    DATA: %u\n", s, msg.body, msg.cmd, msg.data);
            else
                pc.printf("%s#    CMD: %u   DATA %u \n",s, ERROR_CMD(msg.cmd), msg.data);
            break;
        case 2:
            if(!err)
                bt.printf("%u",msg.body);
            else
                bt.printf("%u",ERROR_MSG(msg.body));
            break;
        case 3:
            if(!err){
                pc.printf("%s#    MSG: %u    CMD: %u    DATA: %u\n",s,msg.body, msg.cmd, msg.data);
                bt.printf("%u",msg.body);
            }else{
                pc.printf("%s#    CMD: %u   DATA %u \n",s, ERROR_CMD(msg.cmd), msg.data);
                bt.printf("%u",ERROR_MSG(msg.body));
            }      
            break;
    }
}   



void ISR_zerroCross(void){
    timer.attach_us(&setTriacOn,(MAX_PERIOD/STEPS) * (STEPS - dimmingLevel));
}

void ISR_Serial(void){
    bt.gets(buffer, DIMM_RX_BUFFER);
    LED = !LED;
}

void readData(void)
{
    if(bt.readable()) {

        bt.gets(buffer, DIMM_RX_BUFFER);
        sscanf(buffer,"%u",&msg.body);
        
        switch(msg.cmd){
            case 0x81: //CONN
               if(msg.data == 0xA5){   
                    msg.body = MSG_DEFAULT;
                    printMessage(msg,"CONN",0);
                    }else
                        printMessage(msg,"ERR-CONN",1);   
                break;
            case 0x82: //ON
                if(msg.data == 0xFF){
                    cycling.attach(&dimmingInterval,AUTO_DIMM_PERIOD); 
                    printMessage(msg,"ON",0);                  
                    }else
                        printMessage(msg,"ERR-ON",1); 
                break;
            case 0x83: //OFF
                if(msg.data == 0x01){
                    cycling.attach(&dimmingInterval,AUTO_DIMM_PERIOD);    
                    printMessage(msg,"OFF",0);               
                    }else
                        printMessage(msg,"ERR-OFF",1);               
                break;
            case 0x84: //DIMM
                cycling.attach(&dimmingInterval,AUTO_DIMM_PERIOD); 
                printMessage(msg,"DIMM",0);
                break;
            case 0x85: //TIME/STEP
                if(msg.data <= 0xFF && msg.data > 0x00){
                    AUTO_DIMM_PERIOD = (float)((float)msg.data /1000);
                    printMessage(msg,"TIME/STEP (ms)",0);
                }else
                     printMessage(msg,"ERR-TIME/STEP",1);  
                break;
            case 0x8A: //ASK
                aux.cmd = 0x8A;
                switch(msg.data){
                    case 0x01: //DIMM
                        aux.data = dimmingLevel;
                        printMessage(aux,"DIMM LEVEL",0);
                        break;
                    case 0x02: // TIME/STEP
                        aux.data = (unsigned short)(AUTO_DIMM_PERIOD*1000);
                        printMessage(aux,"TIME/STEP (ms)",0);                                          
                        break;
                    default:
                        aux.data = 0x00;
                        printMessage(aux, "ERR-ASK-CMD", 1);
                        break;
                    }
                break;
            default:
                printMessage(msg, "ERR-CMD", 1);
                break;
        }
    }
}

void testSlider(void){
    if (tsi.readPercentage())
        dimmingLevel= STEPS * (1.0 - tsi.readPercentage());
}

void testDimming(void){  
    if(dimmingLevel % (STEPS - AUTO_DIMM_STEP) == MIN_DIMM_VALUE)
        direction *= -1;  
   changeDimmingLevel(dimmingLevel + direction);
}

int main()
{
    zerroCross.enable_irq(); //enable routine
    zerroCross.fall(&ISR_zerroCross); // falling edge interrupt routine
    
    //cycling.attach(&testDimming,AUTO_DIMM_PERIOD);
    bt.attach(&ISR_Serial); // e mai bine fara intrerupere pentru ca nu apare intreruperea dimmingului 
    
    LED = 1; // led off.
    triacOut = 0; // triac off
    
    while(true){
        //testSlider();
        //readData();
    }
}