NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Serial port programming
I've a few questions on serial port programming that I'm hoping people
may be able to help out with ...
I'm currently writing a program to control an old drum machine via my
computer's RS-232 serial port. On the drum machine end of the cable
there's a phono socket that accepts serial output and ground
connections. On the computer end, the request to send and clear to send
pins are connected together, as are the data set ready and data terminal
ready pins.
My first question, is whether connecting together the pins as I describe
above is still a viable option (the drum machine manual describes this
approach, but it dates from 1983).
The data format is described in the manual as follows:
Start LSB 1 2 3 4 5 6 7 2 stop bits
+12v +-----+ +-----+ +-----+ +-----+ +-----+
| | | | | | | | | |
| | | | | | | | | |
-12v -----+ +-----+ +-----+ +-----+ +-----+ +-----+-----
The first four bits are the volume, and the second four bits are the
instrument, with the note sounding in the 2 stop bits. I wrote the
following code to try play a sound, and it sort of works - a snare drum
is played, but sometimes it's followed by other sounds. Even after I've
closed the connection, the odd sound still plays occasionally, but not
between me putting the drum machine into receive mode and running the
program the first time.
(drumulator.h)
#ifndef DRUMULATOR_H
#define DRUMULATOR_H
#define SERIAL_PORT "/dev/tty00"
#define CLAVE 0x0
#define COWBELL 0x1
#define CLAPS 0x2
#define OPEN_HI_HAT 0x3
#define CLOSED_HI_HAT 0x4
#define RIDE_CYMBAL 0x5
#define BASS_DRUM 0x6
#define SNARE_DRUM 0x7
#define RIMSHOT 0x8
#define HI_TOM 0x9
#define MID_TOM 0xA
#define LOW_TOM 0xB
#define METRONOME_CLICK 0xC
#define NOTE(vol, snd) (((vol) << 4) | (snd))
#endif
(drumulator.c)
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "drumulator.h"
int
main(int argc, char *argv[])
{
int fd, n;
char buf[1];
struct termios attr;
fd = open(SERIAL_PORT, O_WRONLY | O_NOCTTY | O_NDELAY);
if (fd < 0) {
fprintf(stderr, "failed to open port: %s\n", strerror(errno));
return 1;
}
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &attr);
attr.c_cflag |= (CLOCAL | CREAD);
attr.c_cflag &= ~PARENB;
attr.c_cflag &= ~CSTOPB;
attr.c_cflag &= ~CSIZE;
attr.c_cflag |= CS8;
cfsetospeed(&attr, B9600);
tcsetattr(fd, TCSANOW, &attr);
buf[0] = NOTE(0xF, SNARE_DRUM);
n = write(fd, buf, 1);
if (n < 0)
fprintf(stderr, "failed to write to port: %s\n", strerror(errno));
close(fd);
return 0;
}
So, my second question is whether I'm doing anything obviously wrong in
the code, and what problems might be causing the spurious notes (over
sensitivity of the drum machine serial interface for instance).
Finally, (and thanks if you've read this far!), I'd like to knock
together a primitive sequencer for the drum machine if I can resolve the
existing problems. Any suggestions on how to do the timing
(nanosleep(2)?) and to correctly allwo for the start and stop bits would
be most appreciated!
Chris
Home |
Main Index |
Thread Index |
Old Index