Pages: [1]   Go Down
Author Topic: Serial and Processing at Midi Baudrate 31250  (Read 924 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey there.
I'm having a problem with sending midi from the arduino to a processing sketch. First of all, here's my arduino code:

Code:
//#define DEBUG
#include <debugutils.h>
#include <TimerOne.h>

#ifndef DEBUG
#include <MIDI.h>
#endif

#define         bpm_min    60
#define         bpm_max    200
#define         num_ticks  1
#define         quant      16
#define         start_pin  7
#define         num_tracks 7

int             bpm;
unsigned long   beat_time;
unsigned long   beat_time_old;
int             note_current;
unsigned long   tick_time;
int             tick_count;
int             notes_per_quarter;
int             ticks_new;
int             pin_seq[num_tracks][quant];

void setup() {
  bpm               = 120;
  beat_time_old     = 0;
  note_current      = 0;
  tick_time         = int(beat_time/24.0f);
  tick_count        = 0;
  notes_per_quarter = int(24/((1.0f/4.0f)/(1.0f/quant)));
  ticks_new         = 0;


  Timer1.initialize(500000);
  Timer1.attachInterrupt(tick);


  for(int i=0; i<num_tracks; i++) {
    pinMode(start_pin+i, OUTPUT);
    for(int j=0; j<quant; j++) {
      pin_seq[i][j] = 0;
    } 
  }

  pin_seq[0][0]   = 255;
  pin_seq[0][4]   = 255;
  pin_seq[0][8]   = 255;
  pin_seq[0][12]  = 255;

#ifdef DEBUG
  Serial.begin(31250);
#else
  MIDI.begin();
#endif
}

void loop() {
  calc_values();
  check_timer();
}

void calc_values() {
  bpm         = int((analogRead(0)/1023.0f)*(bpm_max-bpm_min)) + bpm_min;
  beat_time   = (unsigned long)(((60000000.0f/float(bpm*num_ticks))+0.5f));
  tick_time   = (unsigned long)((beat_time/24.0f)+0.5f);

  //DEBUG_PRINT((String("Beat: ") + beat_time) + (String(", BPM: ") + bpm) + (String(", TICK: ") + tick_time));
}

void check_timer() {
  if(beat_time != beat_time_old) {
    beat_time_old = beat_time;
    Timer1.setPeriod(tick_time);
  }
}

void tick() {
  tick_count++;
  ticks_new++;

#ifndef DEBUG
  MIDI.sendRealTime(Clock);
#endif

  if(ticks_new > notes_per_quarter) {
    ticks_new = 1;
    note_current++;
    if(note_current >= quant) {
      note_current = 0;
    }

    fire_midi();
  }
}

void fire_midi() {
  for(int i=0; i<num_tracks; i++) {
    if(pin_seq[i][note_current]>0) {
#ifndef DEBUG
      //MIDI.sendNoteOn(0x3c, (byte)pin_seq[i][note_current], (byte)1);
#endif
      int pin = start_pin+i;
      digitalWrite(pin, HIGH);
    }
    else {
#ifndef DEBUG
      //MIDI.sendNoteOn(0x3c, (byte)0, (byte)1);
#endif
      int pin = start_pin+i;
      digitalWrite(pin, LOW);
    }
  }
}

When I try to read the data in my processing sketch, I get wrong inputs. If you leave out the comments the only data send in the piece of code is MIDI.sendRealTime(Clock);. This is 0xf8 send as a byte. The library sends it using Serial.write((byte) 0xf8).

In Processing I initialize the Serialport with 31250 baud, just like the Midi Library does. But the following code just prints: -16. It should -8 for the send data.
Code:
while (serial.available() > 0) {
    byte[] inBuffer = serial.readBytes();
    if (inBuffer != null) {
        for(byte b : inBuffer) {
            PApplet.println(b);
        }
    }
}

I tested the same code with a baudrate of 9600. There the send bytes are -8 which is correct. How do I solve the problem and where does it come from?
I also tested sending the data without the library but with the same result. What have I missed?

I am running fedora 16 and using an arduino duemilanova.
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure that
Code:
    byte[] inBuffer = serial.readBytes();
is right.

The example code on the processing site for Serial.readBytes() is
Code:
void draw() {
  // Expand array size to the number of bytes you expect
  byte[] inBuffer = new byte[7];
  while (myPort.available() > 0) {
    inBuffer = myPort.readBytes();
    myPort.readBytes(inBuffer);
    if (inBuffer != null) {
      String myString = new String(inBuffer);
      println(myString);
    }
  }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used that one before. But with the same result. I actually changed it, because the size got changed anyways, when more bytes were read. (just to be sure, I re-tested it now. But the result is the same. When sending 0xf8 I still get a -16.)
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13664
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


and if you make byte -> int

byte[] inBuffer ?

0xf8 can be seen as -8 but not as -16 unless there has a bit shifted one place?

At other baudrates, does it work?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Using a baudrate of 9600 it works. I tried right shifting the input. That works for this special case but is not a general solution. Ohter messages get totally distorted this way.
And using int[] instead of byte[] won't work since the return type of serial.readBytes is byte[].
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Has nobody any idea where this comes from? I am currently using a baudrate of 38400 which works fine. But for sending midi I will need 31250.
Could it be a problem with the arduino model I'm using?
Logged

Pages: [1]   Go Up
Jump to: