The London Hackspace bandwidth meter

Dependencies:   LPD8806 MODSERIAL mbed picojson

See:

main.cpp

Committer:
Jasper
Date:
2012-10-21
Revision:
8:add24f73747b
Parent:
7:68a26efc1d02

File content as of revision 8:add24f73747b:

#include "mbed.h"
#include "ctype.h"

#include "MODSERIAL.h"
#include "LPD8806.h"
#include "vfd.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

/* talk to the world */
MODSERIAL pc(USBTX, USBRX);

LPD8806 strip = LPD8806(32);

void setPixelsTop(int start, int end, int colour) {
    int i;

    for (i = start; i < end + 1 ; i++) {
        strip.setPixelColor(i, colour);
    }
}

void setPixelsBottom(int start, int end, int colour) {
    int i;

    for (i = start; i < end + 1 ; i++) {
        strip.setPixelColor(16 + i, colour);
    }
}

/* 0 - 16 */
void top_strip(int quantity){
    if (quantity < 16) {
        // blank unused bits.
        setPixelsTop(quantity, 15, 0);
    }

    if (quantity == 0) return;

    quantity --;

    setPixelsTop(0, quantity < 12 ? quantity : 11, strip.Color(0, 127, 0));

    if (quantity > 11)
        setPixelsTop(12, quantity < 14 ? quantity : 14, strip.Color(127, 127, 0));

    if (quantity > 13)
        setPixelsTop(14, quantity < 16 ? quantity : 16, strip.Color(127, 0, 0));
}

void bottom_strip(int quantity){
    if (quantity < 16) {
        // blank unused bits.
        setPixelsBottom(quantity, 15, 0);
    }

    if (quantity == 0) return;
    quantity --;

    setPixelsBottom(0, quantity < 12 ? quantity : 11, strip.Color(0, 127, 0));

    if (quantity > 11)
        setPixelsBottom(12, quantity < 14 ? quantity : 14, strip.Color(127, 127, 0));

    if (quantity > 13)
        setPixelsBottom(14, quantity < 16 ? quantity : 16, strip.Color(127, 0, 0));
}

void emf_blue() {
        setPixelsBottom(0, 15, strip.Color(0, 161, 228));
        setPixelsTop(0, 15, strip.Color(0, 161, 228));
}

void strip_clear() {    
    int i;

    for (i = 0 ; i < strip.numPixels() ; i++) {
        // clear the strip
        strip.setPixelColor(i, 0);
    }
}    

#define s_looking 1
#define s_top 2
#define s_bottom 3

void send_text(const char *s) {
    int i; char c;

    for (i = 0, c=s[i]; c != 0;  i++, c=s[i])
        vfd_data(c);
}

void text_centered(const char *s, int hpos) {

    vfd_pos((20 / 2) - (strlen(s)) / 2, hpos);
    send_text(s);
}

void logo(void) {
    const char line0[] = "Welcome to";
    const char line2[] = "London Hackspace";

    text_centered(line0, 0);
    text_centered(line2, 2);        
}

int hex_char_to_int(char h) {
    int ret;
    if (h >= '0' || h <= '9') {
        ret = h - 48;
    } else if (h >= 'A' || h <= 'F') {
        ret = (h - 'A') + 10;
    } else if (h >= 'a' || h <= 'f') {
        ret = (h - 'a') + 10;
    }
    return ret;
}

int main() {
    
//    setbuf(stdout, NULL);

    pc.printf("Hello!\r\n");

    wait_ms(10);
    vfd_reset();
    wait_ms(10);
    vfd_init();
    wait_ms(10);
    logo();
    wait_ms(10);

    strip.begin();
    pc.printf("post strip.begin\r\n");
    strip_clear();
    strip.show();
    pc.printf("post strip.show\r\n");
    
    int tmp = 0;
    bool changed = false;
    char got;
    char buf[128];
    int bufpos = 0;

    enum state {Looking, Number, String, Cmd};
    enum cmd {None, Top, Bottom, VfdWrite, VfdPos, Emf, VfdReset, VfdClear, SetStrip};
    state state;
    cmd cmd;
    state = Looking;
    cmd = None;
    int num = 0; 
    
    while(1) {

        if (pc.readable()) {
            got = pc.getc();
            if (isprint(got)) {
//                pc.putc(got); // remote echo
            } else {
                pc.printf("%02x ", got);
            }
            changed = false;

            if (state == Looking) {
                switch (got) {
                    case 't':
                        state = Number;
                        num = 0;
                        cmd = Top;
                        break;
                    case 'b':
                        state = Number;
                        num = 0;
                        cmd = Bottom;
                        break;
                    case 'e': // emf blue...
                        cmd = Emf;
                        state = Cmd;
                        break;
                    case 'r':
                        cmd = VfdReset;
                        state = Cmd;
                        break;
                    case 'w':
                        cmd = VfdWrite;
                        state = String;
                        bufpos = 0;
                        break;
                    case 'p':
                        cmd = VfdPos;
                        state = String;
                        bufpos = 0;
                        break;
                    case 'c':
                        cmd = VfdClear;
                        state = Cmd;
                        break;
                    case 's':
                        cmd = SetStrip;
                        state = String;
                        bufpos = 0;
                        break;
                }
            } else { // not looking for a command
                // cr or lf terminates a command.
                if (got == '\n' || got == '\r') {
                    switch (cmd) {
                        case Top:
                            if (num > 16)
                                num = 16; 
                            top_strip(num);
                            changed = true;
                            break;
                        case Bottom:
                            if (num > 16)
                                num = 16; 
                            bottom_strip(num);
                            changed = true;
                            break;
                        case Emf:
                            emf_blue();
                            changed = true;
                            pc.printf("emf_blue\r\n");
                            break;
                        case VfdReset:
                            vfd_reset();
                            break;
                        case VfdWrite:
                            send_text(buf);
                            bufpos = 0;
                            break;
                        case VfdPos:
                            int v,h;
                            sscanf(buf, "%d,%d", &h,&v);
                            if (v > 3) v = 0;
                            if (h > 19) h = 0;
                            vfd_pos(h, v);
                            bufpos = 0;
                            break;
                        case VfdClear:
                            vfd_init();
                            break;
                        case SetStrip:
                            bufpos = 0;
                            // buf[0] == t or b for strip
                            // next 48 chars == HHH rgb * 16
                            int p, r, g, b, poff=0;
                            if (buf[0] == 'b') {
                                poff = 16;
                            }

                            for (p = 0;p < 16 ; p ++) {
                                r = hex_char_to_int(buf[(p * 3) + 1]);
                                g = hex_char_to_int(buf[(p * 3) + 2]);
                                b = hex_char_to_int(buf[(p * 3) + 3]);
                                strip.setPixelColor(p + poff , strip.Color(r,g,b));
                            }
                            changed = true;

                            break;
                        default:
                            pc.printf("no command given\r\n");
                    }
                    state = Looking;
                    cmd = None;
                }
                if (state == Number) {
                    if (got >= '0' || got <= '9') {
                        tmp = (got - 48);
                        num = (num * 10) + tmp;
                    } else {
                        pc.printf("expected a number, got %c\r\n", got);
                    }
                } else if (state == String) {
                    if (bufpos < 127) {
                        buf[bufpos] = got;
                        bufpos++;
                        buf[bufpos] = '\0';
                    } else {
                        pc.printf("buffer full\r\n!");
                        // XXX state == None here?
                    }
                }
            }
        }
        if (changed)
        {
            pc.printf("changed\r\n");
            led1 = led1 ? 0 : 1;
            strip.show();
            changed = false;
        }
    }
}