Pages: [1]   Go Down
Author Topic: Serial.print() giving odd behaviour  (Read 810 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

I am currently working on a project controlling MIDI inputs/outputs using an Arduino Uno.  I am getting some odd outputs and have narrowed down my problem to be within Serial.print() and/or Serial.println() (have tried both).  Current Code:

Code:
#include <MIDI.h>
#define LED1 7
#define LED2 6

void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);        //Listen to all channles (note, cannot send data)
  Serial.begin(31250);                  //31250 - standard MIDI baud rate
  Serial.print("MIDI input test -- 03/20/13 --\n--Display Note, channel(1 or 16), note, velocity\n");
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  BoardOn(3);
}

void BoardOn(byte num) { // Set an initation blink and an 'On' LED
  for (byte i=0;i<num;i++) {
    digitalWrite(LED1,HIGH);
    digitalWrite(LED2,HIGH);
    delay(30);
    digitalWrite(LED1,LOW);
    digitalWrite(LED2,LOW);
    delay(30);
  }
  digitalWrite(LED1,HIGH);
  digitalWrite(LED2,HIGH);
}

unsigned long t=0;                      //time in milliseconds

void loop() {
  int type;        //type of messege, note, velocty, channel, data 1, data 2
  byte note, v, ch, d1, d2;
  if( MIDI.read() ) {                   //If messege incoming
    byte type = MIDI.getType();
 
    switch( type ) {
      case NoteOn:
        note = MIDI.getData1();
        v = MIDI.getData2();
        ch = MIDI.getChannel();
        if (v > 0){
          Serial.print(String("Note on: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");     
        } else {
          Serial.print(String("Note off: ch=") + ch + ",note=" + note + "\n");
        }
        break; 
      case NoteOff:
        note = MIDI.getData1();
        v = MIDI.getData2();
        ch = MIDI.getChannel();
        Serial.print(String("Note off: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");
        break;
      default:
        //d1 = MIDI.getData1();
        //d2 = MIDI.getData2();
        //Serial.println(String("Messege, type=") + type + ", data = " + d1 + " " + d2);
        break;
    }
    t=millis();
  }
  if( (millis() - t) > 10000 ) {
    t += 10000;
    Serial.print("Inactive for 10seconds or more.\n");
  }
}

This prints out everytime I press down or let up a note (using an electronic keyboard).  I get outputs that are correct, although the issue is my output adding random characters to the begging of every new line. 
Example Output:
Code:
MIDI input test -- 03/20/13 --

--Display Note, channel(1 or 16), note, velocity

4PNote on: ch=1, note=52, velocity=800

4 Note off: ch=1,note=520

5PNote on: ch=1, note=53, velocity=800

5 Note off: ch=1,note=530

+PNote on: ch=1, note=43, velocity=800

+ Note off: ch=1,note=430

HPNote on: ch=1, note=72, velocity=800

H Note off: ch=1,note=720

The odd thing is the 'random' characters are consistent with the note I press, as you can see, every On has a corresponding Off with the same leading character.  I have narrowed down my error search to the Serial.print() function.  I have replaced everything within the print() to something consistent, and it still does the same thing.

IMPORTANT:
As you may know, Arduino does not support MIDI baud rate of 31250 in the serial monitor, I am montering my COM port using pySerial and a small Python program.

test.py
Code:
#!/usr/bin/env python3.3
#encoding: utf-8

import sys
import re
import serial

def main():
    ser = serial.Serial('COM9',31250)              #enable for non-command line argument version
    ser.timeout = 10                                  #Set timeout so readline() cannot block forever
    ser.setRTS(True)
    ser.setRTS(False)
    ser.close()                                     #be safe, close the port before opening (rids Windows errors...)
    ser.open()                                      #Open the port between arduino serial and python

    while 1:
        d1 = ser.readline();                        #d1 will be a BYTE class
        data = d1.decode('utf-8','ignore')                   #convert BYTE class into str
        print(data)

    ser.close()

I do not believe the .decode is the problem as if I only print the readline() result, I get the encoded data, along with the 'random' character and then my Arduino print statement. 

I tried to provide as much info as possible, if anyone has heard of a problem with Serial.print() or sees some newb mistake I am making, I would greatly appreciate the help smiley

Thanks once again
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1257
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Is the MIDI and the Serial prnting one the same serial port?
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

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

Is the MIDI and the Serial prnting one the same serial port?
Only the Arduino is printing to the serial port. The Python script is only reading from said serial port.
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1257
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe so, but the Arduino IDE must be getting the data to dsplay from somewhere any you only have one serial port open ..

Thge MIDi library is writing it's stuff to the serial port, same as Serial.print. What COM port is the Python script reading from and is this the same as the IDE?

It is far, far, far more likely that you have some error in the COM port config than there being a problem in the Serial.print library.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

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

Maybe so, but the Arduino IDE must be getting the data to dsplay from somewhere any you only have one serial port open ..

Thge MIDi library is writing it's stuff to the serial port, same as Serial.print. What COM port is the Python script reading from and is this the same as the IDE?

It is far, far, far more likely that you have some error in the COM port config than there being a problem in the Serial.print library.

Python script is reading from COM9 and the Arduino IDE is set on COM9 as well.  I don't get an error on my Python when opening the connection and according to http://playground.arduino.cc/interfacing/python I am reading correctly.

This leaves me still wondering what is prepending characters to my print.
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1257
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Think about what you have just written. The same com port has the midi and debug messages coming to it. What do you think the serial console is going to display?

Easy check. - don't send the midi message and see if your "print" problem disappears.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
          Serial.print(String("Note on: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");     
This is just plain wrong. Wasting precious resources so you can have just one Serial.print() statement is plain laziness. Do it right.
Logged

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

Code:
          Serial.print(String("Note on: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");     
This is just plain wrong. Wasting precious resources so you can have just one Serial.print() statement is plain laziness. Do it right.

I'm sorry, could you elaborate, I am unsure what you mean.

Think about what you have just written. The same com port has the midi and debug messages coming to it. What do you think the serial console is going to display?

Easy check. - don't send the midi message and see if your "print" problem disappears.
I found the cause of my problems.  I use MIDI.begin() AND Serial.begin(31250).  Both are not needed, when I comment out MIDI.begin(), everything runs perfectly.  Although, if I comment out Serial.begin(31250) and leave MIDI.begin() things go wrong again, any idea what may be causing MIDI.begin() to act weird on the serial connection?
« Last Edit: April 20, 2013, 03:14:25 pm by Dohrann » Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1257
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nothing is acting 'weird'. If you share the same serial connection you will see messages from everything that uses that connection. As I have already said several times, you cannot mix MIDI and serial debug on the same serial line and expect it the output to be 'clean'.

If you are just using this for debugging, then live with it and move on. Once you remove the debug statements all that will be left if the midi. If you mean to use this for information, then you need to find a different solution for the messages (LCD 4 line display, for example) that is separate.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm sorry, could you elaborate, I am unsure what you mean.
Sure.

Code:
Serial.print(String("Note on: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");
There is a call to the String constructor, to hold the string "Note on: ch=". Then there are 6 calls to the copy constructor to concatenate each of the other parts. When, Serial.print() prints the string that String wrapped. Finally, there are 7 calls to the String destructor. All so you can have one call to Serial.print().

Code:
Serial.print("Note on: ch=");
Serial.print(ch);
Serial.print(", note=");
Serial.print(note);
Serial.print(", velocity=");
Serial.println(v);
involves no constructors, no destructors, and no memory fragmentation. But it does involve a little more typing. Once.
Logged

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

Nothing is acting 'weird'. If you share the same serial connection you will see messages from everything that uses that connection. As I have already said several times, you cannot mix MIDI and serial debug on the same serial line and expect it the output to be 'clean'.

If you are just using this for debugging, then live with it and move on. Once you remove the debug statements all that will be left if the midi. If you mean to use this for information, then you need to find a different solution for the messages (LCD 4 line display, for example) that is separate.

Updated last post as I found my root cause.

Quote
I'm sorry, could you elaborate, I am unsure what you mean.
Sure.

Code:
Serial.print(String("Note on: ch=") + ch + ", note=" + note + ", velocity=" + v + "\n");
There is a call to the String constructor, to hold the string "Note on: ch=". Then there are 6 calls to the copy constructor to concatenate each of the other parts. When, Serial.print() prints the string that String wrapped. Finally, there are 7 calls to the String destructor. All so you can have one call to Serial.print().

Code:
Serial.print("Note on: ch=");
Serial.print(ch);
Serial.print(", note=");
Serial.print(note);
Serial.print(", velocity=");
Serial.println(v);
involves no constructors, no destructors, and no memory fragmentation. But it does involve a little more typing. Once.
Thank you that made much more sense, I changed my code accordingly and tested some timing, it does run much faster thank you. smiley-grin
Logged

Pages: [1]   Go Up
Jump to: