Echo from Bluefruit to TFT ...

Reasonably new to Arduino, and this is my first attempt, feel I have got a long way to where I want - however need a little help.

I've got the UNO connected to the Bluefruit BLE board - and also the Adafruit_SSD1351 tft screen.

I've got the example sketch that displays all sorts of graphics on TFT - works ok.

I've got the Bluefruit example 'BLEUartdatamode' talking to the iPhone bluefruit App and transferring data back and forth to the serial monitor - works ok.

What I want is to transfer the data from the iphone via BLE to the TFT screen.

So Far;

I modified the uart sketch to include all of the necessary includes and DEFs from the graphics code, and included the TFTdrawtext function. Put in code to 'draw' the incoming text received to the TFT.

First issue I realised was that the Serial speeds of the Serial monitor and TFT were different - so have set the serial monitor bit to 9600 ...bit slow but till works.

When I enter characters on the iphone I get The character I entered echoing in the monitor ok - but on the TFT I'm getting 2 or more graphic type characters.

Qs for the experts: -

Am I doing things the correct way ?
Do I need to translate the incoming somehow - it goes to serial monitor ok - and any 'hardcoded' text, goes to TFT correctly. (ie the 'Input:' see below) ?
Anyone got any sample code for doing what I'm trying to do?

Many thanks for any help
Phil

Code as follows:

pjtxt = "";
//
// If some text from Phone APP .....ie IN the BLE Chip
// Echo received data into the Chip ...(ie Serial Monitor watching)
  while ( ble.available() )
  {
    int c = ble.read();
    Serial.print((char)c);

strcpy(pjtxt,c);

tft.begin();
tft.fillScreen(YELLOW);
testdrawtext("Input:", BLACK);
testdrawtext(pjtxt, BLACK);
delay(500);
   
  }

Code as follows:

That scrap of code hasn't a snowball's chance in hell of compiling. Post your REAL code IN CODE TAGS.

Sorry - told you I was new here...this is only a snippet and it does compile

PhilMonfie:
Sorry - told you I was new here...this is only a snippet and it does compile

sketch_jan10a:1: error: expected constructor, destructor, or type conversion before '=' token
sketch_jan10a:5: error: expected unqualified-id before 'while'

No, it doesn't.

Should I put the whole program here, like I said this is a snippet which I thought may be enough, given that it does work albeit with spurious characters being output.

Should I put the whole program here

Yes, of course.

We need to see, for instance, what type of variable pjtxt is. My guess is that it is a pointer to memory where a literal is stored. Changing the memory that that pointer points to is NOT good programming practice. Doing so leads to unpredictable things happening. Like garbage output, for instance.

Ah ok ...could be my lack of C++ knowledge then - been programming for 40years but very new to C and C++; and extremely new to this type of embedded stuff.

Full code here..... If I need to up my learning curve please just point me somewhere if I'm asking too many newbie questions.

Code:

/*********************************************************************
 This is an example for our nRF51822 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

// You can use any (4 or) 5 pins 
#define sclk 2
#define mosi 3
#define dc   4
#define cs   5
#define rst  6

// Color definitions
#define  BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF



#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
  #include <SoftwareSerial.h>
#endif

#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>

// Option 1: use any pins but a little slower
Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, mosi, sclk, rst);  

// Option 2: must use the hardware SPI pins 
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be 
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
//Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, rst);

float p = 3.1415926;

/*=========================================================================
    APPLICATION SETTINGS

    FACTORYRESET_ENABLE       Perform a factory reset when running this sketch
   
                              Enabling this will put your Bluefruit LE module
                              in a 'known good' state and clear any config
                              data set in previous sketches or projects, so
                              running this at least once is a good idea.
   
                              When deploying your project, however, you will
                              want to disable factory reset by setting this
                              value to 0.  If you are making changes to your
                              Bluefruit LE device via AT commands, and those
                              changes aren't persisting across resets, this
                              is the reason why.  Factory reset will erase
                              the non-volatile memory where config data is
                              stored, setting it back to factory default
                              values.
       
                              Some sketches that require you to bond to a
                              central device (HID mouse, keyboard, etc.)
                              won't work at all with this feature enabled
                              since the factory reset will clear all of the
                              bonding data stored on the chip, meaning the
                              central device won't be able to reconnect.
    MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some new features
    MODE_LED_BEHAVIOUR        LED activity, valid options are
                              "DISABLE" or "MODE" or "BLEUART" or
                              "HWUART"  or "SPI"  or "MANUAL"
    -----------------------------------------------------------------------*/
    #define FACTORYRESET_ENABLE         1
    #define MINIMUM_FIRMWARE_VERSION    "0.6.6"
    #define MODE_LED_BEHAVIOUR          "MODE"
/*=========================================================================*/

// Create the bluefruit object, either software serial...uncomment these lines
/*
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);


// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  while (!Serial);  // required for Flora & Micro
  delay(500);

  //Serial.begin(115200);
  Serial.begin(9600);
  Serial.println(F("Adafruit Bluefruit Command <-> Data Mode Example"));
  Serial.println(F("------------------------------------------------"));

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  if ( FACTORYRESET_ENABLE )
  {
    /* Perform a factory reset to make sure everything is in a known state */
    Serial.println(F("Performing a factory reset: "));
    if ( ! ble.factoryReset() ){
      error(F("Couldn't factory reset"));
    }
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode"));
  Serial.println(F("Then Enter characters to send to Bluefruit"));
  Serial.println();

  ble.verbose(false);  // debug info is a little annoying after this point!

  /* Wait for connection */
  while (! ble.isConnected()) {
      delay(500);
  }

  Serial.println(F("******************************"));

  // LED Activity command is only supported from 0.6.6
  if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
  {
    // Change Mode LED Activity
    Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
    ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
  }

  // Set module to DATA mode
  Serial.println( F("Switching to DATA mode!") );
  ble.setMode(BLUEFRUIT_MODE_DATA);

  Serial.println(F("******************************"));
}

/**************************************************************************/
/*!
    @brief  Constantly poll for new command or response data
*/
/**************************************************************************/
void loop(void)
{
  // Check for user input
  char n, inputs[BUFSIZE+1];
char pjtxt;

//
// If some text on Serial Input (ie INSIDE the BADGE ...send to phone App via BLE .......
  if (Serial.available()) 
  {
    n = Serial.readBytes(inputs, BUFSIZE);
    inputs[n] = 0;
    // Send characters to Bluefruit
    Serial.print("Sending: ");
    Serial.println(inputs);

    // Send input data to host via Bluefruit
    ble.print(inputs);    
  }
// 
//

pjtxt = "";
//
// If some text from Phone APP .....ie IN the BLE Chip
// Echo received data into the Chip ...(ie Serial Monitor watching)
  while ( ble.available() )
  {
    int c = ble.read();
    Serial.print((char)c);          //prints to serial monitor ok

strcat(pjtxt,c);


tft.begin();
tft.fillScreen(YELLOW);
testdrawtext(pjtxt, BLACK);
delay(500);


   
  }
  

 

// Go Back and check again.....
// End of Main Loop
}


void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0,0);
  tft.setTextColor(color);
  tft.print(text);
}

And Apologies - should have the read the 'How to ask questions on this forum' before posting - grateful for your help.

char pjtxt;

So, you can write ONE character to pjtxt.

pjtxt = "";

Single characters use single quotes.

strcat(pjtxt,c);

Here, you try to write two characters (c and a NULL terminator) to one character. Fail. What will really happen is that you will write over memory you don't own.

testdrawtext(pjtxt, BLACK);

I'm almost certain that this function does not expect a character as the first argument.

void testdrawtext(char *text, uint16_t color) {

AHA, I was right.

Change the declaration of pjtxt to be an array of characters.

char pjtxt[20];

Initialize the array to an empty string:

pjtxt[0] = '\0';

Then, you can use strcat() and your function that expects a string.

Thanks for that - did those changes and it runs - but entering 'a' on App echos 'a' in serial monitor but a club then a heart symbol on the display.....

Thanks for that - did those changes and it runs - but entering 'a' on App echos 'a' in serial monitor but a club then a heart symbol on the display.....

My crystal ball says that the problem is on line 551578125874125874522145541. Of course, it might be on the line before or after that line.

Paul - you are a wag - but I am appreciating your help.....

/*********************************************************************
 This is an example for our nRF51822 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

// You can use any (4 or) 5 pins 
#define sclk 2
#define mosi 3
#define dc   4
#define cs   5
#define rst  6

// Color definitions
#define  BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF



#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
  #include <SoftwareSerial.h>
#endif

#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>

// Option 1: use any pins but a little slower
Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, mosi, sclk, rst);  

// Option 2: must use the hardware SPI pins 
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be 
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
//Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, rst);

float p = 3.1415926;

/*=========================================================================
    APPLICATION SETTINGS

    FACTORYRESET_ENABLE       Perform a factory reset when running this sketch
   
                              Enabling this will put your Bluefruit LE module
                              in a 'known good' state and clear any config
                              data set in previous sketches or projects, so
                              running this at least once is a good idea.
   
                              When deploying your project, however, you will
                              want to disable factory reset by setting this
                              value to 0.  If you are making changes to your
                              Bluefruit LE device via AT commands, and those
                              changes aren't persisting across resets, this
                              is the reason why.  Factory reset will erase
                              the non-volatile memory where config data is
                              stored, setting it back to factory default
                              values.
       
                              Some sketches that require you to bond to a
                              central device (HID mouse, keyboard, etc.)
                              won't work at all with this feature enabled
                              since the factory reset will clear all of the
                              bonding data stored on the chip, meaning the
                              central device won't be able to reconnect.
    MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some new features
    MODE_LED_BEHAVIOUR        LED activity, valid options are
                              "DISABLE" or "MODE" or "BLEUART" or
                              "HWUART"  or "SPI"  or "MANUAL"
    -----------------------------------------------------------------------*/
    #define FACTORYRESET_ENABLE         1
    #define MINIMUM_FIRMWARE_VERSION    "0.6.6"
    #define MODE_LED_BEHAVIOUR          "MODE"
/*=========================================================================*/

// Create the bluefruit object, either software serial...uncomment these lines
/*
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);


// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  while (!Serial);  // required for Flora & Micro
  delay(500);

  //Serial.begin(115200);
  Serial.begin(9600);
  Serial.println(F("Adafruit Bluefruit Command <-> Data Mode Example"));
  Serial.println(F("------------------------------------------------"));

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  if ( FACTORYRESET_ENABLE )
  {
    /* Perform a factory reset to make sure everything is in a known state */
    Serial.println(F("Performing a factory reset: "));
    if ( ! ble.factoryReset() ){
      error(F("Couldn't factory reset"));
    }
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode"));
  Serial.println(F("Then Enter characters to send to Bluefruit"));
  Serial.println();

  ble.verbose(false);  // debug info is a little annoying after this point!

  /* Wait for connection */
  while (! ble.isConnected()) {
      delay(500);
  }

  Serial.println(F("******************************"));

  // LED Activity command is only supported from 0.6.6
  if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
  {
    // Change Mode LED Activity
    Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
    ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
  }

  // Set module to DATA mode
  Serial.println( F("Switching to DATA mode!") );
  ble.setMode(BLUEFRUIT_MODE_DATA);

  Serial.println(F("******************************"));
}




/**************************************************************************/
/*!
    @brief  Constantly poll for new command or response data
*/
/**************************************************************************/
void loop(void)                                     // Keeps looping all the time
{
  // Check for user input
  char n, inputs[BUFSIZE+1];  
  char pjtxt[20];      
  pjtxt [0] = '\0';                     


//
// If some text on Serial Input (ie INSIDE the BADGE ...send to phone App via BLE .......
  if (Serial.available()) 
  {

    Serial.println(F("Got input"));

    
    n = Serial.readBytes(inputs, BUFSIZE);
    inputs[n] = 0;
    // Send characters to Bluefruit
    Serial.print("Sending: ");
    Serial.println(inputs);

    // Send input data to host via Bluefruit
    ble.print(inputs);    
  }
// 
//


//
// If some text from Phone APP .....ie IN the BLE Chip
// Echo received data into the Chip ...(ie Serial Monitor watching)
  while ( ble.available() )
  {
    int c = ble.read();
    Serial.print((char)c);          //prints to serial monitor ok

strcat(pjtxt,c);


tft.begin();
tft.fillScreen(YELLOW);
testdrawtext(pjtxt, BLACK);
delay(500);

  }


// Go Back and check again.....
// End of Main Loop
}


void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0,0);
  tft.setTextColor(color);
  tft.print(text);
}

I would add a
Serial.print (pjtxt)
just after you
strcat(pjtxt,c)
in order to see what's really in pjtxt.

  while ( ble.available() )
  {
    int c = ble.read();
    Serial.print((char)c);          //prints to serial monitor ok

strcat(pjtxt,c);

You might want to look at the documentation for strcat(). The second argument is NOT an int.

Declare c to BE a char, so the cast is not necessary. Add c to the array correctly:

  pjtxt[pjIndex++] = c;
   pjtxt[pjIndex] = '\0';

where pjIndex is a new variable, of type byte, declared right after the pjtxt array.

BINGO !!

It Works ...but not sure I understand why ...I need to get up to speed in C++ I think.....

Thank you so much for your help Paul.

Are you part of the Arduino team? You in Seattle ? ...I have a brother in law there.

Phil

Are you part of the Arduino team?

No. Just a volunteer here.

You in Seattle ?

Thereabouts.