lcd handler for weather predictor

Dependencies:   C12832_lcd LCD_fonts

GraphicHandler.cpp

Committer:
yukari_hinata
Date:
2015-01-28
Revision:
0:896ba7a737d9
Child:
1:4399eaceb999

File content as of revision 0:896ba7a737d9:

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

// コンストラクタ
GraphicHandler::GraphicHandler(int data_dimension, int seq_time_interval, int predict_length)
{
    this->data_dimension = data_dimension;
    this->seq_time_interval  = seq_time_interval;
    this->predict_length = predict_length;
    
    // アロケート
    now_data        = new float[data_dimension];
    predict_data    = new float[data_dimension * predict_length];
    predict_weather = new int[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_weather; 
    delete joy_left; delete joy_right;
}

// 予測データと天気のセット
void GraphicHandler::set_predict_data(float* predict_data, int* predict_weather)
{
    memcpy(this->predict_data, predict_data, sizeof(float) * data_dimension * predict_length);
    memcpy(this->predict_weather, predict_weather, sizeof(int) * 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) + (60 * 60 * 9); // JSTにコンバートして取得
} 

// 画像番号の更新
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], "%%", (unsigned char *)Small_7, 37, 12);
        draw_data_at(now_data[2], "hPa", (unsigned char *)Small_7, 37, 20);
    } 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], "%%", (unsigned char *)Small_7, 37, 12);
        draw_data_at(predict_data[base_index + 2], "hPa", (unsigned char *)Small_7, 37, 20);
        draw_weather_bitmap_at(predict_weather[current_display_no-1], current_image_no, 87, 2);
        // draw_percentage_at(0.5, (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_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 = now_time + elapsed_time * 60;
    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;
}