diff --git a/examples/HandyTalkie_nRF52840/HandyTalkie_nRF52840.ino b/examples/HandyTalkie_nRF52840/HandyTalkie_nRF52840.ino new file mode 100644 index 0000000..19a63fb --- /dev/null +++ b/examples/HandyTalkie_nRF52840/HandyTalkie_nRF52840.ino @@ -0,0 +1,282 @@ +/* Hamshield + * Example: HandyTalkie_nRF52840 + * This is a simple example to demonstrate the HamShield working + * with an Adafruit Feather nRF52840 Express + * + * HamShield to Feather Connections: + * SPKR - Feather A0 + * MIC - Feather D11 + * CLK - Feather D5 + * nCS - Feather D6 + * DAT - Feather D9 + * GND - Feather GND + * VCC - Feather 3.3V + * + * Connect the HamShield to your Feather as above. + * Screw the antenna into the HamShield RF jack. Plug a pair + * of headphones into the HamShield. + * + * Connect the Feather nRF52840 Express to your computer via + * a USB Micro B cable. After uploading this program to + * your Feather, open the Serial Monitor. You should see some + * text displayed that documents the setup process. + * + * Once the Feather is set up and talking to the HamShield, + * you can control it over USB-Serial or BLE-Serial(UART). + * + * Try using Adafruit's Bluefruit app to connect to the Feather. + * Once you're connected, you can control the HamShield using + * the same commands you'd use over USB-Serial. The response to + * all commands will be echoed to both USB-Serial and BLE-Serial(UART). + * + * Serial UART commands: + * t - change from Tx to Rx (or vice versa) + * F123400 - set frequency to 123400 kHz +*/ + +#include + +// BLE Service +BLEDis bledis; // device information +BLEUart bleuart; // uart over ble +BLEBas blebas; // battery + +#include +// create object for radio +HamShield radio(9,5,6); +// To use non-standard pins, use the following initialization +//HamShield radio(ncs_pin, clk_pin, dat_pin); + +#define LED_PIN 3 +#define RSSI_REPORT_RATE_MS 5000 + +#define MIC_PIN A1 + +bool blinkState = false; +bool currently_tx; + +uint32_t freq; + +unsigned long rssi_timeout; + +void setup() { + + // NOTE: if not using PWM out, it should be held low to avoid tx noise + pinMode(MIC_PIN, OUTPUT); + digitalWrite(MIC_PIN, LOW); + + // initialize serial communication + Serial.begin(115200); + while (!Serial) delay(10); + Serial.println("Setting up BLE"); + + // Setup the BLE LED to be enabled on CONNECT + // Note: This is actually the default behaviour, but provided + // here in case you want to control this LED manually via PIN 19 + Bluefruit.autoConnLed(true); + + // Config the peripheral connection with maximum bandwidth + // more SRAM required by SoftDevice + // Note: All config***() function must be called before begin() + Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); + + Bluefruit.begin(); + // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 + Bluefruit.setTxPower(4); + Bluefruit.setName("MyBlueHam"); + //Bluefruit.setName(getMcuUniqueID()); // useful testing with multiple central connections + Bluefruit.setConnectCallback(connect_callback); + Bluefruit.setDisconnectCallback(disconnect_callback); + + // Configure and Start Device Information Service + bledis.setManufacturer("Enhanced Radio Devices"); + bledis.setModel("BlueHam"); + bledis.begin(); + + // Configure and Start BLE Uart Service + bleuart.begin(); + + // Start BLE Battery Service + blebas.begin(); + blebas.write(100); + + // Set up and start advertising + startAdv(); + + delay(100); + + Serial.println("beginning Ham radio setup"); + + // verify connection + Serial.println("Testing device connections..."); + if (radio.testConnection()) { + Serial.println("HamShield connection successful"); + } else { + Serial.print("HamShield connection failed"); + while(1) delay(100); + } + + // initialize device + Serial.println("Initializing I2C devices..."); + radio.initialize(); // initializes automatically for UHF 12.5kHz channel + + Serial.println("setting default Radio configuration"); + + // set frequency + Serial.println("changing frequency"); + + radio.setSQOff(); + freq = 446000; + radio.frequency(freq); + + // set to receive + + radio.setModeReceive(); + currently_tx = false; + Serial.print("config register is: "); + Serial.println(radio.readCtlReg()); + Serial.println(radio.readRSSI()); + +/* + // set to transmit + radio.setModeTransmit(); + // maybe set PA bias voltage + Serial.println("configured for transmit"); + radio.setTxSourceMic(); + + + */ + radio.setRfPower(0); + + // configure Arduino LED for + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + rssi_timeout = 0; + +} + +void startAdv(void) +{ + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + + // Include bleuart 128-bit uuid + Bluefruit.Advertising.addService(bleuart); + + // Secondary Scan Response packet (optional) + // Since there is no room for 'Name' in Advertising packet + Bluefruit.ScanResponse.addName(); + + /* Start Advertising + * - Enable auto advertising if disconnected + * - Interval: fast mode = 20 ms, slow mode = 152.5 ms + * - Timeout for fast mode is 30 seconds + * - Start(timeout) with timeout = 0 will advertise forever (until connected) + * + * For recommended advertising interval + * https://developer.apple.com/library/content/qa/qa1931/_index.html + */ + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds +} + +#define TEXT_BUF_LEN 64 +char text_buf[TEXT_BUF_LEN]; +void loop() { + + char c = 0; + bool ble_serial = false; + if (Serial.available()) { + Serial.readBytes(&c, 1); + } else if (bleuart.available()) { + c = (char) bleuart.read(); + ble_serial = true; + } + + if (c != 0) { + if (c == 't') + { + if (!currently_tx) + { + currently_tx = true; + + // set to transmit + radio.setModeTransmit(); + + Serial.println("Tx"); + int str_len = snprintf(text_buf, TEXT_BUF_LEN, "Tx\n"); + bleuart.write(text_buf, str_len); + //radio.setTxSourceMic(); + //radio.setRfPower(1); + } else { + radio.setModeReceive(); + currently_tx = false; + Serial.println("Rx"); + int str_len = snprintf(text_buf, TEXT_BUF_LEN, "Rx\n"); + bleuart.write(text_buf, str_len); + } + } else if (c == 'F') { + if (ble_serial == false) { + Serial.setTimeout(40); + freq = Serial.parseInt(); + Serial.flush(); + } else { + int idx = 0; + while (bleuart.available() && + bleuart.peek() >= '0' && + bleuart.peek() <= '9' && + idx < TEXT_BUF_LEN) { + + text_buf[idx] = bleuart.read(); + idx++; + } + text_buf[idx] = 0; // null terminate + freq = atoi(text_buf); + } + radio.frequency(freq); + Serial.print("set frequency: "); + Serial.println(freq); + int str_len = snprintf(text_buf, TEXT_BUF_LEN, "set frequency: %d\n", freq); + bleuart.write(text_buf, str_len); + + } + } + + if (!currently_tx && (millis() - rssi_timeout) > RSSI_REPORT_RATE_MS) + { + int rssi = radio.readRSSI(); + Serial.println(rssi); + int str_len = snprintf(text_buf, TEXT_BUF_LEN, "rssi: %d\n", rssi); + bleuart.write(text_buf, str_len); + rssi_timeout = millis(); + } +} + + +// callback invoked when central connects +void connect_callback(uint16_t conn_handle) +{ + char central_name[32] = { 0 }; + Bluefruit.Gap.getPeerName(conn_handle, central_name, sizeof(central_name)); + + Serial.print("Connected to "); + Serial.println(central_name); +} + +/** + * Callback invoked when a connection is dropped + * @param conn_handle connection where this event happens + * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h + * https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include/ble_hci.h + */ +void disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void) conn_handle; + (void) reason; + + Serial.println(); + Serial.println("Disconnected"); +}