Pages: [1]   Go Down
Author Topic: Gelöst: MIDI Senden,Seriell und über RFM12  (Read 1403 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo
Ich habe ein Projekt, mit dem ich Sensoren auslese und Midi Befehle sende.
Über die Serielle Schnittstelle funktioniert dies auch. Zusätzlich möchte ich die selben Befehle auch über einen RFM12 senden.
Mit dem Serial Demo für RFM12 kann mann serielle Daten senden. Aber dies funktioniert nur mit Daten die auf der Seriellen Schnittstelle empfangen werden.
Habe schon einige Varianten probiert finde aber keine Lösung .
RFM12 Serial:
Code:
// Serial data over RF12 demo, works in both directions
// 2009-04-17 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: rf12serial.pde 4727 2009-12-08 21:39:49Z jcw $

#include <Ports.h>
#include <RF12.h>
#include <RF12sio.h>

RF12 RF12;

void setup() {
    Serial.begin(31250);
    Serial.print("\n[rf12serial]");
    rf12_config();
}

void loop() {
    if (Serial.available())
        RF12.send(Serial.read());
    
    if (RF12.poll())
        Serial.print(RF12.read());
}


Mein Arduino Code:
Code:
#define BUTTON1  7
#define STAT1  6
byte needToSend;
byte incomingByte;
byte note;
byte velocity;
int pot0;
int pot1;
int val,t;
int note1=48;
int Velo;
int Velor;

//*****************
// Variables
int switchState1 = HIGH;

int currentSwitchState1 = HIGH;

//****************************
byte byte1;
byte byte2;
byte byte3;
// RF 12
#include <Ports.h>
#include <RF12.h>
#include <RF12sio.h>

RF12 RF12;
// ENDE

void setup() {
  
  Serial.begin (38400);  //(31250);     // Midi Baudrate
  Serial.print("\n[rf12serial]");
  rf12_config();  
  rf12_initialize(21, RF12_868MHZ, 8);
 //
  pinMode(STAT1,OUTPUT);
  pinMode(BUTTON1,INPUT);
 

  digitalWrite(BUTTON1,HIGH);
 
  
}

void loop () {

 //****************Digital Ports************
  pot0 = analogRead(0);
  Velor= pot0/8;
  pot1 = analogRead(1);
  Velo= pot1/8;
  //***********Variante B Pollen***************
    
  currentSwitchState1 = digitalRead(BUTTON1); //switchPin1
  if( currentSwitchState1 == LOW && switchState1 == HIGH ) // push
    Midi_Send(0x90, note1,Velo);
    RF12_Send(0x90, note1,Velo);
     digitalWrite(STAT1,HIGH);
  if( currentSwitchState1 == HIGH && switchState1 == LOW ) { // release
    Midi_Send(0x80, note1,0x45);
    RF12_Send(0x80, note1,0x45);
   Midi_Send(0x90, note1+12,Velor);  // release Ton on
   delay (Velor);
   Midi_Send(0x80, note1+12, 0x01); // release Ton off
  }
  switchState1 = currentSwitchState1;
     digitalWrite(STAT1,LOW);

//**********Pollen Ende***************

}


void Midi_Send(byte cmd, byte data1, byte data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
  RF12.send(Serial.read());
}

void RF12_Send(byte cmd, byte data1, byte data2) {
  struct {
    byte cmd:8;    // Note on / off
    byte data1:8;  // Note Value
    byte data2:8;  // Note Velocity
} payload;


      rf12_recvDone();
      if (needToSend && rf12_canSend()) {
        needToSend = 0;
     //   payload.cmd = 1;
     //  payload.data1 = 2;
     //   payload.data2 = 3;
    
        
        rf12_sendStart(0, &payload, sizeof payload);      
     // RF12.send(Serial.read());
     //  RF12.send(cmd, BYTE);
     // RF12.send(data1, BYTE);
     // RF12.send(data2, BYTE);
      
    if (RF12.poll())
    Serial.print(RF12.read());

}
}
char button(char button_num) {
  return (!(digitalRead(button_num)));
}



Die Baudrate steht auf 38400 um den Serial-Monitor zu benutzen. Da ich dort keine freien Werte einrichten kann.
Mit der Variant über Payload funktioniert es nicht.
Auch RF12.send(Serial.read()). macht hier keinen Sinn. Da die Midi befehle auf TX geschrieben werden und RX gelesen wird.
Hat Jemand einenen  Lösungsansatz?

« Last Edit: August 26, 2012, 07:18:54 pm by xboom » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Beispiel verwendet Serial nur weil's so schön einfach ist, und um zu zeigen, dass man
- eine Variable vom Typ RF12 braucht.
- es eine Funktion rf_config() gibt. ( Nicht eventuell RF12.config()  ??? )
- man mit send() ein Byte versenden kann
- man mit read() ein Byte lesen kann
- man mit poll() gemeldet bekommt, ob etwas zum Lesen empfangen wurde.

Was deine RF12 library sonst noch kann, und warum du es so kompliziert machst, verstehe ich nicht.
Statt - wie im Beispiel - das dem einen zu senden was der andere empfangen hat und umgekehrt,
willst du doch nur das, was du dem einen sendest, auch dem anderen senden.
 (So verstehe ich jedenfalls "Zusätzlich möchte ich die selben Befehle auch über einen RFM12 senden." ) 

Du kannst doch deine Midi_Send() Funktion 1:1 kopieren und in einfach Serial.print(x,BYTE) durch  RF12.send(x) ersetzen und das ganze RF12_Send() nennen.

Serial.print(x,BYTE) ist übrigens eigentlich nur Serial.write(x)
Logged

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

Hallo Michael
Dies hatte ich ursprünglich auch versucht. ist am auskommentierten Code zu erkennen. Aber so wie ich die RFM-Lib. verstanden habe muss ich die Daten in einen Payload packen, Damit sie hinterher auch wieder richtig ankommen.
Dokumentation der RFM12 Lib auf:
http://jeelabs.net/projects/cafe/wiki/RF12

Hab jetzt mal nach deinen Vorschlägen geändert und bekomme in der IDE keinen Fehler mehr.
Aber der RFM scheint nichts zu senden.
Code:
void Midi_Send(byte cmd, byte data1, byte data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
 
}

void RF12_Send(byte cmd, byte data1, byte data2) {
      RF12.send(cmd);
      RF12.send(data1);
      RF12.send(data2);
       
}
char button(char button_num) {
  return (!(digitalRead(button_num)));
}
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Aber so wie ich die RFM-Lib. verstanden habe muss ich die Daten in einen Payload packen, Damit sie hinterher auch wieder richtig ankommen.
Aber was macht dann die Demo ?
Quote
Mit dem Serial Demo für RFM12 kann mann serielle Daten senden. Aber dies funktioniert nur mit Daten die auf der Seriellen Schnittstelle empfangen werden.
Dann nimm diese Demo und sende halt was anderes als was von Serial kommt:
z.B. zum Spass
Code:
    if (Serial.available())
    {
       byte c = Serial.read();
       if ( c >='a' && c <= 'z' ) RF12.send( c & 0xDF ); // wandelt in grossbuchstaben vor dem senden
       else if (c >= 'A' && c <= 'Z' )  RF12.send( c | 0x20 ); // wandelt in kleinbuchstaben vor dem senden
       else if ( c >= '0' && c <= '9' ) RF12.send( c );   // Zahlen normal
       else RF12.send ( '.'); // Sonderzeichen ersetzen
       RF12.send ( 0x0d ); RF12.send ( 0x0a );   // und jedes Zeichen in eine neue Zeile
    }
Wie siehst du, dass die Demo funktioniert, was siehst du jetzt ? ( Wer empfängt deine RFM12 Signale ? )
Wie sehen Midi Daten aus ?   
    Midi_Send(0x90, note1,Velo);   erzeugt keinen lesbaren Text, wenn du SerialMonitor anschliesst, oder ?
Logged

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

Hallo Michael
Hier die Hardware
Sender: Arduino UNO mit RFM12 Funkmodul am SPI und Midi Buchse am TX Pin als Stromschleife. Software generiert Midi Signale nach Tastenabfrage und sendet sauber über die Serielle. Zusätzlich soll es die selben Signale über den RFM12 senden um das Gerät kabellos zu betreiben.

Empfänger: Jeenode usb (Arduino Clone mit RFM12 Funkmodul am SPI)  Midi Buchse am TX Pin. Software dieses Serial Demo.

über die Serielle wird gesendet:
Midi_Send(0x82, note5, 0x45)  0x82-Befehl Note on ,Note5- ein Wert zwischen 0 und 127 hier 55. 0x45 Velocity Wert zwischen 0 und 127 wird über Analog- read vom Potentiometer ausgelesen
Midi_Send(0x92, note5, 0x45)  0x92-Befehl Note off


void Midi_Send(byte cmd, byte data1, byte data2) {
  Serial.write(cmd); // 0x82 oder 0x92
  Serial.write(data1);// Wert zwischen 0 und 127
  Serial.write(data2);// Wert zwischen 0 und 127
}
Sendet dies über die Serielle an ein MIDI Interface.

Im Serial Monitor sehe ich auf der Senderseite bei 38400 baud für dieses Beispiel eine Zeichenfolge 5V5EAA als Ascii Zeichen.

Auf der Empfänger Seite  nichts.

Sendestrecke funktioniert, beide Platinen laufen mit dem PingPong Sketch.

Zielsetzung ist also: diese Daten über den RFM12 zu senden, auf der Empfängerseite zu empfangen und Seriell auszugeben.

Ich werde mal dein Beispiel probieren. Vielleicht muss ich ja auch auf der Empfängerseite eine andere Software benutzen.

Grüße Xboom
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vielleicht muss ich ja auch auf der Empfängerseite eine andere Software benutzen.

Oder dort auch einen SerialMonitor anschliessen...

Was macht der SerialMonitor eigentlich bei Zeichen > 127 ?  Hängt, - schätze ich -  vom default encoding ab.
Bei Windows sollte das dann irgendein ANSI Zeichen sein. 

Ist  " 5V5EAA " tatsächlich das was du gesehen hast ?
 6 Zeichen ist ja genau richtig, aber sonst ... ich hätte nach deiner Beschreibung als 3. und 6. Zeichen ein 'E' (0x45) erwartet. 
Oder war das das Ergebnis nach copy/paste in deinen Browser ? Oder passen die Baudraten nicht ?
Logged

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

Hallo Michael
Setup ist: Sender Arduino Uno, am Galaxy Tablet mit Serial Monitor bei 9600 Baud sehe ich 5V5EAA und direkt in der IDE bei 38400 auch 5V5EAA.
              Midi Monitor über ein Interface am Seriellen Pin zeigt korrekte Midi Daten an.

Empfänger hängt am Rechner bei 38400 Baud und dem Serial Monitor der IDE. 38400 ist die falsche Baudrate aber der Serial Monitor kann nicht auf 31250 Baud eingestellt werden.

Im Empfänger läuft das Serial Demo Sketch und empfängt manchmal das Zeichen y mehr nicht. Der Uno sendet also sauber über die Seriell aber vermutlich nicht über den RFM12

Beide Arduinos sind im Test auf 38400 Baud eingestellt.
Logged

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

Ich habe jetzt mal den Code etwas reduziert und den Sendeteil umgestellt.
Über die serielle ist alles in Ordnung.
Nur den RFM 12 kann ich nicht zum senden Bewegen.
Da sich die Mididaten für jede Taste ändern kann ich keine festen Werte im Payload deklarieren. Deshalb die Bytevariablen cmd, data1, data2
Diese Variablen müssen im Sendeteil in den Payload geschrieben werden. Und da liegt mein Problem. Ich habe auch die Variante für einen String probiert .
Der RFM will einfach nicht senden.
Code:
#include <Ports.h>
#include <RF12.h>
//#include <RF12sio.h>
#define BUTTON  9
#define Sendled  6

//*****************
// Variables
int switchState = HIGH;
int currentSwitchState = HIGH;
//static unsigned long payload;
byte needToSend;
//*******************************************************************
void setup() {
  
  Serial.begin (38400);  //(31250);     // Midi Baudrate
  Serial.print("\n[Midi Serial]");
  rf12_config();  
 // rf12_initialize(21, RF12_868MHZ, 8);
  pinMode(Sendled,OUTPUT);
  pinMode(BUTTON,INPUT);
  digitalWrite(BUTTON,HIGH);  
}
void loop () {
  //***********Variante  Pollen***************

  currentSwitchState = digitalRead(BUTTON); //switchPin6
  if( currentSwitchState == LOW && switchState == HIGH ) // push
    Midi_Send(0x90, 0x37, 0x45);
  if( currentSwitchState == HIGH && switchState == LOW ){ // release
    Midi_Send(0x80, 0x37, 0x45);

  }
  switchState = currentSwitchState;
  
}
//**********Pollen Ende***************


void Midi_Send(byte cmd, byte data1, byte data2) {
   digitalWrite(Sendled,HIGH);
typedef struct {
    byte cmd;//:8;    // Note on / off
    byte data1;//:8;  // Note Value
    byte data2;//:8;  // Note Velocity
}payload;

   if (needToSend && rf12_canSend()) {
       needToSend = 0;
   rf12_sendStart(0, &payload, sizeof payload);
   rf12_sendWait(1);
   }    
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
  
  digitalWrite(Sendled,LOW);

}

char button(char button_num) {
  return (!(digitalRead(button_num)));
}

Hier wird nur 1 Taste abgefragt und sendet beim drücken :

0x90= Note on/ Midi Kanal 1
0x37= Note 55
0x45= velocity 67
beim loslassen:
0x80= Note off/ Midi Kanal 1
0x37= Note 55
0x45= velocity 67

Sendeaktivität wird mit einem HF Meter überprüft zusätzlich ein Jenoode am Tablet mit USB-Monitor

Grüße Xboom
« Last Edit: August 22, 2012, 12:27:55 pm by xboom » Logged

Pages: [1]   Go Up
Jump to: