[9780] | 1 | /* |
---|
| 2 | * balanceboard.c |
---|
| 3 | * |
---|
| 4 | * Written By: |
---|
| 5 | * Gabriele Randelli |
---|
| 6 | * Email: < randelli (--AT--) dis [--DOT--] uniroma1 [--DOT--] it > |
---|
| 7 | * |
---|
| 8 | * Copyright 2010 |
---|
| 9 | * |
---|
| 10 | * This file is part of wiiC. |
---|
| 11 | * |
---|
| 12 | * This program is free software; you can redistribute it and/or modify |
---|
| 13 | * it under the terms of the GNU General Public License as published by |
---|
| 14 | * the Free Software Foundation; either version 3 of the License, or |
---|
| 15 | * (at your option) any later version. |
---|
| 16 | * |
---|
| 17 | * This program is distributed in the hope that it will be useful, |
---|
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 20 | * GNU General Public License for more details. |
---|
| 21 | * |
---|
| 22 | * You should have received a copy of the GNU General Public License |
---|
| 23 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
| 24 | * |
---|
| 25 | * $Header$ |
---|
| 26 | * |
---|
| 27 | */ |
---|
| 28 | #include "balanceboard.h" |
---|
| 29 | #include "events.h" |
---|
| 30 | |
---|
| 31 | /** |
---|
| 32 | * @brief Handle the handshake data from the balance board. |
---|
| 33 | * |
---|
| 34 | * @param bb A pointer to a balance_board_t structure. |
---|
| 35 | * @param data The data read in from the device. |
---|
| 36 | * @param len The length of the data block, in bytes. |
---|
| 37 | * |
---|
| 38 | * @return Returns 1 if handshake was successful, 0 if not. |
---|
| 39 | */ |
---|
| 40 | int balance_board_handshake(struct wiimote_t* wm, struct balance_board_t* bb, byte* data, unsigned short len) |
---|
| 41 | { |
---|
| 42 | int offset = 4; |
---|
| 43 | |
---|
| 44 | bb->cal_low_weight.top_left = 0; |
---|
| 45 | bb->cal_low_weight.top_right = 0; |
---|
| 46 | bb->cal_low_weight.bottom_left = 0; |
---|
| 47 | bb->cal_low_weight.bottom_right = 0; |
---|
| 48 | bb->cal_medium_weight.top_left = 0; |
---|
| 49 | bb->cal_medium_weight.top_right = 0; |
---|
| 50 | bb->cal_medium_weight.bottom_left = 0; |
---|
| 51 | bb->cal_medium_weight.bottom_right = 0; |
---|
| 52 | bb->cal_high_weight.top_left = 0; |
---|
| 53 | bb->cal_high_weight.top_right = 0; |
---|
| 54 | bb->cal_high_weight.bottom_left = 0; |
---|
| 55 | bb->cal_high_weight.bottom_right = 0; |
---|
| 56 | bb->pressure_raw_data.top_left = 0; |
---|
| 57 | bb->pressure_raw_data.top_right = 0; |
---|
| 58 | bb->pressure_raw_data.bottom_left = 0; |
---|
| 59 | bb->pressure_raw_data.bottom_right = 0; |
---|
| 60 | bb->pressure_weight.top_left = 0.0; |
---|
| 61 | bb->pressure_weight.top_right = 0.0; |
---|
| 62 | bb->pressure_weight.bottom_left = 0.0; |
---|
| 63 | bb->pressure_weight.bottom_right = 0.0; |
---|
| 64 | bb->pressure_weight.weight = 0.0; |
---|
| 65 | |
---|
| 66 | /* |
---|
| 67 | * Sometimes the data returned here is not correct (all bytes are 0xFF). |
---|
| 68 | * This might happen because the wiimote is lagging |
---|
| 69 | * behind our initialization sequence. |
---|
| 70 | * To fix this just request the handshake again. |
---|
| 71 | */ |
---|
| 72 | if (data[offset+offset] == 0xFF && data[offset+offset+16] == 0xFF) { |
---|
| 73 | /* get the calibration data */ |
---|
| 74 | byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte)); |
---|
| 75 | |
---|
| 76 | WIIC_DEBUG("Balance board handshake appears invalid, trying again."); |
---|
| 77 | wiic_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); |
---|
| 78 | |
---|
| 79 | return 0; |
---|
| 80 | } |
---|
| 81 | |
---|
| 82 | bb->cal_low_weight.top_right = (data[offset+0] << 8) | data[offset+1] ; |
---|
| 83 | bb->cal_low_weight.bottom_right = (data[offset+2] << 8) | data[offset+3] ; |
---|
| 84 | bb->cal_low_weight.top_left = (data[offset+4] << 8) | data[offset+5] ; |
---|
| 85 | bb->cal_low_weight.bottom_left = (data[offset+6] << 8) | data[offset+7] ; |
---|
| 86 | bb->cal_medium_weight.top_right = (data[offset+8] << 8) | data[offset+9] ; |
---|
| 87 | bb->cal_medium_weight.bottom_right = (data[offset+10] << 8) | data[offset+11] ; |
---|
| 88 | bb->cal_medium_weight.top_left = (data[offset+12] << 8) | data[offset+13] ; |
---|
| 89 | bb->cal_medium_weight.bottom_left = (data[offset+14] << 8) | data[offset+15] ; |
---|
| 90 | bb->cal_high_weight.top_right = (data[offset+16] << 8) | data[offset+17] ; |
---|
| 91 | bb->cal_high_weight.bottom_right = (data[offset+18] << 8) | data[offset+19] ; |
---|
| 92 | bb->cal_high_weight.top_left = (data[offset+20] << 8) | data[offset+21] ; |
---|
| 93 | bb->cal_high_weight.bottom_left = (data[offset+22] << 8) | data[offset+23] ; |
---|
| 94 | |
---|
| 95 | /* handshake done */ |
---|
| 96 | wm->exp.type = EXP_BALANCE_BOARD; |
---|
| 97 | |
---|
| 98 | return 1; |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | /** |
---|
| 102 | * @brief Handle balance board event. |
---|
| 103 | * |
---|
| 104 | * @param bb A pointer to a balance_board_t structure. |
---|
| 105 | * @param msg The message specified in the event packet. |
---|
| 106 | */ |
---|
| 107 | void balance_board_event(struct balance_board_t* bb, byte* msg) |
---|
| 108 | { |
---|
| 109 | // Raw data |
---|
| 110 | bb->pressure_raw_data.top_right = (msg[0] << 8) | msg[1]; |
---|
| 111 | bb->pressure_raw_data.bottom_right = (msg[2] << 8) | msg[3]; |
---|
| 112 | bb->pressure_raw_data.top_left = (msg[4] << 8) | msg[5]; |
---|
| 113 | bb->pressure_raw_data.bottom_left = (msg[6] << 8) | msg[7]; |
---|
| 114 | |
---|
| 115 | /* Weight in kg (we must interpole here) */ |
---|
| 116 | |
---|
| 117 | // Top Right |
---|
| 118 | if(bb->pressure_raw_data.top_right <= bb->cal_medium_weight.top_right) { |
---|
| 119 | bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_low_weight.top_right) / (float)(bb->cal_medium_weight.top_right - bb->cal_low_weight.top_right); |
---|
| 120 | } |
---|
| 121 | else if(bb->pressure_raw_data.top_right <= bb->cal_high_weight.top_right) { |
---|
| 122 | bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_medium_weight.top_right) / (float)(bb->cal_high_weight.top_right - bb->cal_medium_weight.top_right) + 17.0; |
---|
| 123 | } |
---|
| 124 | else { |
---|
| 125 | bb->pressure_weight.top_right = 17.0 * (bb->pressure_raw_data.top_right - bb->cal_high_weight.top_right) / (float)(bb->cal_high_weight.top_right - bb->cal_medium_weight.top_right) + 34.0; |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | // Bottom Right |
---|
| 129 | if(bb->pressure_raw_data.bottom_right <= bb->cal_medium_weight.bottom_right) { |
---|
| 130 | bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_low_weight.bottom_right) / (float)(bb->cal_medium_weight.bottom_right - bb->cal_low_weight.bottom_right); |
---|
| 131 | } |
---|
| 132 | else if(bb->pressure_raw_data.bottom_right <= bb->cal_high_weight.bottom_right) { |
---|
| 133 | bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_medium_weight.bottom_right) / (float)(bb->cal_high_weight.bottom_right - bb->cal_medium_weight.bottom_right) + 17.0; |
---|
| 134 | } |
---|
| 135 | else { |
---|
| 136 | bb->pressure_weight.bottom_right = 17.0 * (bb->pressure_raw_data.bottom_right - bb->cal_high_weight.bottom_right) / (float)(bb->cal_high_weight.bottom_right - bb->cal_medium_weight.bottom_right) + 34.0; |
---|
| 137 | } |
---|
| 138 | |
---|
| 139 | // Top Left |
---|
| 140 | if(bb->pressure_raw_data.top_left <= bb->cal_medium_weight.top_left) { |
---|
| 141 | bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_low_weight.top_left) / (float)(bb->cal_medium_weight.top_left - bb->cal_low_weight.top_left); |
---|
| 142 | } |
---|
| 143 | else if(bb->pressure_raw_data.top_left <= bb->cal_high_weight.top_left) { |
---|
| 144 | bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_medium_weight.top_left) / (float)(bb->cal_high_weight.top_left - bb->cal_medium_weight.top_left) + 17.0; |
---|
| 145 | } |
---|
| 146 | else { |
---|
| 147 | bb->pressure_weight.top_left = 17.0 * (bb->pressure_raw_data.top_left - bb->cal_high_weight.top_left) / (float)(bb->cal_high_weight.top_left - bb->cal_medium_weight.top_left) + 34.0; |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | // Botton Left |
---|
| 151 | if(bb->pressure_raw_data.bottom_left <= bb->cal_medium_weight.bottom_left) { |
---|
| 152 | bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_low_weight.bottom_left) / (float)(bb->cal_medium_weight.bottom_left - bb->cal_low_weight.bottom_left); |
---|
| 153 | } |
---|
| 154 | else if(bb->pressure_raw_data.bottom_left <= bb->cal_high_weight.bottom_left) { |
---|
| 155 | bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_medium_weight.bottom_left) / (float)(bb->cal_high_weight.bottom_left - bb->cal_medium_weight.bottom_left) + 17.0; |
---|
| 156 | } |
---|
| 157 | else { |
---|
| 158 | bb->pressure_weight.bottom_left = 17.0 * (bb->pressure_raw_data.bottom_left - bb->cal_high_weight.bottom_left) / (float)(bb->cal_high_weight.bottom_left - bb->cal_medium_weight.bottom_left) + 34.0; |
---|
| 159 | } |
---|
| 160 | |
---|
| 161 | bb->pressure_weight.weight = bb->pressure_weight.top_right + bb->pressure_weight.top_left + bb->pressure_weight.bottom_right + bb->pressure_weight.bottom_left; |
---|
| 162 | } |
---|
| 163 | |
---|
| 164 | /** |
---|
| 165 | * @brief The balance board disconnected. |
---|
| 166 | * |
---|
| 167 | * @param bb A pointer to a balance_board_t structure. |
---|
| 168 | */ |
---|
| 169 | void balance_board_disconnected(struct balance_board_t* bb) |
---|
| 170 | { |
---|
| 171 | memset(bb, 0, sizeof(struct balance_board_t)); |
---|
| 172 | } |
---|