Show Posts
Pages: [1]
1  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: March 07, 2013, 12:40:40 pm
Habe jetzt explizit in einem VB- Forum nachgefragt und kam auf die Lösung
Code:
Serial.Write(Convert.ToChar(Lm1))
.

Danke für eure Hilfe.


Gruß,
Se11001
2  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 28, 2013, 10:34:23 pm
Ok, danke für die Info - hätte ich mir auch denken können. Ich dachte solange kein " " verwendet wird, wird der Wert an sich gesendet.

Hm, die Funktion Chr(x) scheint nicht existent zu sein? smiley-slim (Verwende VB2010 Express)

3  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 28, 2013, 12:24:01 pm
Ja schon, aber ich verbinde ja nur einmal und da stören die 200ms nicht wirklich.

Ich habe nun das VB Programm so verändert, dass ich einfach mit Serial.Write arbeite, und siehe da - es kommt etwas an:

Code:
             Serial.DiscardOutBuffer()
            Serial.Write("P")
            Serial.Write(Lm1)
            O1.Text = Lm1

            Serial.DiscardOutBuffer()
            System.Threading.Thread.Sleep(15)

            V = Analogwert.Value
            Serial.Write("V")
            Serial.Write(V)
            O2.Text = V

            System.Threading.Thread.Sleep(15)

...

Das "Analogwert.Value" ist ein Slider fürs Debuggen, somit kann ich einen beliebigen Wert einstellen.

Der Arduino empfängt jetzt die Buchstaben korrekt und kann so die übertragenen Werte schon richtig zuordnen. Einziges Problem ist, dass die Werte nicht korrekt übertragen werden. Zum Testen habe ich das Programm am Arduino so angepasst, dass er den eingelesenen Wert wieder zurück an den PC schickt. Übertrage ich zum Arduino 0, kommt 48 zurück, bei 1 kommt 49, das geht bis 9 - 57 ab dann kommt immer 48 zurück. Ab undzu springt es auch auf 255.

 Wo kann hier noch der Fehler liegen?

4  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 28, 2013, 11:43:44 am
Hm, müsste das nicht eigentlich egal sein? Ist eine If Bedingung erfüllt, werden die inputChar[] Bytes ja auch nur "angschaut" und in eine andere Variable kopiert, und ansonsten nichts gemacht.
5  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 28, 2013, 09:40:32 am
Aber klar doch, wenn ich als Bedingung festlege dass ein bestimmter Wert eingelesen wurde, dazwischen nicht neu eingelesen wird und ich anschließend nach einem anderen Wert abfrage, kann diese Bedingung nie erfüllt werden, danke.

Nun habe ich den Arduino Sketch folgendermaßen angepasst:
Code:
void loop()

{
  if (inputChar[0]=='w'){                    // Wenn wir an erster Stelle ein "w" empfangen, möchte der PC wissen, ob wir wirklich
    Serial.println("I am a drivers desk");   // der Arduino  für das Fahrpult sind. Das bestätigen wir mit "I am a drivers desk""
    if (inputChar[1]=='w'){                  // Wenn an zweiter Stelle ebenfalls ein "w" kommt, sollen wir akustisch quitieren
      tone(5, 1000, 100);
      delay(200);
      tone(5, 1000, 100);
    }
  }
 
    
  if (inputChar[0] == 'P'){                  // "P" für PZB, stellvertretend für alle Leuchtmelder
  LmPZB(inputChar[1]);                       // Funktion siehe unten
  }
  
  if (inputChar[0] == 'V'){                  // "V" für Geschwindigkeit
    n=2*inputChar[1];
    periode=speed[n];                        // Aus dem Array "speed" wird die entsprechende Periodendauer für die aktuelle Geschwindigkeit gewählt
  }
  
  
  if (inputChar[0] == 'H'){                  // "H" für Hauptluftbehälter
      servoHLB.write(127-inputChar[1]);      // Wir weisen dem entsprechenden Servoobjekt seinen Wert zu
  }
  
  if (inputChar[0] == 'M'){                  // "M" für Motorstrom
    analogWrite(2,255-(2*inputChar[1]));     // Wir geben den Wert von 0 - 255 PWM an Pin 2,3 aus
    analogWrite(3,255-(2*inputChar[1]));
    }
    
  if (inputChar[0] == 'N'){                  // "N" für Primärstrom
    analogWrite(9,255-(2*inputChar[1]));     // Wir geben den Wert von 0 - 255 PWM an Pin 4 aus
    }    
    
  if (inputChar[0] == 'X')                   // "X" - Stunde
  {                  
    h0 = inputChar[1]/10;                    // Aufspalten in 2 Ziffern
    h1 = inputChar[1]%10;
  }
  
  if (inputChar[0] == 'Y')                   // "Y" - Minute
  {      
    m0 = inputChar[1]/10;                    // Aufspalten in 2 Ziffern
    m1 = inputChar[1]%10;  
  }
  //displayDigits();  
  
  
  
   if (inputChar[0]=='i'){                    // Wenn wir an erster Stelle ein "w" empfangen, möchte der PC wissen, ob wir wirklich
   Serial.println("readytosend");  
   if (inputChar[1]=='i')
   {Input();
   }
 }  
}

Im VB Programm sende ich die Datenpakete im 15ms Takt:
Code:
      If +Serial.IsOpen Then


            Lm1 = CByte(44)
            OutChar(0) = 81     'P
            OutChar(1) = CByte(Math.Round(29))
            Serial.Write(OutChar, 0, 2)
            O1.Text = Lm1

            System.Threading.Thread.Sleep(15)

            OutChar(0) = 86     'V  Der Buchstabe der Variable wird an den Arduino gesendet, damit er weiß was kommt.
            OutChar(1) = V      'Der gespeicherte Wert wird gesendet
            Serial.Write(OutChar, 0, 2)
            O2.Text = V

            System.Threading.Thread.Sleep(15)

            OutChar(0) = 46     'B
            OutChar(1) = B
            Serial.Write(OutChar, 0, 2)
            O3.Text = B
...

Eigentlich sollte der Arduino loop ja wesentlich schneller durchlaufen werden als die 15ms aus dem VB Programm und somit jeder Wert eingelesen werden, nun kommt aber trotzdem nichts an beim Arduino.
6  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 28, 2013, 05:01:04 am
Quote
Entschuldige, willst du testen; ob jemand so lange sketches auch nur anschaut ?
Das war ja auch der Grund, warum ich anfangs nur die relavanten Teile gepostet hatte, weil der Sketch eben sehr lang ist.

Wie erwähnt hatte diese Variante mit dem Ankündigungs- und Datenbyte bereits funktioniert, nur eben nicht auf Timerbasis.

Quote
Serial.println() wartet nicht auf eine Antwort, das if in Zeile 6 kann nie true sein
Sorry, ich verstehe nicht ganz, was das Serial.println() mit dem if in Zeile 6 zu tun hat. Das if aus Zeile 3 ist da ja bereits erfüllt.
Wie kann ich alternativ dafür sorgen, dass der Arduino weiß, welcher Wert übertragen werden soll?

Sorry wenn ich hier jemanden nerve, aber mir fällt derzeit einfach keine Lösung für das Problem ein.  smiley-red


Gruß,
Se11001
7  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 27, 2013, 03:29:00 pm
Quote
Soviel ich weiss, ist das keine Interrupt-Routine, sondern kommt zwischen 2 loop() dran, hab ich aber selbst keine Erfahrung mit.
Ja, das hat mit dem Interrupt auch nichts zu tun.

Quote
Du liest also immer 2 Buchstaben. Falls da irgendein unsynchroniserter Schrott kommt (irgendwann mal gekkommen ist ), wird das ohne Kommentar ignoriert
Aber wenn der PC nichts mehr sendet, sollte alles sich beruhigen und es danach wieder gehen.
Naja, aber ich lese ja nur, wenn die Verbindung beidseitig bestätigt wurde und übernommen wird der Wert auch nur wenn als erstes Byte ein definierter Buchstabe kommt.


Quote
Dein Sketch kann ja eine ganze Reihe von Funktionen, gehen denn alle ausser "oo" ?
Ansonsten funktioniert eigentlich alles, es bedarf lediglich noch einer Anpassung; wenn denn einmal Daten übertragen würden.  smiley-confuse


Quote
Da ist in deinem Sketch in Zeile 130 aber auch offensichtlich was verloren gegangen ...
Stimmt, im alten Sketch waren hier 2 Befehle vertauscht. War nicht die neueste Version, die ich vorhin angehängt habe.
8  International / Deutsch / Re: Problem mit Datenübertragung zum PC on: February 27, 2013, 12:26:05 pm
Hallo nochmals!

Da beide Programme relativ lang sind, habe ich mal nur ein paar Schnipsel gepostet, es sind jetzt aber beide Codes im Anhang.


Die Oberfläche des VB Programms sieht folgendermaßen aus:

Die eingelesenen Bytes werden direkt auf der rechten Seite angezeigt, und nehmen auch die Werte an, die vom Pult kommen.

Quote
Oder dass genau dieses If erfüllt ist ?
If Serial.ReadLine() = "ready" & System.Text.Encoding.UTF8.GetString({13}) Then
Das meinte ich damit, die Verbindung an sich wird ja erfolgreich hergestellt und läuft auch stabil. (in die eine Richtung)
Da die Verbindungsaufbau ja beim Einlesen der Werte und beim Verbinden des Arduinos nach dem verwendeten Prinzip ja funktioniert (lediglich mit unterschiedlichen Zeichen), glaube ich nicht dass es am println() liegt.

Quote
Warum hast du keinen Fehlerhinweis im Else zu diesem If ?
Mache ich gleich!

Quote
Deinen Verdacht auf Pufferüberlauf mit einem starren Timer anzugehen verstehe ich übrigens nicht.
Bei so schönen Dialogen zwischen den zweien ...
War nur meine Vermutung, jedenfalls fror das Programm ein nach ein paar Sekunden und ich musste die USB Verbindung neu herstellen.


Quote
Hast du auch einen Test-Modus, der nicht alle 200ms was rausballert, und statt dessen auf dem PC anzeigt, was gesendet wurde und was empfangen wurde ?
Gut, ich kann mal versuchen anstatt des Timers eine Schaltfläche zu benutzen. Was empfangen wurde, wird ja bereits angezeigt.



9  International / Deutsch / Problem mit Datenübertragung zum PC on: February 27, 2013, 09:47:25 am
Hallo,

ich stehe bei meinem Projekt derzeit vor einem Problem, das ich nicht lösen kann.

Zuerst einmal die prinzipielle Aufgabe des Arduino bei meinem Projekt:
Ich will damit Digital- und Analogwerte von einem Pult an den PC schicken, als auch Daten an das Pult schicken, um diese dort als Digital- oder Analogwert auszugeben. Dafür schicke ich 4 Byte vom Pult zum PC, und ca. 8 Byte vom PC zum Pult. Als Schnittstelle am PC dient ein VB Programm, welches die Werte für das Pult von einem TCP-Server bezieht, für das Problem aber gar nicht ausschlaggebend. Ich erstellte zu Beginn ein Programm, das die Werte nur zum Pult schickte, und zwar immer dann, wenn die Werte von der TCP Verbindung aktualisiert wurden. Das funktionierte ganz Ok, nur brachte dieses nicht genau festlegbare Intervall mit sich, dass das Programm am PC bei Übertragung in beide Richtungen nicht stabil lief, da die Werte vom Pult zum PC immer genau alle 200ms gesendet wurden (Timer im VB Programm.) Ich vermute mal dass sich aufgrund der nicht synchronisierten Intervalle der Puffer füllte.
Um dieses Problem zu umgehen, wollte ich die Kommunikation nun in beide Richtungen vom Timer bestimmt ablaufen lassen. Dazu habe ich die Werte von der TCP Verbindung als Variablen gespeichert, um sie dann wenn sie gebraucht werden, zu übertragen. Nun allerdings kann ich zwar Daten vom Arduino zum PC übertragen, das auch stabil, jedoch funktioniert die Übertragung in die andere Richtung nicht mehr - die Routine zur Verbindungsherstellung ist jedoch in beide Richtungen dieselbe.

Ich hoffe die Problematik ist grundsätzlich verständlich, hier nun der VB - und Arduino Code:



Als erstes stelle ich eine Verbindung her, welche vom Arduino auch erfolgreich mit "ready" bestätigt wird:
VB:
Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If Serial.IsOpen
            Serial.WriteLine("oo")      '"oo" für "output"
            System.Threading.Thread.Sleep(50)
Arduino (in Loop):
Code:
 
   if (inputChar[0]=='o'){                    // Der PC will Werte zum Arduino ausgeben, es wird mit "ready" bestätigt
   Serial.println("ready");   
   if (inputChar[1]=='o')
Die letzte if Bedingung wird auch erfüllt, das konnte ich bereits herausfinden. Nun sollen die Daten übertragen werden, in derselben Struktur wie es schon erwähnt bei direkter Übertragung beireits funktioniert hat - nur dass sie eben nicht direkt von der TCP Verbindung aus gesendet werden, sondern vorher in Variablen gespeichert wurden.
An der Speicherung der Werte dürfte es aber auch nicht liegen, ich habe auch schon versucht anstatt der gespeicherten Werte direkt Zahlen mit CByte(<zahl>) zu übertragen, auch erfolglos.

Damit der Arduino die Bytes unterscheiden kann, schicke ich als erstes einen Buchstaben zur Identifikation, anschließend die Information selbst. Also hier der Übertragungsteil im VB Programm:
Code:
            If Serial.ReadLine() = "ready" & System.Text.Encoding.UTF8.GetString({13}) Then

                OutChar(0) = 86     'V  Der Buchstabe der Variable wird an den Arduino gesendet, damit er weiß was kommt.
                OutChar(1) = V      'Der gespeicherte Wert wird gesendet
                Serial.Write(OutChar, 0, 2)

                OutChar(0) = 80     'P
                OutChar(1) = Lm1
                Serial.Write(OutChar, 0, 2)

                OutChar(0) = 72     'H
                OutChar(1) = H
                Serial.Write(OutChar, 0, 2)

                ....

            End If
...und zum Empfang der Daten im Arduino Programm:
Code:
  {
 
  if (inputChar[0] == 'V'){                  // "V" für Geschwindigkeit
    n=2*inputChar[1];
    periode=speed[n];                        // Aus dem Array "speed" wird die entsprechende Periodendauer für die aktuelle Geschwindigkeit gewählt
  }
 
  if (inputChar[0] == 'P'){                  // "P" für PZB, stellvertretend für alle Leuchtmelder
  LmPZB(inputChar[1]);                       // Funktion siehe unten
  } 

Dasselbe noch für die Übertragung zum PC - hier funktioniert alles einwandfrei und die Daten kommen auch beim PC an:
Code:
            'Einlesen der Werte vom Arduino

            Serial.WriteLine("ii")      '"ii" für "input"
            System.Threading.Thread.Sleep(50)
            If Serial.ReadLine() = "readytosend" & System.Text.Encoding.UTF8.GetString({13}) Then
Ist eine Verbindung da, werden die 4 Bytes vom Arduino eingelesen:
Code:

                INa = Serial.ReadByte() 'Byte 0 - Digitaleingabe I
                INb = Serial.ReadByte() 'Byte 1 - Digitaleingabe II
                INc = Serial.ReadByte() 'Byte 2 - Analogwert Fahrschalter
                INd = Serial.ReadByte() 'Byte 3 - Analogwert FbV

Zusätzlich noch die Ausgbe am Bildschirm:
Code:
                Byte1.Text = INa
                Byte2.Text = INb
                Byte3.Text = INc
                Byte4.Text = INd         'Ausgabe am Bildschirm FbV


Ich hoffe es kennt sich hier jemand auch in VB aus und kann mir bei der Problematik behilflich sein - wie gesagt, ich kann mir nicht erklären, wieso keine Daten übertragen werden können.


Gruß,
Se11001
10  International / Deutsch / Re: Problem mit Interrupt für Motoransteuerung on: November 15, 2012, 12:08:54 am
An welchem Timer hängen eigentlich Deine PWM Pins? Nicht etwa zufällig am Timer 1 den Du gerade anderweitig verwendest?
Das habe ich nicht bedacht und war auch der Fehler, Pin 11 und 12 hängen ja an Timer 1. Nachdem ich die Belegung auf die Pins 6,7,8 (also Timer4) geändert habe, funktioniert es nun wunderbar!

Ich nehme mal an Du hast einen Arduino UNO.
Nein, es ist ein Arduino Mega, hätte ich vorher erwähnen sollen. Mit dem ersten Programm lief es ja an den selben Pins.

Vielen dank für eure rasche Hilfe!


Gruß,
Se11001
11  International / Deutsch / Problem mit Interrupt für Motoransteuerung on: November 14, 2012, 03:17:10 pm
Hallo!

Ich bin derzeit dabei einen 24V Synchronmotor mittels 3 Phasen PWM anzusteuern, zur Spannungs- und Stromverstärkung verwende ich eine Platine mit 3 Halbbrücken mit dem IR2104.

Das funktioniert soweit ganz gut und ich habe testweise folgendes Programm geschrieben:

Code:
int n = 0;
int x = 0;
int r[16] = {64,88,109,123,128,123,109,88,64,40,19,5,0,5,19,40};   
int s[16] = {119,103,81,56,32,13,2,1,9,25,47,72,96,115,126,127};
int t[16] = {9,1,2,13,32,56,81,103,119,127,126,115,96,72,47,25};    //Diese drei Arrays enhalten die vorberechneten Sinusschwingungen, jeweils um 120° phasenverschoben.
int rpin = 10;
int spin = 11;
int tpin = 12;


void setup() {
  pinMode(rpin, OUTPUT);
  pinMode(spin, OUTPUT);
  pinMode(tpin, OUTPUT);
}

void loop() {   
if(x>=25)       //Ändere ich diesen Wert, so verändert sich die Drehzahl des Motors (kleiner => schneller, größer => langsamer)
{
 
  x=0;
  if(n>=16) n=0;
  analogWrite(rpin,1*(r[n]));
  analogWrite(spin,1*(s[n]));
  analogWrite(tpin,1*(t[n]));
  n=n+1;

}
  delay(1);
  x++;
}

Mit dem Programm läuft der Motor auch schon wunderbar, jedoch basiert es auf der Laufzeit eines Programmdurchlaufes, wodurch es nicht in ein vorhandenes Programm implenentiert werden kann. Daher habe ich versucht das ganze Programm mittels Interrupt neu zu schreiben, um von keinem Delay abhängig zu sein.

Dazu habe ich mir das "Timer1" Library heruntergeladen und folgendes Programm verfasst:
Code:
#include "TimerOne.h"
int ledpin=13;
int alle_x_millisekunden=100;
int x=0;
int y=0;
int rpin = 10;
int spin = 11;
int tpin = 12;
int r[16] = {64,88,109,123,128,123,109,88,64,40,19,5,0,5,19,40};
int s[16] = {119,103,81,56,32,13,2,1,9,25,47,72,96,115,126,127};
int t[16] = {9,1,2,13,32,56,81,103,119,127,126,115,96,72,47,25};
int periode=5;

void setup()   {
               pinMode(rpin, OUTPUT);
               pinMode(spin, OUTPUT);
               pinMode(tpin, OUTPUT);
               Timer1.initialize(alle_x_millisekunden*1000);
               Timer1.attachInterrupt(motor);
               }


void motor() {
               if(y>=periode)
               {
                  y=0;
                  if(x>=16) x=0;
                  analogWrite(rpin, r[x]);
                  analogWrite(spin, s[x]);
                  analogWrite(tpin, t[x]);
                  x++;
                 
               }
               y++;
               }

     
 
void loop()    {
                    // Später restlicher Programmcode
               }

Nur leider läuft damit der Motor nicht, sondern wird in der Ausgangspositoin festgehalten. Kann jemand den Fehler erkennen?


Gruß,
Se11001
12  Using Arduino / Motors, Mechanics, and Power / Synchronus Motor via PWM and Interrupt on: November 12, 2012, 08:36:03 pm
Hello!

I am currently trying to operate a 3~ 24V Synchronus motor via PWM. For that, I have a print with 3 half - bridges with the IR2104 controller on it, what works very well with the motor if you send a 3 phase 0-5V PWM.

To test the motor, I've written the following program:
Code:
int n = 0;
int x = 0;
int r[16] = {64,88,109,123,128,123,109,88,64,40,19,5,0,5,19,40};  
int s[16] = {119,103,81,56,32,13,2,1,9,25,47,72,96,115,126,127};
int t[16] = {9,1,2,13,32,56,81,103,119,127,126,115,96,72,47,25};    //These 3 arrays contain the previously calculated 3~ PWM, from 0 to 128.
int rpin = 10;
int spin = 11;
int tpin = 12;


void setup() {
  pinMode(rpin, OUTPUT);
  pinMode(spin, OUTPUT);
  pinMode(tpin, OUTPUT);
}

void loop() {  
if(x>=25)       //Changing that variable makes the frequency (and motor rpm) go up or down.
{
 
  x=0;
  if(n>=16) n=0;
  analogWrite(rpin,r[n]);
  analogWrite(spin,s[n]);
  analogWrite(tpin,t[n]);
  n=n+1;

}
  delay(1);
  x++;
}

In principle that works well, but because that program works with delay I can't combine it with other programs. So I wanted to write a program which uses a timer interrupt, so I downloaded the library "Timer1" and wrote a new one:

Code:
#include "TimerOne.h"
int ledpin=13;
int alle_x_millisekunden=100;
int x=0;
int y=0;
int rpin = 10;
int spin = 11;
int tpin = 12;
int r[16] = {64,88,109,123,128,123,109,88,64,40,19,5,0,5,19,40};
int s[16] = {119,103,81,56,32,13,2,1,9,25,47,72,96,115,126,127};
int t[16] = {9,1,2,13,32,56,81,103,119,127,126,115,96,72,47,25};
int periode=5;

void setup()   {
               pinMode(rpin, OUTPUT);
               pinMode(spin, OUTPUT);
               pinMode(tpin, OUTPUT);
               Timer1.initialize(alle_x_millisekunden*1000);
               Timer1.attachInterrupt(motor);
               }


void motor() {
               if(y>=periode)
               {
                  y=0;
                  if(x>=16) x=0;
                  analogWrite(rpin, r[x]);
                  analogWrite(spin, s[x]);
                  analogWrite(tpin, t[x]);
                  x++;
                
               }
               y++;
               }

    
 
void loop()    {
                    // Main program
               }

Unfortunately, it dosen't work that way and the motor is frozen in one position. However, if I set one output pin to 13 and wath the LED, it looks like a sinus :?

Can anyone help me?
(Please excuse my not so good English)


Greets,
Se11001
Pages: [1]