
htr
Dependencies: mbed AdafruitST7735 BLE_API Adafruit_GFX nRF51822
main.cpp
- Committer:
- tekasijimo
- Date:
- 2019-08-11
- Revision:
- 19:02bb67cb303c
- Parent:
- 18:0cbeb28ce4f6
File content as of revision 19:02bb67cb303c:
#include "mbed.h" #include "ble/BLE.h" #include "Adafruit_GFX/Adafruit_GFX.h" #include "AdafruitST7735/Adafruit_ST7735.h" // Конфигурация BLE const static uint16_t SERVICE_UUID = 0xA000; const static char DEVICE_NAME[] = "HPSP BT-Lite"; // Настройка выводов DigitalOut led1(P0_21); DigitalOut DISP_LED (P0_16); DigitalIn key1 (P0_8); DigitalIn key2 (P0_17); DigitalOut OSC (P0_6); #define TFT_MISO P0_4 // NC(NC) //Не подключен так как отсутсвует на дисплее #define TFT_RST P0_9 // RST(5) #define TFT_DC P0_10 // D/C(6) // не работает на 10 #define TFT_MOSI P0_11 // DIN(7) #define TFT_SCK P0_12 // CLK(8) #define TFT_SS P0_13 // CS(11) // Adafruit_ST7735 tft(TFT_MOSI, TFT_MISO, TFT_SCK, TFT_SS, TFT_DC, TFT_RST); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST // Назначение цветов #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF int COLOR = WHITE; Timeout KEY_TIME; // Счетчик для таймера работы программы short FLAG = 0; // Флаг старта программы unsigned int HOUR = 0; // Часы unsigned int MIN = 0; // Минуты unsigned int SEC = 0; // Секунды unsigned int TIME_PROGRAMM = 5400; // Время работы программы int START = 0; // Переменные типа char для дисплея char HOUR_CHAR[2] = {'0', '0'}; char MIN_CHAR[2] = {'0', '0'}; char SEC_CHAR[2] = {'0', '0'}; int r = 20; //static UARTService* uartService; //static EventQueue eventQueue( // /* event count */ 16 * /* event size */ 32 //); Ticker ticker; char freq_storage[900] = {0}; //резервируем блок памяти в EEPROM для хранения частот char timer_storage[100] = {0}; //резервируем блок памяти в EEPROM для хранения таймеров char* freq_storage_pos = freq_storage; char* timer_storage_pos = timer_storage; void generate() { char* freq_storage_pos = freq_storage; unsigned short freq; unsigned short duration = 180; // длительность memcpy( &freq, freq_storage_pos, sizeof(freq) ); freq_storage_pos += sizeof(freq); while ( freq != 0 ) { memcpy( &duration, freq_storage_pos, sizeof(duration) ); freq_storage_pos += sizeof(duration); // распаковываем частоту float real_freq; if ( freq <= 1000 ) { real_freq = (float)freq / 100; } else if ( freq <= 11000 ) { real_freq = (float)(freq - 1000) / 10; } else { real_freq = freq - 10000; } float real_duration = (float)duration * 1000; OSC = 1; wait_ms(real_duration); OSC = 0; /* digitalWrite(led, HIGH); tone(ant, real_freq); customDelay(real_duration); noTone(ant); digitalWrite(led, LOW); */ memcpy( &freq, freq_storage_pos, sizeof(freq) ); freq_storage_pos += sizeof(freq); } } int frequencies_scan_mode = 1; int parse_bt_data( char *buffer // буфер, в котором уже лежат принятые данные в виде стандартной C строки ) { if ( buffer == NULL) // проверяем корректность входных данных { return 0; } // вспомогательные переменные char *current = buffer; // указатель на текущий символ // сканируем частоты while ( frequencies_scan_mode != 0 && *current != 0 ) { if ( *current == ':' ) { break; // выходим, так как частоты закончились } unsigned long freq; // частота в сотых долях герца unsigned long duration; // длительность в секундах char separator[2]; // разделитель int symbols_read; int values_read = sscanf( current, "%ld %ld%1[,:]%n", &freq, &duration, separator, &symbols_read); // считываем частоту и длительность if ( values_read != 3 ) { // закончился буффер // копируем оставшиеся данные в начало буффера int rest_len = strlen( current ); // длина остатка в буффере memmove( buffer, current, rest_len ); return rest_len; } // кодируем частоту для умещения в память unsigned short packed_freq; if ( freq <= 10 * 100 ) // 10Гц { packed_freq = freq; } else if ( freq <= 1000 * 100 ) // 1кГц { packed_freq = 1000 + freq / 10; } else { packed_freq = 10000 + freq / 100; } // сохраняем данные в EEPROM memcpy( freq_storage_pos, &packed_freq, sizeof(packed_freq) ); freq_storage_pos += sizeof(packed_freq); memcpy( freq_storage_pos, &duration, sizeof(duration) ); freq_storage_pos += sizeof(duration); // моргаем после каждых данных //led2 = !led2; current += symbols_read; //переходим к следующей паре if ( *separator == ':' ) { // пишем признак конца данных unsigned short end = 0; memcpy( freq_storage_pos, &end, sizeof(end) ); frequencies_scan_mode = 0; // загрузка частот завершена break; } } // сканируем таймеры while ( *current != 0 ) { if ( *current == '.' ) { break; // выходим, так как таймеры закончились } unsigned int timer_start; int symbols_read; char separator[2]; //разделитель int values_read = sscanf( current, "%d%1[,.]%n", &timer_start, separator, &symbols_read); //считываем время до запуска таймера if ( values_read != 2 ) { // закончился буффер // копируем оставшиеся данные в начало буффера int rest_len = strlen( current ); // длина остатка в буффере memmove( buffer, current, rest_len ); return rest_len; } // сохраняем данные в EEPROM //eeprom_write_block( timer_start, timer_storage_pos, sizeof(timer_start) ); //timer_storage_pos += sizeof(timer_start); current += symbols_read; //переходим к следующей паре if ( *separator == '.' ) { // пишем признак конца данных unsigned short end = 0; memcpy( timer_storage_pos, &end, sizeof(end) ); break; // конец данных } } return 0; } void updateSensorValue() { } void periodicCallback(void) { OSC = !OSC; /* Do blinky on LED1 to indicate system aliveness. */ TIME_PROGRAMM--; r = r + 2; if (r >= 60){ r = 30; if(COLOR == WHITE){ COLOR = BLACK; } else (COLOR = WHITE); }; if (BLE::Instance().getGapState().connected) { // eventQueue.call(updateSensorValue); } } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { tft.fillScreen(ST7735_BLACK); FLAG = 1; r= 30; } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { BLE::Instance().gap().startAdvertising(); tft.fillScreen(ST7735_BLACK); FLAG = 1; r= 30; } #define INPUT_BUFFER_SIZE 50 char buffer[INPUT_BUFFER_SIZE + 1]; //приемный буффер static int config_complete = 0; void onDataWrittenCallback(const GattWriteCallbackParams *params) { if ( params != NULL ) { //led2 = 0; unsigned int buffer_pos = 0; //текущая позиция в буффере //если есть данные - читаем while ( buffer_pos < params->len ) { //загоняем прочитанное в буфер char symbol = params->data[buffer_pos++]; buffer[buffer_pos] = symbol; if ( symbol == '.') { buffer[buffer_pos] = 0; // закрываем строку parse_bt_data(buffer); // обрабатываем полученный кусок данных // конец данных, прекращаем чтение // данные получены, надо выставить флаг и больше из BT не читать config_complete = 1; break; } if ( buffer_pos == INPUT_BUFFER_SIZE ) { buffer[INPUT_BUFFER_SIZE] = 0; //символ конца строки для полностью заполненного буффера buffer_pos = parse_bt_data(buffer); // обрабатываем полученный кусок данных } } //led2 = 1; } } // GATT service and characteristic UUIDs const uint8_t nRF51ServiceUUID[UUID::LENGTH_OF_LONG_UUID] = { 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; const uint8_t nRF51ServiceUUIDreversed[UUID::LENGTH_OF_LONG_UUID] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00 }; const UUID nRF51_GATT_SERVICE = UUID("00001101-0000-1000-8000-00805F9B34FB"); //const UUID nRF51_GATT_CHAR_BUTTON = UUID((uint8_t *)"nRF51-DK button "); const UUID nRF51_GATT_CHAR_LED = UUID("00001102-0000-1000-8000-00805F9B34FB"); //#define CHARACTERISTIC_BUTTON 0 #define CHARACTERISTIC_LED 0 #define CHARACTERISTIC_COUNT 1 // our bluetooth smart objects GattService *gatt_service; GattCharacteristic *gatt_characteristics[CHARACTERISTIC_COUNT]; uint8_t gatt_char_value[CHARACTERISTIC_COUNT]; /** Callback triggered when the ble initialization process has finished */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ //onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); ble.gattServer().onDataWritten(onDataWrittenCallback); // bool initialValueForLEDCharacteristic = false; /* Setup primary service. */ //uartService = new UARTService(ble); /* Setup advertising. */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *)nRF51ServiceUUIDreversed, sizeof(nRF51ServiceUUIDreversed)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(100); /* 100ms. */ // add our gatt service with two characteristics ble.addService(*gatt_service); ble.gap().startAdvertising(); } void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { BLE &ble = BLE::Instance(); // eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); led2 = !led2; } void BUTTON () { if (!key1){ START = 0; } } // Основной цикл int main(void) { DISP_LED = 0; // Инициализация дисплея tft.initR(INITR_144GREENTAB); //tft.invertDisplay(true); // Инвертирование цветов дисплея для корректного отображения цветов tft.fillScreen(ST7735_BLACK); // Заливка черным цветом tft.setTextColor(WHITE); // Установка цвета текста tft.setCursor(40, 48); tft.setTextSize(2); tft.printf("HPSP"); tft.setCursor(22, 64); tft.printf("BT-Lite"); wait(1); tft.setTextSize(1); tft.setCursor(2, 110); tft.printf("HPSP BT-Lite V:pre0.2"); tft.setCursor(2, 120); tft.printf("NOT FOR SALE"); wait(2); tft.fillScreen(ST7735_BLACK); tft.setTextSize(2); tft.setCursor(10, 57); tft.printf("Wait Data"); // tft.drawRect(100, 0, 20, 30, WHITE); ticker.attach(periodicCallback, 0.8); /* Blink LED every 3 seconds */ // create our button characteristic (read, notify) /*gatt_characteristics[CHARACTERISTIC_BUTTON] = new GattCharacteristic( nRF51_GATT_CHAR_BUTTON, &gatt_char_value[CHARACTERISTIC_BUTTON], 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);*/ // create our LED characteristic (read, write) gatt_characteristics[CHARACTERISTIC_LED] = new GattCharacteristic( nRF51ServiceUUID, &gatt_char_value[CHARACTERISTIC_LED], 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY ); // create our service, with both characteristics gatt_service = new GattService(nRF51_GATT_SERVICE, gatt_characteristics, CHARACTERISTIC_COUNT); BLE &ble = BLE::Instance(); // ble.onEventsToProcess(scheduleBleEventsProcessing); ble.init(bleInitComplete); /* SpinWait for initialization to complete. This is necessary because the BLE object is used in the main loop below. */ while (ble.hasInitialized() == false) { /* spin loop */ } // Основной цикл while (true) { if ( !key1 || !key2) { DISP_LED = !DISP_LED; KEY_TIME.attach(BUTTON, 5); wait(0.2); } //BACKLIGTH.attach(&TFT_LED, 30); // Проверка флага на старт программы и отоброжение таймера ( TODO вынести в отдельную функцию и обновлять по прерыванию ) if ( FLAG == 1 ) { // переводим время в другой формат ЧЧ:ММ:СС HOUR = TIME_PROGRAMM / 60 / 60; MIN = (TIME_PROGRAMM / 60) % 60; SEC = TIME_PROGRAMM % 60; // Тут надо добавить конвертацию типов пока вижу это как разделение на десятки и еденицы и далее по формуле i + '0' записывать их в массив. // конвертацию то я сделал но как то не так. сыпет муссором на дисплей вида 00:0000:000000 и это в лучшем случае... // Часы HOUR_CHAR[0] = ((HOUR / 10) % 10) + '0'; HOUR_CHAR[1] = (HOUR % 10) + '0'; // Минуты MIN_CHAR[0] = ((MIN / 10) % 10) + '0'; MIN_CHAR[1] = (MIN % 10) + '0'; // Секунды SEC_CHAR[0] = ((SEC / 10) % 10) + '0'; SEC_CHAR[1] = (SEC % 10) + '0'; // Так как библиотека принимает только char пришлось посимвольно выводить время... tft.drawChar(52, 48, HOUR_CHAR[0], WHITE, BLACK, 2); tft.drawChar(64, 48, HOUR_CHAR[1], WHITE, BLACK, 2); tft.drawChar(52, 64, MIN_CHAR[0], WHITE, BLACK, 2); tft.drawChar(64, 64, MIN_CHAR[1], WHITE, BLACK, 2); if (r >= 30) { r = 20; if (COLOR == WHITE) { COLOR = BLACK; } else (COLOR = WHITE); }; tft.drawCircle(63, 62, r, COLOR); if (TIME_PROGRAMM < 1) { FLAG = 0; } } else { ble.waitForEvent(); } } }