lcd handler for weather predictor

Dependencies:   C12832_lcd LCD_fonts

GraphicHandler.cpp

Committer:
yukari_hinata
Date:
2015-02-19
Revision:
5:4aacf35455da
Parent:
4:1d811ee32310

File content as of revision 5:4aacf35455da:

#include "GraphicHandler.hpp"
#include "graphics.hpp"

// コンストラクタ
GraphicHandler::GraphicHandler(int data_dimension, int seq_time_interval, int predict_length, time_t init_time)
{
    this->data_dimension    = data_dimension;
    this->seq_time_interval = seq_time_interval;
    this->predict_length    = predict_length;
    this->now_time          = init_time;

    // アロケート
    now_data        = new float[data_dimension];
    predict_data    = new float[data_dimension * predict_length];
    predict_weather = new int[predict_length];
    predict_probability = new float[predict_length];

    // ティッカー初期化
    // time_ticker.attach(this, &GraphicHandler::update_time, 60.0);
    // image_ticker.attach(this, &GraphicHandler::update_image, 1.0);

    // ジョイスティック割り込み設定 : p13が左, p16が右
    joy_left  = new InterruptIn(p13);
    joy_right = new InterruptIn(p16);
    joy_left->rise(this, &GraphicHandler::joyleft_isr);
    joy_right->rise(this, &GraphicHandler::joyright_isr);

    // LCDの初期化/フォントサイズ設定
    lcd.cls();
    // lcd.setmode(XOR);
    // lcd.set_font((unsigned char*) Arial_9);

    // 画面番号のリセット
    current_display_no = 0;
    current_image_no = 0;
}

GraphicHandler::~GraphicHandler(void)
{
    delete [] now_data;
    delete [] predict_data;
    delete [] predict_probability;
    delete [] predict_weather;
    delete joy_left;
    delete joy_right;
}

// 予測データと天気のセット
void GraphicHandler::set_predict_data(float* predict_data, int* predict_weather, float* predict_probability)
{
    memcpy(this->predict_data, predict_data, sizeof(float) * data_dimension * predict_length);
    memcpy(this->predict_weather, predict_weather, sizeof(int) * predict_length);
    memcpy(this->predict_probability, predict_probability, sizeof(float) * predict_length);
}

// 観測データのセット
void GraphicHandler::set_now_data(float* now_data)
{
    memcpy(this->now_data, now_data, sizeof(float) * data_dimension);
}


// ジョイスティック左
void GraphicHandler::joyleft_isr(void)
{
    current_display_no++;
    //update_draw();
    //printf("JOYSTICK LEFT FIRED DISP_NO:%d \r\n", current_display_no);

}

// ジョイスティック右
void GraphicHandler::joyright_isr(void)
{
    current_display_no--;
    //update_draw();
    //printf("JOYSTICK RIGHT FIRED DISP_NO:%d \r\n", current_display_no);
}

// 時間の更新
void GraphicHandler::update_time(void)
{
    now_time = time(NULL);
}

// 最終学習時刻の更新
void GraphicHandler::update_last_learned_time(void)
{
    last_learned_time = now_time;
}

// 画像番号の更新
void GraphicHandler::update_image(void)
{
    current_image_no++;
    if (current_image_no >= 2) {
        current_image_no = 0;
    }
}

// 描画処理
void GraphicHandler::update_draw(void)
{
    lcd.cls();         // 画面クリア/locateの座標を原点に
    lcd.setmode(XOR);  // 描写モードをXORに : 重ねて書くと消える

    // 現在の画面番号の調整
    if (current_display_no < 0) {
        current_display_no = 0;
    } else if (current_display_no > predict_length) {
        current_display_no = predict_length;
    }

    // 現在/予測データの描写 配置は全部決め打ち(すまんな)
    if (current_display_no == 0) {
        draw_text_at("Now", (unsigned char *)Arial_9, 0, 0);
        // データ
        draw_data_at(now_data[0], "C", (unsigned char *)Small_7, 37, 4);
        draw_data_at(now_data[1], "hPa", (unsigned char *)Small_7, 37, 12);
        draw_data_at(now_data[2], "%%", (unsigned char *)Small_7, 37, 20);
        // 時刻
        draw_time_at((unsigned char *)Arial_9, 0, 5, 10);
    } else {
        // 画面番号に合わせて予測系列インデックスを変化させる
        int base_index = data_dimension * (current_display_no-1);
        draw_text_at("Predict", (unsigned char *)Arial_9, 0, 0);
        draw_data_at(predict_data[base_index], "C", (unsigned char *)Small_7, 37, 4);
        draw_data_at(predict_data[base_index + 1], "hPa", (unsigned char *)Small_7, 37, 12);
        draw_data_at(predict_data[base_index + 2], "%%", (unsigned char *)Small_7, 37, 20);
        draw_weather_bitmap_at(predict_weather[current_display_no-1], current_image_no, 87, 2);
        draw_percentage_at(predict_probability[current_display_no-1], (unsigned char *)Small_6, 112, 25);
        // 予測時刻
        draw_time_at((unsigned char *)Arial_9, seq_time_interval * current_display_no, 5, 10);
    }

}

// テキストの描画ルーチン
void GraphicHandler::draw_text_at(const char* str,
                                  unsigned char* format,
                                  int x, int y)
{
    // lcd.setmode(XOR);
    lcd.set_font(format);
    lcd.locate(x, y);
    lcd.printf(str);
    return;
}

// ログ出力
void GraphicHandler::draw_log(const char* msg)
{   
    lcd.cls(); 
    draw_text_at(msg, (unsigned char *)Small_6, 0, 25);
}

// データの描画ルーチン
void GraphicHandler::draw_data_at(float data,
                                  const char* unit,
                                  unsigned char* format,
                                  int x, int y)
{
    // 実質sprintf
    char buffer[20];
    sprintf(buffer, "%5.1f %s", data, unit);    // 全体5桁, 小数点一位まで.
    draw_text_at(buffer, format, x, y);
    return;
}

// 確率の描画
void GraphicHandler::draw_percentage_at(float percentage,
                                        unsigned char* format,
                                        int x, int y)
{
    char buffer[20];
    int convert_per_val = int(percentage * 100);
    // 確率100%の時は'%'を印字しない
    if ( convert_per_val >= 100 ) {
        strcat(buffer, "100");
    } else {
        sprintf(buffer, "%d", convert_per_val);
        strcat(buffer, "%%");
    }
    draw_text_at(buffer, format, x, y);
    return;
}

// 時刻の描画ルーチン
void GraphicHandler::draw_time_at(unsigned char* format,
                                  int elapsed_time,
                                  int x, int y)
{
    char buffer[20];
    time_t buf_time;
    // 経過時間が指定された場合は予測時刻であることがわかる
    if (elapsed_time > 0) {
        buf_time = last_learned_time + elapsed_time;
    } else if (elapsed_time == 0) {
        buf_time = now_time;
    } else {
        buf_time = time(NULL);
    }
    strftime(buffer, 32, "%H:%M", localtime(&buf_time));
    draw_text_at(buffer, format, x, y);
    return;
}

// 天候の描画ルーチン
void GraphicHandler::draw_weather_bitmap_at(int weather_id,
        int image_no,
        int x, int y)
{
    Bitmap buffer;

    // lcd.setmode(XOR);
    // ビットマップ選択
    switch(weather_id) {
        case SHINY:
            // 番号についても場合分けだよ!
            if (image_no == 0) {
                buffer = bitm_shiny1;
            } else if (image_no == 1) {
                buffer = bitm_shiny2;
            }
            break;
        case CLOUDY:
            if (image_no == 0) {
                buffer = bitm_cloudy1;
            } else if (image_no == 1) {
                buffer = bitm_cloudy2;
            }
            break;
        case RAINY:
            if (image_no == 0) {
                buffer = bitm_rainy1;
            } else if (image_no == 1) {
                buffer = bitm_rainy2;
            }
            break;
        case SNOWY:
            if (image_no == 0) {
                buffer = bitm_snowy1;
            } else if (image_no == 1) {
                buffer = bitm_snowy2;
            }
            break;
        default:
            fprintf(stderr, "ERROR : weather drawing \r\n");
            break;
    }
    // 描画
    lcd.print_bm(buffer, x, y);
    lcd.copy_to_lcd();
    return;
}