The solution seemed like an easy enough job for any PIC with an EEPROM. After a little fiddling I came up with a simple but effective code in MPLAB XC8. My PIC of choice was a 16LF1938. This chip really is overkill for this application, but it at least gives me tons of room to expand to other functions as I decide.
PORTB.3 = output
PORTB.0 = yellow LED recording indicator
PORTB.1 = key
PORTB.2 = record/play/cancel button
This video is a quick demonstration of how it will record anything, including a sloppy fist.
- Is key pressed?
- Key radio.
- Is record button held down for 3 seconds?
- Erase eeprom.
- Watch for first key press.
- Loop until key is released. Checking every 10ms. (This gives a total recordable time of 2.55 seconds per mark or space.)
- Record the duration in EEPROM and increment the EEPROM address.
- Record duration until key pressed again or until 2.54s reached. Increment EEPROM address.
- Continue loop until record button is pressed again.
- When record button is clicked briefly, EEPROM is 'played back' in a key down/key up rotating format until an EEPROM value of 255 is read, or EEPROM address of 255 is reached which equates to ~126 marks (more than enough for even the windiest CQ call).
That's all there is to it. I've posted my code below incase anyone is interested. I realize using interrupts would be much more efficient, but this was just a quick hack job to get it working. Also, I'm hardly a programmer, just a tinkerer...
/*
* File: SKeyer.c
* Author: AB9LM
*
* Created on January 26, 2016, 6:06 PM
*/
#define _XTAL_FREQ 8000000
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
//End config
char address;
void blink_yellow(void);
void system_setup(){
OSCCON = 0b01110000;
OPTION_REG = 0b00000000;
TRISB = 0b00000110;
PORTB = 0b00000000;
TRISC = 0b00010000;
ANSELB = 0b00000000;
WPUB1 = 1;
WPUB2 = 1;
}
void delay_ms(unsigned int milliseconds)
{
while(milliseconds > 0)
{
milliseconds--;
__delay_us(990);
}
}
void erase_eeprom(){
char i = 0;
for(i=0; i != 255; i++){
eeprom_write(i, 0xff);
}
}
void record_mark(){
char count = 0;
while(!RB1){
LATBbits.LATB3 = 1;
count += 1;
delay_ms(10);
}
LATBbits.LATB3 = 0;
eeprom_write(address, count);
}
void record_space(){
char count = 0;
while(RB1){
count += 1;
delay_ms(10);
if(!RB2 | count == 255){
eeprom_write(address, count - 1);
break;
}
}
eeprom_write(address, count);
}
void blink_yellow(void){
LATBbits.LATB0 = 0;
delay_ms(50);
LATBbits.LATB0 = 1;
delay_ms(50);
LATBbits.LATB0 = 0;
}
void send_eeprom(){
char delay = 0x00;
char address = 0x00;
while(delay != 0xFF){
if(!RB1){
LATBbits.LATB3 = 0;
blink_yellow();
delay_ms(100);
while(!RB1){}
break;
}
delay = eeprom_read(address);
if(delay == 0xFF){
break;
}
LATBbits.LATB3 = 1;
delay_ms(delay * 10);
LATBbits.LATB3 = 0;
address += 1;
delay = eeprom_read(address);
delay_ms(delay * 10);
address += 1;
}
}
int main(){
address = 0x00;
int ms_count = 0;
system_setup();
while(1){
if(RB1 == 0){
LATBbits.LATB3 = 1;
}
else{
LATBbits.LATB3 = 0;
}
ms_count = 0;
while(!RB2){
ms_count += 1;
delay_ms(10);
if(RB2){
delay_ms(100);
send_eeprom();
}
if(ms_count > 200){
erase_eeprom();
address = 0x00;
while(1){
LATBbits.LATB0 = 1;
while(!RB2){}
if(!RB1){
record_mark();
address += 1;
record_space();
address += 1;
eeprom_write(0xFF,address);
}
if(!RB2 | address >= 0xF0){
while(!RB2){}
LATBbits.LATB0 = 0;
delay_ms(100);
break;
}
}
}
}
}
return 0;
}
No comments:
Post a Comment