Forum: Mikrocontroller und Digitale Elektronik Umwandlung von Bascomcode in C (Midi)


von Fabian F. (fabiii9)


Lesenswert?

Hallo zusammen,

ich habe einen Bascom Code.
Allerdings möchte ich in C Programmieren, weil ich gehört habe, dass das 
viel besser ist.

Ich fang gerade an, und habe ein bisschen Erfahrung.

Bascom-Code:
1
$regfile = "m8def.dat"                                      ' ATMEGA8
2
$crystal = 1000000                                          ' 1 MHz
3
$baud = 31250                                               ' MIDI-Baudrate (31,25kBit)
4
5
Taster Alias Pind.2
6
7
Dim Keydown As Byte                                         ' Tasten-Merker
8
9
Init:
10
  Ddrd.1 = 1                                                ' Sendeleitung auf Output
11
  Portd.2 = 1                                               ' internen Pull-Up aktivieren für Taster
12
13
Main:
14
  Do
15
    If Taster = 0 Then
16
      If Keydown = 1 Then
17
        Gosub Sendmidinoteon
18
        Keydown = 0
19
      End If
20
    Else
21
      If Keydown = 0 Then
22
        Gosub Sendmidinoteoff
23
        Keydown = 1
24
      End If
25
    End If
26
  Loop
27
  End
28
29
Sendmidinoteon:
30
  Print Chr(&B10010001);                                    ' NOTE-ON-Command
31
  Print Chr(65);                                            ' Tasten-Nummer 69 (A4)
32
  Print Chr(100);                                           ' Key-Down-Velocity 100
33
Return
34
35
Sendmidinoteoff:
36
  Print Chr(&B10000001);                                    ' NOTE-OFF-Command
37
  Print Chr(65);                                            ' Tasten-Nummer 69 (A4)
38
  Print Chr(0);                                             ' Release-Velocity 0 (Default)
39
Return

Habe jetzt schonmal angefangen, ihn umzuwandeln, doch an manchenstellen 
weis ich einfach nicht weiter. Ich weis auch nicht wie ich danach 
googlen soll.
1
/*
2
 * GccApplication1.c
3
 *
4
 * Created: 09.02.2014 15:04:14
5
 *  Author: Fabian
6
 */ 
7
8
9
#include <avr/io.h>
10
#define F_CPU 20000000U;
11
12
int Keydown1 = 0;
13
14
int main(void)
15
DDRD  &= ~ (1<<PD2);
16
17
{
18
    while(1)
19
    {
20
        if ( PIND & ( 0<<PIND2 ) )//wenn PortD.4 Taster gedrückt. (Wird auf Masse gedrückt)
21
        {
22
         if (Keydown1 == 1)            //wenn Keydown1 auf 1
23
         {
24
          
25
         Keydown1 = 0;
26
         }
27
        }
28
        else {
29
          if (Keydown1 == 0)            //wenn Keydown1 auf 0
30
          {
31
            //Gosub noteoff
32
        Keydown1=1              //Keydown1 = 1
33
          }
34
        }
35
    }
36
}

Wäre echt dankbar, wenn mir jemand helfen könnte.

Vielen Dnk
Gruß
Fabi

von Fabian F. (fabiii9)


Lesenswert?

keiner eine Idee????

von Peter II (Gast)


Lesenswert?

Fabian Müller schrieb:
> keiner eine Idee????

wo ist denn eine Frage?

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

das was du suchen solltest für C sind "Funktionsaufrufe"

von Fabian F. (fabiii9)


Lesenswert?

Hallo,

vielen Dank für eure Antworten.

Ich suche einen Code für c was deisem Code in Bascom entspricht:
1
Sendmidinoteon:
2
  Print Chr(&B10010001);                                    ' NOTE-ON-Command
3
  Print Chr(65);                                            ' Tasten-Nummer 69 (A4)
4
  Print Chr(100);                                           ' Key-Down-Velocity 100
5
Return
6
7
Sendmidinoteoff:
8
  Print Chr(&B10000001);                                    ' NOTE-OFF-Command
9
  Print Chr(65);                                            ' Tasten-Nummer 69 (A4)
10
  Print Chr(0);                                             ' Release-Velocity 0 (Default)
11
Return


Vielen DAnk
Gruß
Fabi

von Peter II (Gast)


Lesenswert?

Fabian Müller schrieb:
> Ich suche einen Code für c was deisem Code in Bascom entspricht:

was macht Print in Bascom? Wohin wird dort etwas ausgeprintet?

von D. V. (mazze69)


Lesenswert?

Peter II schrieb:
> was macht Print in Bascom? Wohin wird dort etwas ausgeprintet?

UART

von Peter II (Gast)


Lesenswert?

D. V. schrieb:
> Peter II schrieb:
>> was macht Print in Bascom? Wohin wird dort etwas ausgeprintet?
>
> UART

dafür gibt es nichts fertiges in C. du musst also erst mal die Uart 
initialisieren und dann jedes Zeichen einzeln Versenden.

Beispiele für C stehen im Datenblatt vom Controller.

von Fabian F. (fabiii9)


Angehängte Dateien:

Lesenswert?

Halo,
oh ja sorry hatte meinen Schaltplan ganz vergessen.

Da wird ein Midisignal erzeugt.
Das Signal lese ich dann über einen Midi-USB Konverter ein.

Vielen Dank
Gruß
Fabi

von Rene Z. (renezimmermann)


Lesenswert?

ungetestet, da ich nicht zu Hause bin:
1
#include <avr/io.h> 
2
#define F_CPU 1000000              // 1 MHz
3
#define BAUD 31250                // MIDI-Baudrate (31,25kBit)
4
#include <util/setbaud.h>
5
6
#define Taster PD2
7
uint8_t Keydown;
8
 
9
void uart_init(void){
10
  UBRRH = UBRRH_VALUE;
11
  UBRRL = UBRRL_VALUE;
12
  #if USE_2X                  // U2X-Modus erforderlich
13
    UCSRA |= (1 << U2X);
14
  #else                    // U2X-Modus nicht erforderlich
15
    UCSRA &= ~(1 << U2X);
16
  #endif
17
  UCSRB |= (1<<TXEN);              // UART TX einschalten
18
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1  
19
}
20
21
void uart_putc(unsigned char c){
22
    while (!(UCSRA & (1<<UDRE))){}        // warten bis Senden moeglich
23
    UDR = c;                  // sende Zeichen
24
}
25
26
void Sendmidinoteon(void){
27
  uart_putc(145);                // NOTE-ON-Command
28
  uart_putc(65);                // Tasten-Nummer 69 (A4)
29
  uart_putc(100);                // Key-Down-Velocity 100
30
}
31
void Sendmidinoteoff(void){
32
  uart_putc(129);                // NOTE-OFF-Command
33
  uart_putc(65);                // Tasten-Nummer 69 (A4)
34
  uart_putc(0);                // Release-Velocity 0 (Default)
35
}
36
37
int main(void){
38
  uart_init();                // Uart initialisieren
39
  DDRD |= (1<<PD1);              // PD1 Output
40
  PORTD |= (1<<Taster);            // am Tastereingang Pullup an 
41
  while(1){                  // Endlosschleife
42
    if(!(PIND & (1<<Taster))){        // wenn Taste gedrueckt
43
      if(Keydown = 1){
44
        Sendmidinoteon();
45
        Keydown = 0;
46
      }
47
    }
48
    else{                  // wenn Taste nicht gedrueckt
49
      if(Keydown = 0){
50
        Sendmidinoteoff();
51
        Keydown = 1;
52
      }
53
    }
54
  }                      // Ende Endlosschleife
55
}

von Fabian F. (fabiii9)


Lesenswert?

Hallo,
vieeeeelen, vielen Dank !!!!!

Werde es morgen ausprobieren.

Gruß Fabi

von Fabian F. (fabiii9)


Lesenswert?

Hallo zusammen,
Habe den Code gerade ausprobiert.
Der Code funktioniert nicht ganz.
Wenn ich den Taster betätige werden mehrere Note-on Befehle gesendet bis 
ich wieder loslasse.

Es sollte aber beim Tastendruck nur einmal ein Note-on Befehl gesndet 
werden und wenn ich loslasse sollte ein note-off Befehl gesendet werden.

Auf jedenfall funktioniert es, dass ein Midibefehl gesendet wird und vom 
Computer auch als solcher verstanden wird.


Vielen Dank nochmal für deinen Code.

Wäre super, wenn euch was einfällt was falsch ist.

Habe jetzt schon länger rumgedoktert, komm aber einfach nicht drauf.

Vielen Dank
Gruß
Fabi

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Fabian Müller schrieb:

Zunächst mal:
Du solltest dir ein gewisses Grundwissen an C aneignen.
Und zwar BEVOR du an ein konkretes Projekt gehst. Denn sonst 
verzweifelst du an blödsinnigen Fehlern.
1
    if(!(PIND & (1<<Taster))){        // wenn Taste gedrueckt
2
      if(Keydown = 1){
3
        Sendmidinoteon();
4
        Keydown = 0;
5
      }
6
    }
7
    else{                  // wenn Taste nicht gedrueckt
8
      if(Keydown = 0){
9
        Sendmidinoteoff();
10
        Keydown = 1;
11
      }
12
    }

Eine Zuweisung schreibt sich in C mit einem einfachen =.
Ein Vergleich auf Gleichheit schreibt sich mit einem doppelten ==.

Also
1
    if(!(PIND & (1<<Taster))){        // wenn Taste gedrueckt
2
      if(Keydown == 1){
3
        Sendmidinoteon();
4
        Keydown = 0;
5
      }
6
    }
7
    else{                  // wenn Taste nicht gedrueckt
8
      if(Keydown == 0){
9
        Sendmidinoteoff();
10
        Keydown = 1;
11
      }
12
    }

Gerade in der µC Programmierung sollte man aber meiner Meingung nach 
weitgehend auf derartig explizite Vergleiche verzichten. Die haben 
nämlich ein gewisses Potential falsch gemacht zu werden.
Im konkreten Fall, mit der Variablen 'Keydown' geht das so: Wir wissen, 
dass diese Variable nur 2 Zustände haben kann. Entweder die ist 0 (was 
soviel wie 'nicht gedrückt' bedeutet wie der Name der Variablen schon 
sagt - es ist nicht wahr, dass die Taste gedrückt ist; ergo ist sie 
nicht gedrückt), oder sie ist es nicht (dann ist die Taste gedrückt, 
ebenfalls wie es der Variablenname aussagt - es ist wahr, dass die Taste 
gedrückt ist). Und genau so sollte man das auch schreiben und dabei 
ausnutzen, dass in C alles was ungleich 0 ist, als logisch wahr gewertet 
wird. Nur eine 0 gilt als logisch falsch.

D.h. man kann das auch so schreiben
1
    if(!(PIND & (1<<Taster))){        // wenn Taste gedrueckt
2
      if( Keydown ){
3
        Sendmidinoteon();
4
        Keydown = 0;
5
      }
6
    }
7
    else{                  // wenn Taste nicht gedrueckt
8
      if( !Keydown ){
9
        Sendmidinoteoff();
10
        Keydown = 1;
11
      }
12
    }

das liest sich dann gleich auch viel besser, denn
1
      if( !Keydown ){
'übersetzt' sich in normales Deutsch als
"wenn die Taste nicht gedrückt ist".

BZw. da steht dann
1
      if( Keydown ){
oder eben in normalem Deutsch
"Wenn die Taste gedrückt ist".

Die zusätzlichen Vergleiche mit == 1 bzw. == 0, bringen hier keinerlei 
zusätzliche Klarheit und bringen nur zusätzliches Fehlerpotential mit 
sich. Wähle deine Variablennamen in solchen Fällen immer so, dass sich 
ein
1
   if( variable )
unmittelbar durch Einsetzen des Variablennamens in einen vernünftigen 
deutschen Satz übersetzt, der genau dann wahr ist, wenn die Variable den 
Wert 1 hat. BZw. so, dass die Negation davon
1
   if( ! variable )
genau dann wahr ist, wenn die Variable den Wert 0 hat.
Auf lange Sicht gesehen machst du so wesentlich weniger Fehler und das 
Programm wird um einiges leichter verstehbar beim Code-lesen. Der erste 
Schritt - einen ordentlichen Variablennamen - ist schon gemacht worden. 
Jetzt muss man nur noch über seinen Schatten springen, und das ganze als 
boolsche Variable ansehen, die in sich selbst bereits auch ohne 
zusätzlichen Vergleich eine Information trägt.

> Wäre super, wenn euch was einfällt was falsch ist.

Besorg dir ein C-Buch und fang auf dem PC an, die Grundlagen von C zu 
trainieren. Ansonsten fällst du unweigerlich immer wieder unnötigerweise 
auf die Schnauze und alles dauert 10 mal so lang, als wenn du erst mal 
ein paar Tage investierst.

: Bearbeitet durch User
von Fabian F. (fabiii9)


Lesenswert?

Hallo zusammen,

super das war der Fehler.

eigentlich wusste ich schon, dass man == setzen muss.
hab aber einfach drüber gelesen.

Aber danke für den Tipp mit der boolschen methode.

Werde es einbauen.

Gruß
Fabi

von Fabian F. (fabiii9)


Lesenswert?

Hallo,

da bin ich leider schon wieder.

Tut mir echt leid. Aber jetzt weis ich grad wirklich nicht was abgeht. 
:)

Wollte jetzt den Code umschreiben auf mehrere (2) Taster.

Doch leider sendet er jetzt ein Midisignal noteon 69, ohne das ich 
drücke.
Er sendet einfach die ganze Zeit durch.

Was hab ich jetzt falsch gemacht.

Weis echt nicht was da flasch sein könnte.

Vielen Dank.
Danach hab ich es fast geschafft.
Hoffe ich brauche euch so schnell nciht mehr.

Vielen Dank
Gruß
Fabi
1
#include <avr/io.h>
2
#define F_CPU 1000000              // 1 MHz
3
#define BAUD 31250                // MIDI-Baudrate (31,25kBit)
4
#include <util/setbaud.h>
5
6
#define Taster PD2
7
#define Taster1 PD3
8
uint8_t Keydown;
9
uint8_t Keydown1;
10
11
void uart_init(void){
12
  UBRRH = UBRRH_VALUE;
13
  UBRRL = UBRRL_VALUE;
14
  #if USE_2X                  // U2X-Modus erforderlich
15
  UCSRA |= (1 << U2X);
16
  #else                    // U2X-Modus nicht erforderlich
17
  UCSRA &= ~(1 << U2X);
18
  #endif
19
  UCSRB |= (1<<TXEN);              // UART TX einschalten
20
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
21
}
22
23
void uart_putc(unsigned char c){
24
  while (!(UCSRA & (1<<UDRE))){}        // warten bis Senden moeglich
25
  UDR = c;                  // sende Zeichen
26
}
27
28
void Sendmidinoteon(void){
29
  uart_putc(145);                // NOTE-ON-Command
30
  uart_putc(65);                // Tasten-Nummer 69 (A4)
31
  uart_putc(100);                // Key-Down-Velocity 100
32
}
33
void Sendmidinoteoff(void){
34
  uart_putc(129);                // NOTE-OFF-Command
35
  uart_putc(65);                // Tasten-Nummer 69 (A4)
36
  uart_putc(0);                // Release-Velocity 0 (Default)
37
}
38
void Sendmidinoteon1(void){
39
  uart_putc(145);                // NOTE-ON-Command
40
  uart_putc(69);                // Tasten-Nummer 69 (A4)
41
  uart_putc(100);                // Key-Down-Velocity 100
42
}
43
void Sendmidinoteoff1(void){
44
  uart_putc(129);                // NOTE-OFF-Command
45
  uart_putc(69);                // Tasten-Nummer 69 (A4)
46
  uart_putc(0);                // Release-Velocity 0 (Default)
47
}
48
49
int main(void){
50
  uart_init();                // Uart initialisieren
51
  DDRD |= (1<<PD1);              // PD1 Output
52
  PORTD |= (1<<Taster);            // am Tastereingang Pullup an
53
  while(1){                  // Endlosschleife
54
      if(!(PIND & (1<<Taster))){        // wenn Taste gedrueckt
55
        if( Keydown ){
56
          Sendmidinoteon();
57
          Keydown = 0;
58
        }
59
      }
60
      else{                  // wenn Taste nicht gedrueckt
61
        if( !Keydown ){
62
          Sendmidinoteoff();
63
          Keydown = 1;
64
        }
65
      }
66
      if(!(PIND & (1<<Taster1))){        // wenn Taste gedrueckt
67
        if( Keydown1 ){
68
          Sendmidinoteon1();
69
          Keydown1 = 0;
70
        }
71
      }
72
      else{                  // wenn Taste nicht gedrueckt
73
        if( !Keydown1 ){
74
          Sendmidinoteoff1();
75
          Keydown1 = 1;
76
        }
77
      }
78
  }                      // Ende Endlosschleife
79
}

von Karl H. (kbuchegg)


Lesenswert?

>   PORTD |= (1<<Taster);            // am Tastereingang Pullup an

Und was ist mit dem Pullup am Taster1 ?

von Karl H. (kbuchegg)


Lesenswert?

Im übrigen sind wir jetzt genau so weit.

Der Weg, den du gerade versuchst, ist genau der Weg den man nicht geht.
Man dupliziert nicht einfach den Code jetzt für alle Taste bzw. Noten.
Sondern man überlegt sich eine Datenstruktur bzw. eine Kombination mit 
einem Array, so dass EIN kurzer Code alle Tasten behandeln kann.
Anstelle von also 88 mal denselben Code für alle 88 Tasten, kommt EIN 
Codestück, welches in einer Schleife alle 88 Tasten abarbeitet.


Denn sonst hättest du auch bei BASCOM bleiben können.
Ob man jetzt in BASCOM oder in C einen Fortran-Code produziert, schenkt 
sich nichts. Es ist und bleibt Fortran Code.

: Bearbeitet durch User
von Fabian F. (fabiii9)


Lesenswert?

Hallo,

vielen Dank für eure weiteren Anregungen.
Der Pullup war das Problem.

Vielen Dank für die Anregung mit dem Array.

Muss den Code eh noch umschreiben auf Schieberegister (Brauch am Ende 
200 Tasten). Da werde ich ein Array sicher einbauen.

Hoffe ich bekomm das mit dem Schieberegister hin.

Werde jetzt mal viel googlen.
Der Code war nur ein Test-Code.

Vielen Dank
Gruß
Fabi

von CBRler (Gast)


Lesenswert?

Hallo Karl-Heinz,


"Denn sonst hättest du auch bei BASCOM bleiben können."

Unter Bascom gibt's keine Array's ?????

Das ist ja wohl jetzt mal Quatsch, Sorry....

Wenn ich den Programmieraufwand unter C sehe, nur um Midi-Signale von 
einer Tastatur auszugeben, muss ich einfach schmunzeln....

Dass habe ich persönlich schon in den Achzigern auf einem Atari 520ST
mit GFK-Basic programmiert. Der war seinerzeit auch mit einer 
MIDI-Schnittstelle bestückt.

cu

CBRler

von Karl H. (kbuchegg)


Lesenswert?

CBRler schrieb:
> Hallo Karl-Heinz,
>
>
> "Denn sonst hättest du auch bei BASCOM bleiben können."
>
> Unter Bascom gibt's keine Array's ?????

Strukturen!
Strukturen!

Die Kombination aus Pin, zu versendenden Notenwert und Tastenzustand 
fasst man sinnvollerweise in einer Struktur zusammen und macht dann ein 
Array daraus.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.