1

Topic: RemoteXY doesn't connect to paired bluetooth

This charming idea called RemoteXY solves my problem to create an own android app.
So i wrote a little sketch producing an useless app to see how it works and to get familiar with it.
It works fine but there are some problems to be solved.

First:
I'm using to differnt HC-05 bluetooth modules: an older one CZ-HC-05 and a newer one with integrated switch for AT mode.
RemoteXY does not connect to this CZ-HC-05. The other one works without problems.
BT Simple Terminal connects both, so the modules aren't the problem.

Second:
Setting AT+IPSCAN=1024,10,1024,10 (factory setting AT+IPSCAN=1024,512,1024,512) causes connection problems with RemoteXY but works with BT Simple Terminal.
Reason for changing IPSCAN to the mentioned values: reduces current consumption drastically. This is what i need.

Third:
The sketch is based on an 8MHz Arduino Pro Mini. 8MHz is sufficient for my application and consumes less current than 20Mhz.
But this forces the internal oscillator to be adjusted via OSCCAL register because i need a reliable system clock of T0=10 ms for a software driven clock (date and time).
The sketch uses timer/counter 2 for this 10ms system clock and timer/counter 0 to count pulses at a pin.
The interrupt service routine for timer/counter 2 produces a pulse of 100us every 10 ms.
All other things to handle RemoteXY are done in loop() exactly as the downloaded code proposes.

The android app itself uses two LED indicators and two push buttons to switch the indicators. This is useless but suitable for test.

Inside loop() there is a delay of 15ms as payload to see if this arrangement is working when it gets interrupted by timer/counter 2.
To my surprise it is working! Fine.

Next step is adjusting the internal oscillator.
The sketch uses hardware serial to communicate with the BT module. Therefore the real baud rate must be in a range of +-6% of nominal baud rate (due to data sheet of ATMega328) otherwise the communication will fail (it normally fails until the oscillator gets adjusted.
This is the second constraint to calibrate the oscillator.

Calibration of oscillator:
The value provided in the OSCCAL register influences the frequency of the internal oscillator from witch baudrate and clock for timer/counter 2 are derived. The value must be set individually for each processor chip.
To find the best fitting value i measured the 100us pulse at pin12. The pulse must occur every T0=10 ms.
The correct count value for timer/counter 2 would be 78,125 but we only can set CONST_TIM2 = 78. This delivers T0=9,984ms (at 8Mhz).
While variating the OSCCAL values i could see some really strange behaviour:

  OSCCAL = 0x84;  produces pulses every 10.06 ms, RemoteXY connects successfully

  OSCCAL = 0x86;  produces pulses every 9.96 ms, RemoteXY connects, but doesn't work correctly

  OSCCAL = 0x88;  produces pulses every 9.9 ms, RemoteXY doesn't connect

The total deviation of T0 and the internal counter frequency is ~0,16% and this is far away from the tolerance boundaries of baud rate.

The described behaviour is very surprising and not tolerable.
And there is no reason for failures inside the tolerances for serial baud rate.
Please explain and fix.

My sketch (the .ino file):

/******************************************************************************
 Uses:
 arduino-1.8.2, remotexy 2.3.1
 Board: arduino mini pro, ATmega328 3,3V, 8MHz 
 *****************************************************************************/

#include "remoteApp.h"

#define flagISR   12        //PB4/MISO pin 12 timer2 interrupt flag
#define T0        10.0      //timer2 interupt time T0 in ms
#define CLKCPU  8000000     //CPU clock
#define CONST_TIM2  byte(CLKCPU/1024*T0/1000)  //count value for T0 at 8Mhz, prescaler=1024


void setup()
{
  //Adjust cpu clock as close to 8MHz as possible, so timer2 produces
  // a 10ms interrupt for a software clock (for other mini pro we find other values).
  OSCCAL = 0x84;   //produces pulses every 10.06 ms, remoteXY connects successfully
  //OSCCAL = 0x86;   //produces pulses every 9.96 ms, remoteXY connects, but doesn't work correctly
  //OSCCAL = 0x88;   //produces pulses every 9.9 ms, remoteXY doesn't connect

  //Baud rates for HW-serial work in the tolerance range of +- 6% (10,6ms - 9,4ms in this example),
  //so we exclude this
  
  //define pins (ports).
  pinMode(flagISR, OUTPUT);       //timer2 interrupt flag

  //Timer0 counts pulses at T0/PD4
  TCNT0  = 0;
  TCCR0A = 0;                                        //Normal mode (count up)
  TCCR0B |= ((1 << CS02) | (1 << CS01) | (1 << CS00)); //T0-pin, rising edge
  TIMSK0 = 0;                                        //no interrupts

  //Timer2, compare A, match value
  noInterrupts();
  TCNT2  = 0;
  TCCR2A = 0;                                     //Normal mode (count up)
  TCCR2B = 0;                                     //Normal mode (count up)
  OCR2A = CONST_TIM2;                             //count for T0
  TCCR2A |= (1 << WGM21);                         //CTC mode
  TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20)); //1024 prescaler
  TIMSK2 |= (1 << OCIE2A);                        //compare A interrupt
  interrupts();

  //Android App
  RemoteXY_Init ();
   
  //initialise values in communication structure
  RemoteXY.led1_g = 0;
  RemoteXY.led2_r = 0;
}

/*============================================================================
  Interupt Service Routine Timer 2, compare A
  system clock 10ms, check pulses at pin12
*/
ISR(TIMER2_COMPA_vect, ISR_BLOCK)
{
  digitalWrite(flagISR, HIGH);      //begin ISR pin12
  
  //do some short stuff for this application
  delayMicroseconds(100);
  
  digitalWrite(flagISR, LOW);      //end of ISR pin12
} //End ISR


void loop()
{
  //do some stuff for this application
  delayMicroseconds(15000);

  //Android-App
  RemoteXY_Handler();

  //values from and to communication structure
  if(1==RemoteXY.button1 && 0==RemoteXY.button2)
    {
      RemoteXY.led1_g = 200;
      RemoteXY.led2_r = 0;
    }
  if(0==RemoteXY.button1 && 1==RemoteXY.button2)
    {
      RemoteXY.led1_g = 0;
      RemoteXY.led2_r = 200;
    }
  
}
// End application ----------------------------------------------------------

The include file

#define REMOTEXY_MODE__HARDSERIAL

#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 57600 

// RemoteXY configurate  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,2,0,2,0,45,0,6,5,0,
  1,1,42,24,19,12,5,103,114,101,
  101,110,0,1,1,64,24,19,12,5,
  32,32,114,101,100,32,32,0,65,2,
  10,9,18,18,2,65,4,11,33,18,
  18,2 };
  
// this structure defines all the variables of your control interface 
struct {

    // input variable
  uint8_t button1; // =1 if button pressed, else =0 
  uint8_t button2; // =1 if button pressed, else =0 

    // output variable
  uint8_t led1_g; // =0..255 LED Green brightness 
  uint8_t led2_r; // =0..255 LED Red brightness
  
    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY; 
#pragma pack(pop)