2650 tag IO service for led and buzzer

Discuss mobile apps for Texas Instruments products.
lb96
Posts: 18
Joined: 11:32, 06 Jul 2015

2650 tag IO service for led and buzzer

Postby lb96 » 09:44, 10 Aug 2015

Hi

Is it possible to activate the buzzer and LEDs on the 2650 SensorTag. I've looked through this forum and the code and can't see anything that looks like this is currently supported.

Regards
LB

Fredrik
Site Admin
Posts: 196
Joined: 15:00, 18 Nov 2013

Re: 2650 tag IO service for led and buzzer

Postby Fredrik » 09:36, 11 Aug 2015

Our "tisensortag" library doesn't have any functions to access the LED/buzzer service, but it ought to be possible to do it directly. A good starting point might be our example "ti-sensortag-cc2650-demo", which doesn't use the library but instead talks to the tag via "easyble".

This file and this page describe all the available BLE services on the CC2650 SensorTag.

The buzzer has service ID AA64, data ID AA65 and config ID AA66.

So to turn on the buzzer, I might write something like this:

Code: Select all

// Config: remote mode.
device.writeCharacteristic('f000aa66-0451-4000-b000-000000000000', new Uint8Array([1]), function() {
  // Data: buzzer on.
  device.writeCharacteristic('f000aa65-0451-4000-b000-000000000000', new Uint8Array([4]), function() {
    console.log("success");
  }, fail);
}, fail);

This code is not tested at all. Use at your own risk.

lb96
Posts: 18
Joined: 11:32, 06 Jul 2015

Re: 2650 tag IO service for led and buzzer

Postby lb96 » 16:14, 11 Aug 2015

Thanks for the reply I'll check it out.

Regards
LB

lb96
Posts: 18
Joined: 11:32, 06 Jul 2015

Re: 2650 tag IO service for led and buzzer

Postby lb96 » 12:52, 21 Oct 2015

Hi

Just started looking at this again and I can get the buzzer working however I'm somewhat confused as to how to get the LEDs running.

The documentation says:

Power on Self Test
Bit Number Description
0 Red LED (LED1)
1 Green LED (LED2)
2 Buzzer

The code to activate the buzzer is:

device.writeCharacteristic('f000aa66-0451-4000-b000-000000000000', new Uint8Array([1]), function() {
// Data: buzzer on.
device.writeCharacteristic('f000aa65-0451-4000-b000-000000000000', new Uint8Array([4]), function() {
console.log("buzzer on success");
}, app.buzzerFail() );
}, app.buzzerFail() );

What i don't understand is what is the value Uint8Array([4]) doing when the docs say the value for the buzzer is 2. What values do I need to get the red and green LEDs to light up?

Regards
LB

lb96
Posts: 18
Joined: 11:32, 06 Jul 2015

Re: 2650 tag IO service for led and buzzer

Postby lb96 » 13:22, 21 Oct 2015

Hi

Worked it out:

The Uint8Array values are as such:

1 = red
2 = green
3 = red + green
4 = buzzer
5 = red + buzzer
6 = green + buzzer
7 = all

Fredrik
Site Admin
Posts: 196
Joined: 15:00, 18 Nov 2013

Re: 2650 tag IO service for led and buzzer

Postby Fredrik » 13:22, 21 Oct 2015

The buzzer/led value is a bitfield. One can use the bitwise OR operator ( | ) to combine bits.

Values are determined by the formula (1 << bit).

The first bit, bit 0, has the value 1 and controls the red LED. The second bit, bit 1, has value 2 and controls the green LED. The third bit, bit 2, has value 4 and controls the buzzer.

That is how value 4 turns on the buzzer. Similarly, value 1 should turn off the buzzer and the green LED and turn on the red LED. Value 7 (1 | 2 | 4) should turn on all three devices. Value 0 should turn them off.

rc54
Posts: 2
Joined: 20:31, 29 Oct 2015

Re: 2650 tag IO service for led and buzzer

Postby rc54 » 20:51, 29 Oct 2015

Newby here, possible embarrassing question.

Am also trying to get the buzzer/leds functioning. Have tried the code presented by lb96 in all manner of ways both in the workbench and in the sample app "ti-sensortag-cc2650-demo"....within a function etc. etc. and after the initialization routines. No luck. Am familiar with reading from the Sensortag........but not writing. Any simple ideas. Thanks in advance for your reply......

lb96
Posts: 18
Joined: 11:32, 06 Jul 2015

Re: 2650 tag IO service for led and buzzer

Postby lb96 » 15:01, 09 Nov 2015

Hi

I'm no expert with this stuff however I modified the code in app.js from the TI SensorTag CC2650 Demo. I don't use the workbench and compile stuff using Cordova.

Hope this helps.

Code: Select all

// JavaScript code for the TI SensorTag Demo app.

/**
 * Object that holds application data and functions.
 */
var app = {};

/**
 * Data that is plotted on the canvas.
 */
app.dataPoints = [];

/**
 * Timeout (ms) after which a message is shown if the SensorTag wasn't found.
 */
app.CONNECT_TIMEOUT = 3000;

/**
 * Object that holds SensorTag UUIDs.
 */
app.sensortag = {};

// UUIDs for movement services and characteristics.
app.sensortag.MOVEMENT_SERVICE = 'f000aa80-0451-4000-b000-000000000000';
app.sensortag.MOVEMENT_DATA = 'f000aa81-0451-4000-b000-000000000000';
app.sensortag.MOVEMENT_CONFIG = 'f000aa82-0451-4000-b000-000000000000';
app.sensortag.MOVEMENT_PERIOD = 'f000aa83-0451-4000-b000-000000000000';
app.sensortag.MOVEMENT_NOTIFICATION = '00002902-0000-1000-8000-00805f9b34fb';


app.sensortag.IO_SERVICE = 'f000aa64-0451-4000-b000-000000000000';
app.sensortag.IO_CONFIG = 'f000aa66-0451-4000-b000-000000000000';
app.sensortag.IO_DATA = 'f000aa65-0451-4000-b000-000000000000';

app.sensortag.BAROMETER_SERVICE = 'f000aa40-0451-4000-b000-000000000000';
app.sensortag.BAROMETER_DATA = 'f000aa41-0451-4000-b000-000000000000';
app.sensortag.BAROMETER_CONFIG = 'f000aa42-0451-4000-b000-000000000000';
app.sensortag.BAROMETER_CALIBRATION = 'f000aa43-0451-4000-b000-000000000000';
app.sensortag.BAROMETER_PERIOD = 'f000aa44-0451-4000-b000-000000000000';
app.sensortag.BAROMETER_NOTIFICATION = '00002902-0000-1000-8000-00805f9b34fb';


/**
 * Initialise the application.
 */
app.initialize = function()
{
   document.addEventListener(
      'deviceready',
      function() { evothings.scriptsLoaded(app.onDeviceReady) },
      false);

   // Called when HTML page has been loaded.
   $(document).ready( function()
   {
      // Adjust canvas size when browser resizes
      $(window).resize(app.respondCanvas);

      // Adjust the canvas size when the document has loaded.
      app.respondCanvas();
   });
};

/**
 * Adjust the canvas dimensions based on its container's dimensions.
 */
app.respondCanvas = function()
{
   var canvas = $('#canvas')
   var container = $(canvas).parent()
   canvas.attr('width', $(container).width() ) // Max width
   // Not used: canvas.attr('height', $(container).height() ) // Max height
};

app.onDeviceReady = function()
{
   app.showInfo('Activate the SensorTag and tap Start.');
};

app.showInfo = function(info)
{
   document.getElementById('info').innerHTML = info;
};

app.onStartButton = function()
{
   app.onStopButton();
   app.startScan();
   app.showInfo('Status: Scanning...');
   app.startConnectTimer();
   
};

app.onStopButton = function()
{
   // Stop any ongoing scan and close devices.
   app.stopConnectTimer();
   evothings.easyble.stopScan();
   evothings.easyble.closeConnectedDevices();
   app.showInfo('Status: Stopped.');
};

app.startConnectTimer = function()
{
   // If connection is not made within the timeout
   // period, an error message is shown.
   app.connectTimer = setTimeout(
      function()
      {
         app.showInfo('Status: Scanning... ' +
            'Please press the activate button on the tag.');
      },
      app.CONNECT_TIMEOUT)
}

app.stopConnectTimer = function()
{
   clearTimeout(app.connectTimer);
}

app.startScan = function()
{
   evothings.easyble.startScan(
      function(device)
      {
         // Connect if we have found a sensor tag.
         if (app.deviceIsSensorTag(device))
         {
            app.showInfo('Status: Device found: ' + device.name + '.');
            evothings.easyble.stopScan();
            app.connectToDevice(device);
            app.stopConnectTimer();
         }
      },
      function(errorCode)
      {
         app.showInfo('Error: startScan: ' + errorCode + '.');
      });
};

app.deviceIsSensorTag = function(device)
{
   console.log('device name: ' + device.name);
   return (device != null) &&
      (device.name != null) &&
      (device.name.indexOf('Sensor Tag') > -1 ||
         device.name.indexOf('SensorTag') > -1);
};

/**
 * Read services for a device.
 */
app.connectToDevice = function(device)
{
   app.showInfo('Connecting...');
   device.connect(
      function(device)
      {
         app.showInfo('Status: Connected - reading SensorTag services...');
         console.log("Connect: buzzer");
         app.readBuzzerServices(device);
         
         //console.log("Connect: movement");
         //app.readServices(device);
      },
      function(errorCode)
      {
         app.showInfo('Error: Connection failed: ' + errorCode + '.');
         evothings.ble.reset();
         // This can cause an infinite loop...
         //app.connectToDevice(device);
      });
};

app.readServices = function(device)
{
   device.readServices(
      [
      app.sensortag.MOVEMENT_SERVICE // Movement service UUID.
      ],
      // Function that monitors accelerometer data.
      app.startAccelerometerNotification,
      function(errorCode)
      {
         console.log('Error: Failed to read services: ' + errorCode + '.');
      });
};

app.readBuzzerServices = function(device)
{
   device.readServices(
      [
         app.sensortag.IO_SERVICE,
         app.sensortag.MOVEMENT_SERVICE,
         app.sensortag.BAROMETER_SERVICE
      ],
      // Function that monitors accelerometer data.
      //app.startBuzzerNotification,
      app.startAccelerometerNotification,
         function(errorCode) { console.log('Error: Failed to read buzzer services: ' + errorCode + '.'); }

      //app.startNotifications(),
      //function(errorCode) { console.log('Error: Failed to read services: ' + errorCode + '.'); }
      
      );
      
};

app.startNotifications = function(device) {

   app.startBuzzerNotification();
   app.startAccelerometerNotification();
   
}

app.startBuzzerNotification = function(device)
{
   console.log("Trying to start IO service");
   
   // Config: remote mode.
   device.writeCharacteristic(app.sensortag.IO_CONFIG, new Uint8Array([1]), function() {
      // Data: buzzer on.
      device.writeCharacteristic(app.sensortag.IO_DATA, new Uint8Array([3]), function() {
      console.log("buzzer on success");
      }, app.buzzerFail() );
   }, app.buzzerFail() );   
}

app.buzzerFail = function() {
   console.log("Buzzer failed: ");
}

/**
 * Read accelerometer data.
 */
app.startAccelerometerNotification = function(device)
{
   
   console.log("Trying to start IO service");
   
   // Config: remote mode.
   device.writeCharacteristic(app.sensortag.IO_CONFIG, new Uint8Array([1]), function() {
      
      // Data values
      //1 = red
      //2 = green
      //3 = red + green
      //4 = buzzer
      //5 = red + buzzer
      //6 = green + buzzer
      //7 = all
      
      device.writeCharacteristic(app.sensortag.IO_DATA, new Uint8Array([3]), function() {
      console.log("buzzer on success");
      }, app.buzzerFail() );
   }, app.buzzerFail() );   
   
   app.showInfo('Status: Starting accelerometer notification...');

   // Set accelerometer configuration to ON.
   // magnetometer on: 64 (1000000) (seems to not work in ST2 FW 0.89)
   // 3-axis acc. on: 56 (0111000)
   // 3-axis gyro on: 7 (0000111)
   // 3-axis acc. + 3-axis gyro on: 63 (0111111)
   // 3-axis acc. + 3-axis gyro + magnetometer on: 127 (1111111)
   device.writeCharacteristic(
      app.sensortag.MOVEMENT_CONFIG,
      new Uint8Array([56,0]),
      function()
      {
         console.log('Status: writeCharacteristic ok.');
      },
      function(errorCode)
      {
         console.log('Error: writeCharacteristic: ' + errorCode + '.');
      });

   // Set accelerometer period to 100 ms.
   device.writeCharacteristic(
      app.sensortag.MOVEMENT_PERIOD,
      new Uint8Array([10]),
      function()
      {
         console.log('Status: writeCharacteristic ok.');
      },
      function(errorCode)
      {
         console.log('Error: writeCharacteristic: ' + errorCode + '.');
      });

   // Set accelerometer notification to ON.
   device.writeDescriptor(
      app.sensortag.MOVEMENT_DATA,
      app.sensortag.MOVEMENT_NOTIFICATION, // Notification descriptor.
      new Uint8Array([1,0]),
      function()
      {
         console.log('Status: writeDescriptor ok.');
      },
      function(errorCode)
      {
         // This error will happen on iOS, since this descriptor is not
         // listed when requesting descriptors. On iOS you are not allowed
         // to use the configuration descriptor explicitly. It should be
         // safe to ignore this error.
         console.log('Error: writeDescriptor: ' + errorCode + '.');
      });

   // Start accelerometer notification.
   device.enableNotification(
      app.sensortag.MOVEMENT_DATA,
      function(data)
      {
         app.showInfo('Status: Data stream active - accelerometer');
         var dataArray = new Uint8Array(data);
         var values = app.getAccelerometerValues(dataArray);
         app.drawDiagram(values);
      },
      function(errorCode)
      {
         console.log('Error: enableNotification: ' + errorCode + '.');
      });
   
};


/**
 * Calculate accelerometer values from raw data for SensorTag 2.
 * @param data - an Uint8Array.
 * @return Object with fields: x, y, z.
 */
app.getAccelerometerValues = function(data)
{
   var divisors = { x: -16384.0, y: 16384.0, z: -16384.0 };

   // Calculate accelerometer values.
   var ax = evothings.util.littleEndianToInt16(data, 6) / divisors.x;
   var ay = evothings.util.littleEndianToInt16(data, 8) / divisors.y;
   var az = evothings.util.littleEndianToInt16(data, 10) / divisors.z;

   // Return result.
   return { x: ax, y: ay, z: az };
};

/**
 * Plot diagram of sensor values.
 * Values plotted are expected to be between -1 and 1
 * and in the form of objects with fields x, y, z.
 */
app.drawDiagram = function(values)
{
   var canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');

   // Add recent values.
   app.dataPoints.push(values);

   // Remove data points that do not fit the canvas.
   if (app.dataPoints.length > canvas.width)
   {
      app.dataPoints.splice(0, (app.dataPoints.length - canvas.width));
   }

   // Value is an accelerometer reading between -1 and 1.
   function calcDiagramY(value)
   {
      // Return Y coordinate for this value.
      var diagramY =
         ((value * canvas.height) / 2)
         + (canvas.height / 2);
      return diagramY;
   }

   function drawLine(axis, color)
   {
      context.strokeStyle = color;
      context.beginPath();
      var lastDiagramY = calcDiagramY(
         app.dataPoints[app.dataPoints.length-1][axis]);
      context.moveTo(0, lastDiagramY);
      var x = 1;
      for (var i = app.dataPoints.length - 2; i >= 0; i--)
      {
         var y = calcDiagramY(app.dataPoints[i][axis]);
         context.lineTo(x, y);
         x++;
      }
      context.stroke();
   }

   // Clear background.
   context.clearRect(0, 0, canvas.width, canvas.height);

   // Draw lines.
   drawLine('x', '#f00');
   drawLine('y', '#0f0');
   drawLine('z', '#00f');
};

// Initialize the app.
app.initialize();

rc54
Posts: 2
Joined: 20:31, 29 Oct 2015

Re: 2650 tag IO service for led and buzzer

Postby rc54 » 21:44, 13 Nov 2015

Bingo!......that did it, and can now see where (multiple wrongs) I went wrong. Thanks kindly for posting the code and educating me. Regards

caravan
Posts: 1
Joined: 22:12, 22 Apr 2016

Re: 2650 tag IO service for led and buzzer

Postby caravan » 23:35, 22 Apr 2016

Hi!

I followed this example, and I can get the buzzer/LED's to turn on when initializing the app (thanks!), but how do I go about if I want to create a function to turn LED's/buzzer on or off when e.g. clicking a button? It seemed very straight forward - I just created a function inside of app.js using the exact same code as was suggested here:

Code: Select all

app.startBuzzer = function(device)
{
   device.writeCharacteristic(app.sensortag.IO_CONFIG, new Uint8Array([1]), function() {
     
      device.writeCharacteristic(app.sensortag.IO_DATA, new Uint8Array([4]), function() {
      console.log("buzzer on success");
      }, app.buzzerFail() );
   }, app.buzzerFail() ); 
};


Then making a button inside of index.html:

Code: Select all

<button onclick="app.startBuzzer()" class="yellow">START BUZZER</button>


This won't work however. I can see why there would be a problem, since startBuzzer asks for an object to be passed in ("device") and I don't know how to do this (I've tried everything I could think of, "device", "app.device" etc. but I'm a noob so I can't get it to work).

Any suggestions would be much appreciated! :)


Return to “Texas Instruments”

Who is online

Users browsing this forum: No registered users and 1 guest