Using a 4x4 touch sensor keyboard [TTP229-BSF] as an I2C module with Teensy 3.6

Status
Not open for further replies.

brownidj

New member
My data collection project requires a Teensy 3.6 with the keypad as an I2C module. I've used a slightly modified version of Steve Stover's code. This is the most reliable method I've found for using this keypad. It works fine with a Uno, but gives an "expected constructor, destructor, or type conversion before '(' token" error when compiling for the Teensy. I assume that atomic.h is not available for the Teensy - is there an alternative?

My C coding skills are not up to sorting this out, so any advice/help with be appreciated:
Code:
/*
   touchpad16_interrupt.ino

   Created: 5/27/2015 9:02:08 PM
   Author: Steve Stover

   16 Key Capacitive Touchpad using TTP229B IC
   http://www.ebay.com/itm/371304274498

   The Touchpad has a jumper on TP1/SAHL for active high serial out
     and a jumper on TP2/KYSEL for 16-keys operation

   Processing the input via external interrupt INT1
     on an Arduino Nano v3.0

   https://forum.arduino.cc/index.php?topic=301382.0
*/

#include <util/atomic.h>

#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))

#define clock_Pin 2
#define sdo_Pin 3
#define beep_Pin 8

// Touchpad value
volatile uint16_t touchVal;  // var for ISR access
uint16_t touchValc;          // copy var for main loop

const int NUMBER_OF_ELEMENTS = 16;
const int MAX_SIZE = 14;

char desc [NUMBER_OF_ELEMENTS] [MAX_SIZE] = {
  { "D:short pause" },
  { "D:long pause" },
  { "D:converse" },
  { "D:sniff" },
  { "D:en passant" },
  { "D:functional" },
  { "D:greet" },
  { "D:tug" },
  { "D:investigate" },
  { "D:roll" },
  { "D:wait" },
  { "P:converse" },
  { "P:tug" },
  { "P:wait" },
  { "P:view" },
  { "P:functional" },
};

void setup() {
  Serial.begin(9600);
  pinMode(clock_Pin, OUTPUT);
  pinMode(sdo_Pin, INPUT);
  pinMode(8, OUTPUT);

  beep(200);
  beep(50);
  beep(50);
  delay(1000);

  // set up INT1 on digital pin 3
  EICRA = (1 << ISC11) | (1 << ISC10);  // external INT1 on rising edge
  EIMSK = (1 << INT1);  // External Interrupt Request 1 Enable
  sei();
}

void loop() {
  ATOMIC_BLOCK(ATOMIC_FORCEON) {
    touchValc = touchVal;
  }
  if (touchValc) {
    //    Serial.print(touchValc, DEC);
    for (byte b = 0; b <= 15; b++) {
      if ((touchValc >> b) & 1) {
        //        Serial.print('\t'); Serial.print("bit "); Serial.print(b);
        //        Serial.print('\t'); Serial.print("pad "); Serial.print(b+1);
        switch (b) {
          case 0 :
            Serial.println(desc[0]);
            break;
          case 1 :
            Serial.println(desc[1]);
            break;
          case 2 :
            Serial.println(desc[2]);
            break;
          case 3 :
            Serial.println(desc[3]);
            break;
          case 4 :
            Serial.println(desc[4]);
            break;
          case 5 :
            Serial.println(desc[5]);
            break;
          case 6 :
            Serial.println(desc[6]);
            break;
          case 7 :
            Serial.println(desc[7]);
            break;
          case 8 :
            Serial.println(desc[8]);
            break;
          case 9 :
            Serial.println(desc[9]);
            break;
          case 10 :
            Serial.println(desc[10]);
            break;
          case 11 :
            Serial.println(desc[11]);
            break;
          case 12 :
            Serial.println(desc[12]);
            break;
          case 13 :
            Serial.println(desc[13]);
            break;
          case 14 :
            Serial.println(desc[14]);
            break;
          case 15 :
            Serial.println(desc[15]);
            break;
        }
        beep(20);
      }
    }
  }
}

void beep(unsigned char delayms) {
  analogWrite(9, 200);      // Almost any value can be used except 0 and 255
  // experiment to get the best tone
  delay(delayms);          // wait for a delayms ms
  analogWrite(9, 0);       // 0 turns it off
  delay(delayms);          // wait for a delayms ms
}

ISR(INT1_vect) {
  touchVal = 0;
  delayMicroseconds(100);
  for (byte i = 0; i <= 15; i++) {
    SET(PORTD, clock_Pin);
    delayMicroseconds(50);
    touchVal |= (digitalRead(sdo_Pin) << i);
    CLR(PORTD, clock_Pin);
    delayMicroseconds(50);
  }
}

The error messages are:
Arduino: 1.8.8 (Mac OS X), TD: 1.45, Board: "Teensy 3.6, Serial, 180 MHz, Faster, US English"

...

keypad_03:145: error: expected constructor, destructor, or type conversion before '(' token
ISR(INT1_vect) {
^
keypad_03: In function 'void setup()':
keypad_03:66: error: 'EICRA' was not declared in this scope
EICRA = (1 << ISC11) | (1 << ISC10); // external INT1 on rising edge
^
keypad_03:66: error: 'ISC11' was not declared in this scope
EICRA = (1 << ISC11) | (1 << ISC10); // external INT1 on rising edge
^
keypad_03:66: error: 'ISC10' was not declared in this scope
EICRA = (1 << ISC11) | (1 << ISC10); // external INT1 on rising edge
^
keypad_03:67: error: 'INT1' was not declared in this scope
EIMSK = (1 << INT1); // External Interrupt Request 1 Enable
^
/Users/david/Arduino/keypad_03/keypad_03.ino: At global scope:
keypad_03:145: error: expected constructor, destructor, or type conversion before '(' token
ISR(INT1_vect) {
^
expected constructor, destructor, or type conversion before '(' token

Many thanks
 
Last edited:
This code uses generic AVR (original 8bit Arduino etc.) registers to define the interrupt setup and handling. This can not work on modern 32bit ARM processors like the Teensy 3.x series. You’ll have to rewrite the corresponding code parts using the attachInterrupt(pin, handlerfct) function.
 
Status
Not open for further replies.
Back
Top