The Cranky Sysadmin A world of technology, fun, and ignorant rants.

June 12, 2013

Arduino Capacitive Touch Iambic Key (using attiny85)

Filed under: Arduino,Electronics,ham radio — Cranky Sysadmin @ 9:19 pm

Since I’m trying to learn morse code, I decided I’d build a key which functions as a trainer and an actual key. I’ve always liked the idea of capacitive touch sensors, so I went with that. This is a small project using a handful of parts. One should be able to finish it in an evening of focused work. Read on if you’re interested in the details.

I got my inspiration from a few places. The arduino playground has some pages on capacitive touch sensors,  this one is really nice. There is also a German site which implements a capacitive key with the program in Bascom. There are other capacitive touch implementations, but they all use extra pins and components to do the work. With a little opaque code, you don’t need anything but the input pins and some copper pads. The way these no frills sensors work is via a measured RC time constant.  First the pin is brought low. The pin is then set to input and the internal pullup resistor is activated. The time until the pin goes high is then measured. If nothing is touching the sensor, not much time goes by. If your finger is on the sensor, more time goes by because of the capacitance in your body.

I use two inputs, one for dit and one for dah. I included a tiny speaker in the case, and I send the key signal out through a standard mono jack. I use one potentiometer for volume, and one for code speed. The code for the key is below. It requires the arduino-attiny additions.

/*
Copyright (c) 2013 John Jorgensen
Use this code as you will but attribute authorship to me.
*/

#define DIT 3
#define DAH 4
#define LED 1
#define SPEAKER 0  
#define DITLEN A1
// THRESH is the count before the input pin goes high. I only needed 1.
#define THRESH 1
// #define note 75
#define TONE 700

int note;

boolean readbutton(int button){
  volatile uint8_t* ddr;
  volatile uint8_t* port;
  volatile uint8_t* pin;
  byte bitmask;
  unsigned int count=0;
  port=portOutputRegister(digitalPinToPort(button));
  ddr=portModeRegister(digitalPinToPort(button));
  bitmask=digitalPinToBitMask(button);
  pin=portInputRegister(digitalPinToPort(button));
  *port &= ~(bitmask);
  *ddr |= bitmask;
  delay(1);
  *ddr &= ~(bitmask);
  *port |= bitmask;  // comment this out if you install 100k pullups
                     // on the inputs.

  while ( ! (*pin & bitmask)) {
    count++;
  }
  *port &= ~(bitmask);
  *ddr  |= bitmask;

  return(count>THRESH?1:0);
}

void setup (){
  pinMode(DIT, INPUT);
  pinMode(DAH, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(SPEAKER, OUTPUT);
}

void loop(){
//  bitWrite(PORTB, LED,HIGH);
//  delay(500);
  boolean dit,dah;

  note=analogRead(A1);
//  note=150;
  dit=readbutton(DIT);
  dah=readbutton(DAH);
  // dit and dah pressed together produce a dahdit
  if (dit && dah){
    /*
    digitalWrite(LED, HIGH);
    tone(SPEAKER,TONE, note*3);
    delay(note*3);
    digitalWrite(LED, LOW);
    delay(note);
    digitalWrite(LED, HIGH);
    tone(SPEAKER,TONE, note);
    delay(note);
    digitalWrite(LED, LOW);
    delay(note);
    */
   } else if (dit) {
    digitalWrite(LED, HIGH);
    tone(SPEAKER,TONE,note);
    delay(note);
    digitalWrite(LED, LOW);
    delay(note);
  } else if (dah){
    digitalWrite(LED, HIGH);
    tone(SPEAKER,TONE, note*3);
    delay(note*3);
    digitalWrite(LED, LOW);
    delay(note);
  }
}

Below is the schematic. Add a largish (I used 47 uf) cap between the 5v rail and ground. I missed that in the schematic.
iambic

As noted in a comment in the code, it may be better to add a real 100k pullup resistor to the input pins, and then remove the
*port |= bitmask;
line. With this change you may be able to detect a lighter touch and adjust THRESH up a bit. I have ham hands, so I don’t need this.

Below is a picture of the project all put together. Of special note are the touch sensors, which is simply a heavy piece of double sided pcb stock that I carved to a nice shape.

yet another example of ugly construction

yet another example of ugly construction

IMG_0042

I included an ISP port to cover for my mistakes in software. Turn down the volume before programming as the speaker connection can interfere with programming.

I included an ISP port to cover for my mistakes in software. Turn down the volume before programming as the speaker connection can interfere with programming.

I have a USB ASP programmer which I got cheaply online. The ISP pins are marked in the schematic. Just match them up to a nice female header.

I’m not an expert in morse code, but this key seems to perform very well for me. The audio is low but audible. I tested the key with my FT-450D and it seems to work fine. Just be sure to enable the key and don’t turn on the “keyer” option.

 

1 Comment »

  1. Hello,
    I have try your code, all work perfect, only pot for speed do not work.
    Speed is always same (used pot of 10 KOhm).
    I have try also to change value of potentiometer, till 2 MOhm, but always same, speed is very high.

    Can you please help about this problem?

    Thank you very much in advance,
    Michael

    Comment by Michael — November 23, 2014 @ 3:57 pm

RSS feed for comments on this post.

Leave a comment

Powered by WordPress