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.



#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 NOTE(vol, snd) (((vol) << 4) | (snd))



#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"

main(int argc, char *argv[])
    int fd, n;
    char buf[1];
    struct termios attr;


    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));


    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!


Home | Main Index | Thread Index | Old Index