Projet S5 Info - Beginner

Dependencies:   TextLCD XBeeLib mbed-rtos mbed

Fork of Coordinateur-Advanced by Vincent Belanger

main.cpp

Committer:
vinbel93
Date:
2016-04-14
Revision:
10:3e598dcf9e59
Parent:
9:912506053afd

File content as of revision 10:3e598dcf9e59:

#include "mbed.h"
#include "XBeeLib.h"
#include "TextLCD.h"
#include "rtos.h"

using namespace XBeeLib;

PwmOut speaker(p21);
TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
DigitalIn button_back(p28);
DigitalIn button_enter(p29);
DigitalIn button_next(p30);
Ticker timer;
int btn_b;
int btn_e;
int btn_n;

bool capt_1;
bool capt_2;
bool capt_3;
bool capt_4;
bool capt_5;
bool capt_6;

const float DO = 261.63;
const float RE = 293.66;
const float MI = 329.63;
const float FA = 349.23;
const float SOL = 392.00;
const float LA = 440.00;

float dutyCycle = 0.0002;
float octaveMult = 2.0;
int lastCapt = -1;
Thread* thread_digital;
Thread* thread_menu;

const char MainMenuText[2][16] = {"1. Volume", "2. Octave"};
const char VolumeMenuText[4][16] = {"+1", "-1", "+10", "-10"};
const char OctaveMenuText[3][16] = {"3", "4", "5"};
const int maxMenuCount = 2;
const int maxVolumeCount = 4;
const int maxOctaveCount = 3;

bool inMainMenu = true;

int menuCount = 0;
int itemCount = 0;

static float findPeriod(float frequency)
{
    float freq = frequency * octaveMult;
    return 1.0/freq;
}

void timer_Signal()
{
    thread_menu->signal_set(0x2);
}

void digitLect(void const *args)
{
    while(true)
    {
        btn_b = button_back;
        btn_e = button_enter;
        btn_n = button_next;
    }
}

static void receive_cb(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len)
{
    const uint64_t remote_addr64 = remote.get_addr64();

    capt_1 = (data[0] & 0b10000000);
    capt_2 = (data[0] & 0b01000000);
    capt_3 = (data[0] & 0b00100000);
    capt_4 = (data[0] & 0b00010000);
    capt_5 = (data[0] & 0b00001000);
    capt_6 = (data[0] & 0b00000100);

    if(!capt_1) {
        if (lastCapt != 1) {
            speaker.period(findPeriod(DO));
        }
        
        speaker = dutyCycle;
        lastCapt = 1;
    } else if(!capt_2) {
        if (lastCapt != 2) {
            speaker.period(findPeriod(RE));
        }

        speaker = dutyCycle;
        lastCapt = 2;
    } else if(!capt_3) {
        if (lastCapt != 3) {
            speaker.period(findPeriod(MI));
        }

        speaker = dutyCycle;
        lastCapt = 3;
    } else if(!capt_4) {
        if (lastCapt != 4) {
            speaker.period(findPeriod(FA));
        }

        speaker = dutyCycle;
        lastCapt = 4;
    } else if(!capt_5) {
        if (lastCapt != 5) {
            speaker.period(findPeriod(SOL));
        }

        speaker = dutyCycle;
        lastCapt = 5;
    } else if(!capt_6) {
        if (lastCapt != 6) {
            speaker.period(findPeriod(LA));
        }

        speaker = dutyCycle;
        lastCapt = 6;
    } else {
        if (lastCapt != 0)
        {
            speaker = 0.0f;
        }
        
        lastCapt = 0;
    }
}

void nextItem(int menuCount, int itemCount, bool inMainMenu)
{
    lcd.cls();
    if(inMainMenu) {
        lcd.printf(MainMenuText[menuCount]);
    } else if(!inMainMenu && menuCount == 0) {
        lcd.printf(VolumeMenuText[itemCount]);
    } else if(!inMainMenu && menuCount == 1) {
        lcd.printf(OctaveMenuText[itemCount]);
    } else {
        lcd.printf("nextItem ERROR.");
    }
}

void enterMenu()
{
    lcd.cls();
    nextItem(menuCount, itemCount, inMainMenu);

    if(menuCount == 0) {
        switch (itemCount) {
            case 0:
                dutyCycle += 0.0001;
                if (dutyCycle > 0.5)
                {
                    dutyCycle = 0.5;
                }
                break;
            case 1:
                dutyCycle -= 0.0001;
                if (dutyCycle < 0)
                {
                    dutyCycle = 0;
                }
                break;
            case 2:
                dutyCycle += 0.001;
                if (dutyCycle > 0.5)
                {
                    dutyCycle = 0.5;
                }
                break;
            case 3:
                dutyCycle -= 0.001;
                if (dutyCycle < 0)
                {
                    dutyCycle = 0;
                }
                break;
            default:
                break;
        }
    }
    else if(menuCount == 1) {
        switch (itemCount) {
            case 0:
                octaveMult = 0.5;
                break;
            case 1:
                octaveMult = 1.0;
                break;
            case 2:
                octaveMult = 2.0;
                break;
            default:
                break;
        }
    }
}

void backMenu()
{
    lcd.cls();
    nextItem(menuCount, itemCount, inMainMenu);
}

void processMenu(void const *args)
{
    while(true)
    {
        Thread::signal_wait(0x2);
        if(btn_n) {
            if(menuCount != maxMenuCount - 1 && inMainMenu) {
                menuCount++;
            }
    
            else if(menuCount == maxMenuCount - 1 && inMainMenu) {
                menuCount = 0;
            }
    
            if(menuCount == 0 && !inMainMenu) {
                if(itemCount != maxVolumeCount - 1) {
                    itemCount++;
                } else {
                    itemCount = 0;
                }
            }
    
            if(menuCount == 1 && !inMainMenu) {
                if(itemCount != maxOctaveCount - 1) {
                    itemCount++;
                } else {
                    itemCount = 0;
                }
            }
            nextItem(menuCount, itemCount, inMainMenu);
        }
    
        if(btn_e) {
    
            inMainMenu = false;
            enterMenu();
    
        }
    
        if(btn_b) {
            inMainMenu = true;
            itemCount = 0;
            backMenu();
        }
    }
}

int main()
{
    XBeeZB xbee = XBeeZB(p13, p14, NC, NC, NC, 9600);
    xbee.register_receive_cb(&receive_cb);
    RadioStatus const radioStatus = xbee.init();
    
    timer.attach_us(&timer_Signal, 100000);
    thread_digital = new Thread(digitLect);
    thread_menu = new Thread(processMenu);
    MBED_ASSERT(radioStatus == Success);
    
    while (!xbee.is_joined()) {
        wait_ms(1000);
    }

    lcd.printf("Make a Selection:");

    while (true) {
        xbee.process_rx_frames();
        wait_ms(10);
    }
}