!Wireless Motor Monitoring CC2650 Radio Protocol !Edited by M. Raleigh !10/27/2014 !Notes ! ! PRINT PRINT "This is a console program to rx/tx data from the WMMU via the CC2650 BLE Radio." PRINT PRINT "Press the Stop button to stop this program." PRINT connected = 0 System.showConsole DIM zTemp AS INTEGER zTemp = 1 DIM modecode AS INTEGER modecode = 93 DIM firstvalue AS INTEGER firstvalue = 15000 DIM RXData AS INTEGER RXData = 66 DIM commandsAllowed AS INTEGER, commandTime AS DOUBLE, delay AS DOUBLE delay = .5 ! Set up variables to hold the peripheral and the characteristics DIM WMMURadio AS BLEPeripheral ! Create the plots and arrays to hold the plot points. DIM p as Plot, px as PlotPoint DIM zDataBuff(400, 2) ! Create the controls. DIM quit AS Button, send AS Button, samples AS Button, fourier AS Button, nextKHz AS Button, nextKHz2 AS Button, nextKHz3 AS Button, nextKHz4 AS Button ! Create and initialize the global tracking variables. fileName$ = "wmmu_data.txt" !Init GUI !setUpGUI ! We will look for these services. DIM servicesHeader AS STRING, services(1) AS STRING servicesHeader = "-0451-4000-B000-000000000000" services(1) = "FFF0" accel% = 1 ! Start the BLE service and begin scanning for devices. debug = 0 BLE.startBLE DIM uuid(0) AS STRING BLE.startScan(uuid) ! Called when a peripheral is found. If it is a WMMU, we ! initiate a connection to it and stop scanning for peripherals. ! ! Parameters: ! time - The time when the peripheral was discovered. ! peripheral - The peripheral that was discovered. ! services - List of services offered by the device. ! advertisements - Advertisements (information provided by the ! device without the need to read a service/characteristic) ! rssi - Received Signal Strength Indicator ! SUB BLEDiscoveredPeripheral (time AS DOUBLE, _ peripheral AS BLEPeripheral, _ services() AS STRING, _ advertisements(,) AS STRING, _ rssi) IF peripheral.bleName = "SimpleBLEPeripheral" THEN WMMURadio = peripheral BLE.connect(WMMURadio) BLE.stopScan END IF IF peripheral.bleName = "Simple BLE Peripheral" THEN WMMURadio = peripheral BLE.connect(WMMURadio) BLE.stopScan END IF END SUB ! Called to report information about the connection status of the ! peripheral or to report that services have been discovered. ! ! Parameters: ! time - The time when the information was received. ! peripheral - The peripheral. ! kind - The kind of call. One of ! 1 - Connection completed ! 2 - Connection failed ! 3 - Connection lost ! 4 - Services discovered ! message - For errors, a human-readable error message. ! err - If there was an error, the Apple error number. If there ! was no error, this value is 0. ! SUB BLEPeripheralInfo (time AS DOUBLE, _ peripheral AS BLEPeripheral, _ kind AS INTEGER, _ message AS STRING, _ err AS LONG) IF kind = 1 THEN ! The connection was established. Look for available services. IF debug THEN PRINT "Connection made." peripheral.discoverServices(uuid) ELSE IF kind = 2 OR kind = 3 THEN IF debug THEN PRINT "Connection lost: "; kind BLE.connect(WMMURadio) ELSE IF kind = 4 THEN ! Services were found. If it is one of the ones we are interested ! in, begin discovery of its characteristics. DIM availableServices(1) AS BLEService availableServices = peripheral.services FOR s = 1 to UBOUND(services, 1) FOR a = 1 TO UBOUND(availableServices, 1) print availableServices(a).uuid IF services(s) = availableServices(a).uuid THEN IF debug THEN PRINT "Discovering characteristics for "; services(s) peripheral.discoverCharacteristics(uuid, availableServices(a)) END IF NEXT NEXT END IF END SUB ! Called to report information about a characteristic or included ! services for a service. If it is one we are interested in, start ! handling it. ! ! Parameters: ! time - The time when the information was received. ! peripheral - The peripheral. ! service - The service whose characteristic or included ! service was found. ! kind - The kind of call. One of ! 1 - Characteristics found ! 2 - Included services found ! message - For errors, a human-readable error message. ! err - If there was an error, the Apple error number. If there ! was no error, this value is 0. ! SUB BLEServiceInfo (time AS DOUBLE, _ peripheral AS BLEPeripheral, _ service AS BLEService, _ kind AS INTEGER, _ message AS STRING, _ err AS LONG) IF kind = 1 THEN ! Get the characteristics. DIM characteristics(1) AS BLECharacteristic characteristics = service.characteristics FOR i = 1 TO UBOUND(characteristics, 1) IF service.uuid = services(accel%) THEN ! Found the accelerometer. print characteristics(i).uuid SELECT CASE characteristics(i).uuid CASE "FFF1" ! Tell the CC2650 to begin sending data. IF debug THEN PRINT "Write Command" DIM value(1) as INTEGER value(1) = modecode peripheral.writeCharacteristic(characteristics(i), value, 1) connected=1 !peripheral.setNotify(characteristics(i), 1) peripheral.readCharacteristic(characteristics(i)) CASE "FFF5" !Used to recieve the actual wmmu fft data IF debug THEN PRINT "RXing FFT Data" DIM RXData(1) as INTEGER !peripheral.setNotify(characteristics(i), 1) peripheral.readCharacteristic(characteristics(i)) CASE "F000AA12" & servicesHeader ! Turn the accelerometer sensor on. IF debug THEN PRINT "Accelerometer on." DIM value(1) as INTEGER value(1) = 1 peripheral.writeCharacteristic(characteristics(i), value, 1) CASE "F000AA13" & servicesHeader ! Set the sample rate to 500ms. DIM value(1) as INTEGER value(1) = 50 IF debug THEN PRINT "Setting accelerometer sample rate to "; value(1) peripheral.writeCharacteristic(characteristics(i), value, 1) END SELECT END IF NEXT END IF END SUB ! Called to return information from a characteristic. ! ! Parameters: ! time - The time when the information was received. ! peripheral - The peripheral. ! characteristic - The characteristic whose information ! changed. ! kind - The kind of call. One of ! 1 - Called after a discoverDescriptors call. ! 2 - Called after a readCharacteristics call. ! 3 - Called to report status after a writeCharacteristics ! call. ! message - For errors, a human-readable error message. ! err - If there was an error, the Apple error number. If there ! was no error, this value is 0. ! SUB BLECharacteristicInfo (time AS DOUBLE, _ peripheral AS BLEPeripheral, _ characteristic AS BLECharacteristic, _ kind AS INTEGER, _ message AS STRING, _ err AS LONG) IF kind = 2 THEN DIM value(1) AS INTEGER value = characteristic.value !input line$ SELECT CASE characteristic.uuid CASE "FFF1" ! Update the accelerometer. ! IF value(1) = 94 THEN ! value(1) = 93 ! ELSE ! value(1) = 94 ! print value(1) ! print RXData ! END IF value(1) = modecode peripheral.writeCharacteristic(characteristic, value, 1) peripheral.readCharacteristic(characteristic) !delay = 0.2 CASE "FFF5" ! RX FFT Data print value(1) !print RXData IF zTemp < 400 THEN IF value(1) = 0 THEN zTemp = 1 END IF IF abs(firstvalue - value(1)) > 0 THEN print value(2) firstvalue=value(1) value(1)=value(2) FOR x = 1 TO 20 !print value(x) zDataBuff(zTemp, 2) = value(x) zTemp = zTemp + 1 NEXT END IF ELSE setUpGUI zTemp = 1 END IF peripheral.readCharacteristic(characteristic) END SELECT ELSE IF kind = 3 AND err <> 0 THEN PRINT "Error writing "; characteristic.uuid; ": ("; err; ") "; message END IF END SUB !SUB nullEvent (time AS DOUBLE) ! IF connected = 1 THEN ! DIM characteristics(1) AS BLECharacteristic ! characteristics = WMMURadio.characteristics(1) ! FOR i = 1 TO UBOUND(characteristics, 1) ! ! Found the accelerometer. ! IF chacteristics(i).uuid = "FFF1" THEN ! WMMURadio.readCharacteristic(characteristics(i)) ! END IF ! NEXT ! END IF !END SUB ! Send the last recorded data file to an email. SUB sendData DIM e AS eMail e = System.newEMail IF e.canSendMail THEN e.setSubject("Accelerometer data") e.setMessage("Accelerometer data") e.addAttachment(fileName$, "text/plain") e.send ELSE button = Graphics.showAlert("Can't Send", _ "Email cannot be sent from this device.") END IF END SUB ! Creates a new button with a gradient fill. ! ! Parameters: ! x - Horizontal location. ! y - Vertical location. ! title - Name of the button. ! ! Returns: The new button. FUNCTION newButton (x, y, title AS STRING) AS Button DIM b AS Button b = Graphics.newButton(x, y) b.setTitle(title) b.setBackgroundColor(1, 1, 1) b.setGradientColor(0.6, 0.6, 0.6) newButton = b END FUNCTION ! Set up the user interface. SUB setUpGUI ! Tell the accelerometer to update once every 0.05 seconds. sensors.setAccelRate(0.05) ! Initialize the plot arrays. FOR t = 1 TO 400 zDataBuff(t, 1) = t NEXT ! Initialize the plot and show it. p = Graphics.newPlot p.setTitle("WMMU GRAPH DATA") p.setXAxisLabel("Sample Number (X 2.4 = Hertz)") p.setYAxisLabel("Magnitude") p.showGrid(1) p.setGridColor(0.8, 0.8, 0.8) p.setAllowedGestures($0042) px = p.newPlot(zDataBuff) px.setColor(0, 1, 0) px.setPointColor(0, 1, 0) ! Set the plot range and domain. This must be done ! after adding the first PlotPoint, since that also ! sets the range and domain. p.setView(0, -1, 400, 256, 0) ! Show the graphics screen. Pass 1 as the parameter ! for full-screen mode. system.showGraphics(1) ! Lock the screen in the current orientation. orientation = 1 << (System.orientation - 1) System.setAllowedOrientations(orientation) ! Set the plot size. p.setRect(0, 0, Graphics.width, Graphics.height - 47) ! Draw the background. Graphics.setPixelGraphics(0) Graphics.setColor(0.886, 0.886, 0.886) Graphics.fillRect(0, 0, Graphics.width, Graphics.height) ! Set up the user interface. h = Graphics.height - 47 quit = newButton(Graphics.width - 82, h, "Quit") send = newButton(Graphics.width - 266, h, "Send") samples = newButton(Graphics.width - 466, h, "Samples") fourier = newButton(Graphics.width - 566, h, "FFT(0-1KHz") nextKHz = newButton(Graphics.width - 666, h, "FFT(1-2KHz)") nextKHz2 = newButton(Graphics.width - 766, h, "FFT(2-3KHz)") nextKHz3 = newButton(Graphics.width - 866, h, "FFT(3-4KHz)") nextKHz4 = newButton(Graphics.width - 966, h, "FFT(4-5KHz)") ! If there is nothing to send, disable the Send button. IF NOT EXISTS(fileName$) THEN send.setEnabled(0) END IF END SUB ! Handle a tap on one of the buttons. ! ! Parameters: ! ctrl - The button that was tapped. ! time - The time when the event occurred. SUB touchUpInside (ctrl AS Button, time AS DOUBLE) IF ctrl = quit THEN STOP ELSE IF ctrl = send THEN sendData ELSE IF ctrl = samples THEN modecode = 93 ELSE IF ctrl = fourier THEN modecode = 94 ELSE IF ctrl = nextKHz THEN modecode = 92 ELSE IF ctrl = nextKHz2 THEN modecode = 91 ELSE IF ctrl = nextKHz3 THEN modecode = 90 ELSE IF ctrl = nextKHz4 THEN modecode = 89 END IF END SUB