Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed AdafruitST7735 BLE_API Adafruit_GFX nRF51822
main.cpp
00001 #include "mbed.h" 00002 #include "ble/BLE.h" 00003 #include "Adafruit_GFX/Adafruit_GFX.h" 00004 #include "AdafruitST7735/Adafruit_ST7735.h" 00005 00006 // Конфигурация BLE 00007 const static uint16_t SERVICE_UUID = 0xA000; 00008 const static char DEVICE_NAME[] = "HPSP BT-Lite"; 00009 00010 // Настройка выводов 00011 DigitalOut led1(P0_21); 00012 DigitalOut DISP_LED (P0_16); 00013 DigitalIn key1 (P0_8); 00014 DigitalIn key2 (P0_17); 00015 DigitalOut OSC (P0_6); 00016 00017 #define TFT_MISO P0_4 // NC(NC) //Не подключен так как отсутсвует на дисплее 00018 #define TFT_RST P0_9 // RST(5) 00019 #define TFT_DC P0_10 // D/C(6) // не работает на 10 00020 #define TFT_MOSI P0_11 // DIN(7) 00021 #define TFT_SCK P0_12 // CLK(8) 00022 #define TFT_SS P0_13 // CS(11) 00023 00024 // 00025 Adafruit_ST7735 tft(TFT_MOSI, TFT_MISO, TFT_SCK, TFT_SS, TFT_DC, TFT_RST); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST 00026 00027 // Назначение цветов 00028 #define BLACK 0x0000 00029 #define BLUE 0x001F 00030 #define RED 0xF800 00031 #define GREEN 0x07E0 00032 #define CYAN 0x07FF 00033 #define MAGENTA 0xF81F 00034 #define YELLOW 0xFFE0 00035 #define WHITE 0xFFFF 00036 int COLOR = WHITE; 00037 00038 Timeout KEY_TIME; // Счетчик для таймера работы программы 00039 short FLAG = 0; // Флаг старта программы 00040 unsigned int HOUR = 0; // Часы 00041 unsigned int MIN = 0; // Минуты 00042 unsigned int SEC = 0; // Секунды 00043 unsigned int TIME_PROGRAMM = 5400; // Время работы программы 00044 int START = 0; 00045 // Переменные типа char для дисплея 00046 char HOUR_CHAR[2] = {'0', '0'}; 00047 char MIN_CHAR[2] = {'0', '0'}; 00048 char SEC_CHAR[2] = {'0', '0'}; 00049 int r = 20; 00050 00051 //static UARTService* uartService; 00052 00053 //static EventQueue eventQueue( 00054 // /* event count */ 16 * /* event size */ 32 00055 //); 00056 00057 Ticker ticker; 00058 00059 char freq_storage[900] = {0}; //резервируем блок памяти в EEPROM для хранения частот 00060 char timer_storage[100] = {0}; //резервируем блок памяти в EEPROM для хранения таймеров 00061 00062 char* freq_storage_pos = freq_storage; 00063 char* timer_storage_pos = timer_storage; 00064 00065 void generate() 00066 { 00067 char* freq_storage_pos = freq_storage; 00068 unsigned short freq; 00069 unsigned short duration = 180; // длительность 00070 00071 memcpy( &freq, freq_storage_pos, sizeof(freq) ); 00072 freq_storage_pos += sizeof(freq); 00073 00074 while ( freq != 0 ) 00075 { 00076 memcpy( &duration, freq_storage_pos, sizeof(duration) ); 00077 freq_storage_pos += sizeof(duration); 00078 00079 // распаковываем частоту 00080 float real_freq; 00081 if ( freq <= 1000 ) 00082 { 00083 real_freq = (float)freq / 100; 00084 } 00085 else if ( freq <= 11000 ) 00086 { 00087 real_freq = (float)(freq - 1000) / 10; 00088 } 00089 else 00090 { 00091 real_freq = freq - 10000; 00092 } 00093 00094 float real_duration = (float)duration * 1000; 00095 00096 OSC = 1; 00097 wait_ms(real_duration); 00098 OSC = 0; 00099 00100 /* 00101 digitalWrite(led, HIGH); 00102 tone(ant, real_freq); 00103 customDelay(real_duration); 00104 noTone(ant); 00105 digitalWrite(led, LOW); 00106 */ 00107 00108 memcpy( &freq, freq_storage_pos, sizeof(freq) ); 00109 freq_storage_pos += sizeof(freq); 00110 } 00111 } 00112 00113 int frequencies_scan_mode = 1; 00114 00115 int parse_bt_data( char *buffer // буфер, в котором уже лежат принятые данные в виде стандартной C строки 00116 ) 00117 { 00118 if ( buffer == NULL) // проверяем корректность входных данных 00119 { 00120 return 0; 00121 } 00122 00123 // вспомогательные переменные 00124 char *current = buffer; // указатель на текущий символ 00125 00126 // сканируем частоты 00127 while ( frequencies_scan_mode != 0 && *current != 0 ) 00128 { 00129 if ( *current == ':' ) 00130 { 00131 break; // выходим, так как частоты закончились 00132 } 00133 00134 unsigned long freq; // частота в сотых долях герца 00135 unsigned long duration; // длительность в секундах 00136 char separator[2]; // разделитель 00137 00138 int symbols_read; 00139 int values_read = sscanf( current, "%ld %ld%1[,:]%n", &freq, &duration, separator, &symbols_read); // считываем частоту и длительность 00140 00141 if ( values_read != 3 ) 00142 { 00143 // закончился буффер 00144 // копируем оставшиеся данные в начало буффера 00145 int rest_len = strlen( current ); // длина остатка в буффере 00146 memmove( buffer, current, rest_len ); 00147 return rest_len; 00148 } 00149 00150 // кодируем частоту для умещения в память 00151 unsigned short packed_freq; 00152 if ( freq <= 10 * 100 ) // 10Гц 00153 { 00154 packed_freq = freq; 00155 } 00156 else if ( freq <= 1000 * 100 ) // 1кГц 00157 { 00158 packed_freq = 1000 + freq / 10; 00159 } 00160 else 00161 { 00162 packed_freq = 10000 + freq / 100; 00163 } 00164 00165 // сохраняем данные в EEPROM 00166 memcpy( freq_storage_pos, &packed_freq, sizeof(packed_freq) ); 00167 freq_storage_pos += sizeof(packed_freq); 00168 memcpy( freq_storage_pos, &duration, sizeof(duration) ); 00169 freq_storage_pos += sizeof(duration); 00170 00171 // моргаем после каждых данных 00172 //led2 = !led2; 00173 00174 current += symbols_read; //переходим к следующей паре 00175 00176 if ( *separator == ':' ) 00177 { 00178 // пишем признак конца данных 00179 unsigned short end = 0; 00180 memcpy( freq_storage_pos, &end, sizeof(end) ); 00181 00182 frequencies_scan_mode = 0; // загрузка частот завершена 00183 break; 00184 } 00185 } 00186 00187 // сканируем таймеры 00188 while ( *current != 0 ) 00189 { 00190 if ( *current == '.' ) 00191 { 00192 break; // выходим, так как таймеры закончились 00193 } 00194 00195 unsigned int timer_start; 00196 00197 int symbols_read; 00198 char separator[2]; //разделитель 00199 int values_read = sscanf( current, "%d%1[,.]%n", &timer_start, separator, &symbols_read); //считываем время до запуска таймера 00200 00201 if ( values_read != 2 ) 00202 { 00203 // закончился буффер 00204 // копируем оставшиеся данные в начало буффера 00205 int rest_len = strlen( current ); // длина остатка в буффере 00206 memmove( buffer, current, rest_len ); 00207 return rest_len; 00208 } 00209 00210 // сохраняем данные в EEPROM 00211 //eeprom_write_block( timer_start, timer_storage_pos, sizeof(timer_start) ); 00212 //timer_storage_pos += sizeof(timer_start); 00213 00214 current += symbols_read; //переходим к следующей паре 00215 00216 if ( *separator == '.' ) 00217 { 00218 // пишем признак конца данных 00219 unsigned short end = 0; 00220 memcpy( timer_storage_pos, &end, sizeof(end) ); 00221 break; // конец данных 00222 } 00223 } 00224 00225 return 0; 00226 } 00227 00228 void updateSensorValue() 00229 { 00230 00231 } 00232 00233 void periodicCallback(void) 00234 { 00235 OSC = !OSC; /* Do blinky on LED1 to indicate system aliveness. */ 00236 TIME_PROGRAMM--; 00237 r = r + 2; 00238 if (r >= 60){ 00239 r = 30; 00240 if(COLOR == WHITE){ 00241 COLOR = BLACK; 00242 } 00243 else (COLOR = WHITE); 00244 }; 00245 if (BLE::Instance().getGapState().connected) { 00246 // eventQueue.call(updateSensorValue); 00247 } 00248 } 00249 00250 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00251 { 00252 tft.fillScreen(ST7735_BLACK); 00253 FLAG = 1; 00254 r= 30; 00255 } 00256 00257 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00258 { 00259 BLE::Instance().gap().startAdvertising(); 00260 tft.fillScreen(ST7735_BLACK); 00261 FLAG = 1; 00262 r= 30; 00263 } 00264 00265 #define INPUT_BUFFER_SIZE 50 00266 char buffer[INPUT_BUFFER_SIZE + 1]; //приемный буффер 00267 static int config_complete = 0; 00268 00269 void onDataWrittenCallback(const GattWriteCallbackParams *params) { 00270 if ( params != NULL ) 00271 { 00272 //led2 = 0; 00273 unsigned int buffer_pos = 0; //текущая позиция в буффере 00274 00275 //если есть данные - читаем 00276 while ( buffer_pos < params->len ) 00277 { 00278 //загоняем прочитанное в буфер 00279 char symbol = params->data[buffer_pos++]; 00280 buffer[buffer_pos] = symbol; 00281 if ( symbol == '.') 00282 { 00283 buffer[buffer_pos] = 0; // закрываем строку 00284 parse_bt_data(buffer); // обрабатываем полученный кусок данных 00285 00286 // конец данных, прекращаем чтение 00287 // данные получены, надо выставить флаг и больше из BT не читать 00288 config_complete = 1; 00289 break; 00290 } 00291 00292 if ( buffer_pos == INPUT_BUFFER_SIZE ) 00293 { 00294 buffer[INPUT_BUFFER_SIZE] = 0; //символ конца строки для полностью заполненного буффера 00295 buffer_pos = parse_bt_data(buffer); // обрабатываем полученный кусок данных 00296 } 00297 } 00298 //led2 = 1; 00299 } 00300 } 00301 00302 // GATT service and characteristic UUIDs 00303 const uint8_t nRF51ServiceUUID[UUID::LENGTH_OF_LONG_UUID] = { 00304 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00, 00305 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB 00306 }; 00307 const uint8_t nRF51ServiceUUIDreversed[UUID::LENGTH_OF_LONG_UUID] = { 00308 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 00309 0x00, 0x10, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00 00310 }; 00311 const UUID nRF51_GATT_SERVICE = UUID("00001101-0000-1000-8000-00805F9B34FB"); 00312 //const UUID nRF51_GATT_CHAR_BUTTON = UUID((uint8_t *)"nRF51-DK button "); 00313 const UUID nRF51_GATT_CHAR_LED = UUID("00001102-0000-1000-8000-00805F9B34FB"); 00314 00315 //#define CHARACTERISTIC_BUTTON 0 00316 #define CHARACTERISTIC_LED 0 00317 #define CHARACTERISTIC_COUNT 1 00318 00319 // our bluetooth smart objects 00320 GattService *gatt_service; 00321 GattCharacteristic *gatt_characteristics[CHARACTERISTIC_COUNT]; 00322 uint8_t gatt_char_value[CHARACTERISTIC_COUNT]; 00323 00324 /** 00325 Callback triggered when the ble initialization process has finished 00326 */ 00327 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00328 { 00329 BLE& ble = params->ble; 00330 ble_error_t error = params->error; 00331 00332 if (error != BLE_ERROR_NONE) { 00333 /* In case of error, forward the error handling to onBleInitError */ 00334 //onBleInitError(ble, error); 00335 return; 00336 } 00337 00338 /* Ensure that it is the default instance of BLE */ 00339 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00340 return; 00341 } 00342 00343 ble.gap().onDisconnection(disconnectionCallback); 00344 ble.gattServer().onDataWritten(onDataWrittenCallback); 00345 00346 // bool initialValueForLEDCharacteristic = false; 00347 00348 /* Setup primary service. */ 00349 //uartService = new UARTService(ble); 00350 00351 /* Setup advertising. */ 00352 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00353 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00354 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *)nRF51ServiceUUIDreversed, sizeof(nRF51ServiceUUIDreversed)); 00355 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00356 ble.gap().setAdvertisingInterval(100); /* 100ms. */ 00357 00358 // add our gatt service with two characteristics 00359 ble.addService(*gatt_service); 00360 00361 ble.gap().startAdvertising(); 00362 } 00363 00364 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 00365 BLE &ble = BLE::Instance(); 00366 // eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); 00367 led2 = !led2; 00368 } 00369 00370 void BUTTON () { 00371 if (!key1){ 00372 START = 0; 00373 } 00374 } 00375 00376 // Основной цикл 00377 int main(void) 00378 { 00379 DISP_LED = 0; // Инициализация дисплея 00380 tft.initR(INITR_144GREENTAB); 00381 //tft.invertDisplay(true); // Инвертирование цветов дисплея для корректного отображения цветов 00382 tft.fillScreen(ST7735_BLACK); // Заливка черным цветом 00383 tft.setTextColor(WHITE); // Установка цвета текста 00384 tft.setCursor(40, 48); 00385 tft.setTextSize(2); 00386 tft.printf("HPSP"); 00387 tft.setCursor(22, 64); 00388 tft.printf("BT-Lite"); 00389 wait(1); 00390 tft.setTextSize(1); 00391 tft.setCursor(2, 110); 00392 tft.printf("HPSP BT-Lite V:pre0.2"); 00393 tft.setCursor(2, 120); 00394 tft.printf("NOT FOR SALE"); 00395 wait(2); 00396 tft.fillScreen(ST7735_BLACK); 00397 tft.setTextSize(2); 00398 tft.setCursor(10, 57); 00399 tft.printf("Wait Data"); 00400 // tft.drawRect(100, 0, 20, 30, WHITE); 00401 00402 ticker.attach(periodicCallback, 0.8); /* Blink LED every 3 seconds */ 00403 00404 // create our button characteristic (read, notify) 00405 /*gatt_characteristics[CHARACTERISTIC_BUTTON] = 00406 new GattCharacteristic( 00407 nRF51_GATT_CHAR_BUTTON, 00408 &gatt_char_value[CHARACTERISTIC_BUTTON], 1, 1, 00409 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | 00410 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);*/ 00411 00412 // create our LED characteristic (read, write) 00413 gatt_characteristics[CHARACTERISTIC_LED] = 00414 new GattCharacteristic( 00415 nRF51ServiceUUID, 00416 &gatt_char_value[CHARACTERISTIC_LED], 1, 1, 00417 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | 00418 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | 00419 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | 00420 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY ); 00421 00422 // create our service, with both characteristics 00423 gatt_service = 00424 new GattService(nRF51_GATT_SERVICE, 00425 gatt_characteristics, CHARACTERISTIC_COUNT); 00426 00427 BLE &ble = BLE::Instance(); 00428 // ble.onEventsToProcess(scheduleBleEventsProcessing); 00429 ble.init(bleInitComplete); 00430 00431 /* SpinWait for initialization to complete. This is necessary because the 00432 BLE object is used in the main loop below. */ 00433 while (ble.hasInitialized() == false) 00434 { 00435 /* spin loop */ 00436 } 00437 00438 // Основной цикл 00439 while (true) 00440 { 00441 if ( !key1 || !key2) { 00442 DISP_LED = !DISP_LED; 00443 KEY_TIME.attach(BUTTON, 5); 00444 wait(0.2); 00445 00446 } 00447 00448 //BACKLIGTH.attach(&TFT_LED, 30); 00449 00450 // Проверка флага на старт программы и отоброжение таймера ( TODO вынести в отдельную функцию и обновлять по прерыванию ) 00451 if ( FLAG == 1 ) { 00452 00453 // переводим время в другой формат ЧЧ:ММ:СС 00454 HOUR = TIME_PROGRAMM / 60 / 60; 00455 MIN = (TIME_PROGRAMM / 60) % 60; 00456 SEC = TIME_PROGRAMM % 60; 00457 // Тут надо добавить конвертацию типов пока вижу это как разделение на десятки и еденицы и далее по формуле i + '0' записывать их в массив. 00458 // конвертацию то я сделал но как то не так. сыпет муссором на дисплей вида 00:0000:000000 и это в лучшем случае... 00459 // Часы 00460 HOUR_CHAR[0] = ((HOUR / 10) % 10) + '0'; 00461 HOUR_CHAR[1] = (HOUR % 10) + '0'; 00462 // Минуты 00463 MIN_CHAR[0] = ((MIN / 10) % 10) + '0'; 00464 MIN_CHAR[1] = (MIN % 10) + '0'; 00465 // Секунды 00466 SEC_CHAR[0] = ((SEC / 10) % 10) + '0'; 00467 SEC_CHAR[1] = (SEC % 10) + '0'; 00468 // Так как библиотека принимает только char пришлось посимвольно выводить время... 00469 tft.drawChar(52, 48, HOUR_CHAR[0], WHITE, BLACK, 2); 00470 tft.drawChar(64, 48, HOUR_CHAR[1], WHITE, BLACK, 2); 00471 tft.drawChar(52, 64, MIN_CHAR[0], WHITE, BLACK, 2); 00472 tft.drawChar(64, 64, MIN_CHAR[1], WHITE, BLACK, 2); 00473 00474 if (r >= 30) { 00475 r = 20; 00476 if (COLOR == WHITE) { 00477 COLOR = BLACK; 00478 } 00479 else (COLOR = WHITE); 00480 }; 00481 00482 tft.drawCircle(63, 62, r, COLOR); 00483 if (TIME_PROGRAMM < 1) { 00484 FLAG = 0; 00485 } 00486 } 00487 00488 else { 00489 ble.waitForEvent(); 00490 00491 } 00492 } 00493 }
Generated on Mon Jul 25 2022 17:19:13 by
1.7.2