4180 Fish Tank Project

Dependencies:   Motordriver NeoStrip mbed-rtos mbed

Fork of rtos_basic by mbed official

main.cpp

Committer:
4180Team
Date:
2017-12-14
Revision:
12:097b52548f0b
Parent:
11:0309bef74ba8

File content as of revision 12:097b52548f0b:

#include "mbed.h"
#include "rtos.h"
#include <stdint.h>
#include "NeoStrip.h"
#include "gt.h"
#include <iomanip> // setprecision
#include <sstream> // stringstream
#include "motordriver.h"
#define N 64
#define PATTERNS 3

RawSerial  pi(USBTX, USBRX);

NeoStrip strip(p18, N);
DigitalIn b1(p20); // brightness up
DigitalIn b2(p19); // brightness down
DigitalIn b3(p21); // next pattern

Thread t1;
Thread t2;
Mutex ulcd_mutex;
Motor A(p24, p23, p22, 1); // pwm, fwd, rev, can brake
PwmOut led1(LED1); //indicates when mbed is ready
PwmOut led2(LED2);
PwmOut led4(LED4);
AnalogIn photocell(p16);
float volatile x = 0; //global variable to change motor speed
bool test = false;
int hueToRGB(float h);
void pattern0();
void pattern1();
void pattern2();
// array of function pointers to the various patterns
void (*patterns[])(void) = {&pattern0, &pattern1, &pattern2};

//
void motor() {
    while(true) {
        led1 = 1;
        if (test) {
            x = .30;
            A.speed(x);
            Thread::wait(1200);
            test = false;
            A.speed(0);
        }
    }
}
double volatile bright = 0.05; 
bool test2 = false;  
float value = 0;
void ambient() {
    led2 = 1;
    while (true) {
        if (test2) {
            value = photocell;
            if (value < .10) value = .10;
            if (value > .3) value = .30;
            bright = abs(value - .10 - .20);
            if (bright > .25) bright = .25;
            strip.setBrightness(bright);
        }
    } 
}
int pattern = 0;
void dev_recv()
{
    char temp = 0;
    while(pi.readable()) {
        temp = pi.getc();
        pi.putc(temp);
        if (temp=='1') {
            bright = .15;
            strip.setBrightness(bright);
        }
        if (temp=='0' && bright > 0){
            bright = 0;
            strip.setBrightness(bright);
        }
        if (temp=='=') test = true; // run motor
        if (temp=='a') test2 = true; // ambient mode on
        if (temp=='m') test2 = false; // manual mode on
        if (temp=='+') {
            bright = bright + .083;
            if (bright > .25) bright = .25;
            strip.setBrightness(bright);    
        }
        if (temp=='-') {
            bright = bright - .083;
            if (bright < 0) bright = 0;
            strip.setBrightness(bright);    
        }
        if (temp=='p') pattern = (pattern + 1) % 3;
    }
}
int main() {
    pi.baud(9600);
    pi.attach(&dev_recv, Serial::RxIrq);
    b1.mode(PullUp);
    b2.mode(PullUp);
    b3.mode(PullUp);
    bool b3o = b3;      // old copy of button 3 to poll for changes
    bright = .05;
    strip.setBrightness(bright);    // set default brightness
    t1.start(ambient);
    t2.start(motor);
    
    while (1) {
         //button 1 increases brightness
        if (b1 && bright < .25)
        {
            bright += 0.005;
            if (bright > .25)
                bright = .25;
            strip.setBrightness(bright);
        }

        // button 2 decreases brightness
        if (b2 && bright > 0)
        {
            bright -= 0.005;
            if (bright < 0)
                bright = 0;
            strip.setBrightness(bright);
        }
        
        // button 3 changes the pattern, only do stuff when its state has changed
        if (b3 != b3o)
        {
            if (b3 && ++pattern == PATTERNS)
                pattern = 0;
            b3o = b3;
        }
        // run the pattern update function which sets the strip's pixels
        patterns[pattern]();
        strip.write();
        wait_ms(10);
    }
}

//// pattern0 displays a static image
void pattern0()
{
    strip.setPixels(0, N, gt_img);
}

// display a shifting rainbow, all colors have maximum
// saturation and value, with evenly spaced hue
void pattern1()
{
    static float dh = 360.0 / N;
    static float x = 0;
    for (int i = 0; i < N; i++)
        strip.setPixel(i, hueToRGB((dh * i) - x));
    x += 1;
    if (x > 360)
        x = 0;
}
// display a shifting gradient between red and blue
void pattern2()
{
    // offset for each pixel to allow the pattern to move
    static float x = 0;
    float r, b, y;
    for (int i = 0; i < N; i++)
    {
        // y is a scaled position between 0 (red) and 1.0 (blue)
        y = 1.0 * i / (N - 1) + x;
        if (y > 1)
            y -= 1;
        // if on the left half, red is decreasing and blue is increasng
        if (y < 0.5)
        {
            b = 2 * y;
            r = 1 - b;
        }
        // else red is increasing and blue is decreasing
        else
        {
            r = 2 * (y - 0.5);
            b = 1 - r;
        }
        // scale to integers and set the pixel
        strip.setPixel(i, (uint8_t)(r * 255), 0, (uint8_t)(b * 200));
    }
    x += 0.003;
    if (x > 1)
        x = 0;
}

// Converts HSV to RGB with the given hue, assuming
// maximum saturation and value
int hueToRGB(float h)
{
    // lots of floating point magic from the internet and scratching my head
    float r, g, b;
    if (h > 360)
        h -= 360;
    if (h < 0)
        h += 360;
    int i = (int)(h / 60.0);
    float f = (h / 60.0) - i;
    float q = 1 - f;
    switch (i % 6)
    {
        case 0: r = 1; g = f; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = f; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = f; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
        default: r = 0; g = 0; b = 0; break;
    }
    // scale to integers and return the packed value
    uint8_t R = (uint8_t)(r * 255);
    uint8_t G = (uint8_t)(g * 255);
    uint8_t B = (uint8_t)(b * 255);
    return (R << 16) | (G << 8) | B;
}
// test code, this demonstrates working motor drivers. 
// full reverse to full stop, dynamicaly brake and switch off.