PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Board und Software verbinden (r232)



Thomas Glas
18.04.2011, 15:53
Hallo Community , nachdem ich nun das eine oder andere Problem gelöst bekommen habe und auch den Verdacht hege das anscheinend alles so funktioniert wie ich es mir vorstelle möchte ich nun das meine Software den Inhalt meiner ausgelesenen Daten an den Atmega sendet.

Mein System:
Visual Studio 2008 // Anfängerkenntnisse
Bascom // Anfängerkenntnisse
Atmega16 @ 16Mhz
Avrisp Mk2
max232


Ich habe nun soviel gesucht im Netz zu serial r232 register etc. aber ganz ehrlich gesagt verstanden habe ich es nicht! Irgendwie setzten alle Seiten ein Grundwissen in C#/c++ vorraus. Und genau hier bin ich nun und weiss nimmer weiter.


Ich habe einen Flugsimulator aus dem Shared Memory des Flugsimulators lese ich nun gewisse Daten aus. z.B.Lichter,Flaps,... und auch als Beispiel ob das Fahrwerk ein oder ausgefahren ist.

Beispiel:
Ist das Fahrwerk eingefahren ist der Wert = 0
Ist das Fahrwerk eingefahren ist der Wert = 1

Ausschnitt von c#


if ((data.lightBits3 & 0x10000) != 0)
{
txtNoseGear.Text = "1";
}
else
{
txtNoseGear.Text = "0";
}


if ((data.lightBits3 & 0x20000) != 0)
{
txtLeftGear.Text = "1";
}
else
{
txtLeftGear.Text = "0";
}


if ((data.lightBits3 & 0x40000) != 0)
{
txtRightGear.Text = "1";
}
else
{
txtRightGear.Text = "0";
}


if ((data.lightBits & 0x8000) != 0)
{
txtRefuelRDY.Text = "ON";
}
else
{
txtRefuelRDY.Text = "OFF";
}


if (data != null)//make sure we got something
{
//assign shared memory values to our text boxes so we can see
//what's in there!
txtFTIT.Text = data.ftit.ToString();
txtNozzle.Text = data.nozzlePos.ToString();
txtOil.Text = data.oilPressure.ToString();
txtRPM.Text = data.rpm.ToString();
//txtNoseGear.Text = data.gearPos.ToString();
//txtRefuelRDY.Text = data.lightBits.ToString()
}
else
{
txtFTIT.Text = "UNAVAILABLE";
txtNozzle.Text = "UNAVAILABLE";
txtOil.Text = "UNAVAILABLE";
txtRPM.Text = "UNAVAILABLE";
txtNoseGear.Text = "UNAVAILABLE";
txtRefuelRDY.Text = "UNAVAILABLE";
}


Wie man nun sehen kann habe ich viele Ausgaben.
NoseGear = 1 oder 0
LeftGear = 1 oder 0
RightGear = 1 oder 0
RefuelRDY = 1 oder 0
FTIT = Variaber Werte // Analoginstrument Info
Nozzle = Variaber Werte // Analoginstrument Info
Oil = Variaber Werte // Analoginstrument Info
RPM = Variaber Werte // Analoginstrument Info


Diese Werte möchte ich nun gern an meinen Atmega senden und z.B wenn das Gear ausgefahren ist das eine LED angeht und genau da weiss ich nichtmal einen Ansatz wie ich das machen soll. An dieser Stelle bin ich einfach überfordert.


Die Komunikation zwischen Mega und PC steht eine Verbindung mit Hterm ist möglich es kann zwischen den Geräten komuniziert werden. Ergo fehlt es mir in meiner Software eigentlich nur an einer Serialinplementierung und das zusammenfassen meiner Daten.

Auch hier weiss ich nicht wie sich das gestalten soll wenn ich mal fertig bin möchte ich alle meine aus Flugsimulator ausgelesenen Daten (bis zu 200 Datensätze) im 100ms Takt an den Mega senden und dieser soll das dann verarbeiten und meine Leds z.B. ein oder auschalten. Muss das alles als ein paket an den Mega gesendet werden oder alles in Einzelschritten hintereinander,... eigentlich habe ich tausende Fragen aber das würde den Rahmen sicherlich hier sprengen. Wie würdet Ihr das machen?



Ich wäre sehr über Hilfe dankbar.

Edit: Da es hier sicherlich keine Musterlösung geben wird denke ich darüber nach, ob mir jemand meine Software um diese Serialgeschichte programmiern könnte (Mir ist bewusst das es nicht umsonst ist). Allerdings in diesem Bereich weiss ich nicht, was das kostet und ob sich jemand überhaupt dafür findet. :/ am Ende muss auch ich das ja ein Bischen verstehen was passiert damit ich an meinem Projekt weiterarbeiten kann.

Richard
18.04.2011, 18:52
Bascom // Anfängerkenntnisse


Warum benutzt Du dann Bascom nicht? Dort sind etliche Beispiele für RS232 mit Einzeldaten oder auch Blockweise Verarbeitung. Achtung bei Input wird auf ein CR gewartet also Messwert CR übertragen sonst wartet das Programm unendlich! Ansonsten muss man halt einige Bascom Beispiele durcharbeiten bis dessen Wirkung geläufig ist. Bei den Mengen die Du verarbeiten willst, solltest Du Dir ganz besonders RS 232 mit IRQ anschauen und auch die Abarbeitung von Werten welche sich nicht geändert haben sofort verwerfen. b.z.w. erst überhaupt nicht zum µC senden. Dazu solltest Du Dir ein Protokoll ausdenken, Start Zeichen, Anzahl der zu sendenden Nutzdaten, Nutzdaten, CRC Checksumme Stopp Zeichen. Die Reihenfolge der Nutzdaten muss immer gleich sein, damit die immer an gleicher Stelle abgelegt werden.

Gruß Richard

sternst
18.04.2011, 19:05
Ich bin verblüfft.
Ich habe null Erfahrung mit C#, aber wenn ich "c# serial" bei Google eingebe, bekomme ich haufenweise extrem viel versprechende Links. Mit ausführlichen Erklärungen und Beispiel-Codes und allem Drum und Dran. Deine C#-Kenntnisse reichen also nicht aus, um mit all dem irgendetwas anzufangen, aber du hast trotzdem das hier hin bekommen:

Ich habe einen Flugsimulator aus dem Shared Memory des Flugsimulators lese ich nun gewisse Daten aus. z.B.Lichter,Flaps,...
...
Ausschnitt von c#Also wer das kann, sollte doch mit so was Simplen, wie dem hier

using System.IO.Ports;

private static void SendSampleData() {
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Hello World");
port.Close();
}keine Probleme haben, oder?

Thomas Glas
18.04.2011, 19:06
Ich kann in Bascom nen Taster oder ne Led schalten Standart Tutorials halt.
Die Fähigkeit einen Chip anzusteuern traue ich mir nicht zu.
Alles andere überschreitet meine Fähigkeit ,... so möchte ich es ausdrücken.

Ich habe mir das schon gedacht @ IRQ und Register ... das wird dann noch komplexer :(
Dazu kommt das mein Englisch zu schlecht ist *grusel* ergo bleiben mir nur deutsche Tutorials oder Hilfe von aussen.
Ansonsten muss ich mein Vorhaben einstampfen was ich sehr schade fände.


Gruß Thomas

Thomas Glas
18.04.2011, 19:15
Ich bin verblüfft.
Ich habe null Erfahrung mit C#, aber wenn ich "c# serial" bei Google eingebe, bekomme ich haufenweise extrem viel versprechende Links. Mit ausführlichen Erklärungen und Beispiel-Codes und allem Drum und Dran. Deine C#-Kenntnisse reichen also nicht aus, um mit all dem irgendetwas anzufangen, aber du hast trotzdem das hier hin bekommen:
Also wer das kann, sollte doch mit so was Simplen, wie dem hier

using System.IO.Ports;

private static void SendSampleData() {
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Hello World");
port.Close();
}keine Probleme haben, oder?



Ja das habe ich auch schon durch :) kenne ich alles schon aber das ist nen Example welches schick und simple aussieht aber ich weiss immernoch nicht wie die

A einbinden soll und
B muss statt Hello World ja auch mein Datensatz da rein
c sollte mein Datensatz ja eine art Struktur aufweisen um in Bascom das alles wieder auseinander ziehen zu können

und das was ich geschafft habe ist nichts anderes als stundenlanges probieren und snippets kopieren und einbinden.
Wenn ich das in Stunden zusammenfassen sollte ca 100 Stunden ,... mit dem Serial hänge ich mindesten genauso lang daran Google behaupte ich habe ich komplett durch *grins*.

Ich bräuchte ne art Beispiel wie ich das einbinden soll und wie die Daten versendet werden dann würde ich auch verstehen was passiert.
Für den einen oder anderen von euch ist das sicher total einfach für mich ist das ne ganz schwere Sache. Muss ich gestehen. Ausserdem haben damals für meinen Flugsimulator die Leute schonmal etwas Programmiert und den Code frei zugänglich gemacht.
Am Ende ist es so das keiner mehr sich dafür interessiert "ich schon!"

Hier aus der Datei nun ein Auszug es war ein simples Example und ich habe es dann erweitert es ist nicht von mir!!!



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;



namespace SharedMemExample
{
public partial class frmMain : Form
{
/// <summary>
/// Shared instance of a Falcon shared memory reader
/// </summary>
private F4SharedMem.Reader _reader;

/// <summary>
/// Flag to indicate whether the polling loop should keep polling
/// </summary>
private bool _keepPolling = false;

public frmMain()
{
InitializeComponent();
}

private void frmMain_Load(object sender, EventArgs e)
{
//set the Falcon data format here
F4SharedMem.FalconDataFormats sharedMemFormat = F4SharedMem.FalconDataFormats.OpenFalcon;

//now create a new instance of the F4 Shared Memory reader, using this data format
_reader = new F4SharedMem.Reader(sharedMemFormat);
}

private void cmdStart_Click(object sender, EventArgs e)
{
cmdStop.Enabled = true;
cmdStart.Enabled = false;

_keepPolling = true; //set the flag that allows the polling loop to keep running

//wait for Falcon to be running or for the user to click the Stop button
while (!_reader.IsFalconRunning && _keepPolling)
{
Application.DoEvents(); //stay responsive to Windows events
}

//loop while Falcon is running and the keepPolling flag is set
while (_reader.IsFalconRunning && _keepPolling)
{
//read all variables from Falcon's shared memory
F4SharedMem.FlightData data = _reader.GetCurrentData();



if ((data.lightBits3 & 0x10000) != 0)
{
txtNoseGear.Text = "1";
} else {
txtNoseGear.Text = "0";
}

if ((data.lightBits3 & 0x20000) != 0)
{
txtLeftGear.Text = "1";
}
else
{
txtLeftGear.Text = "0";
}

if ((data.lightBits3 & 0x40000) != 0)
{
txtRightGear.Text = "1";
}
else
{
txtRightGear.Text = "0";
}



if ((data.lightBits & 0x8000) != 0)
{
txtRefuelRDY.Text = "1";
}
else
{
txtRefuelRDY.Text = "0";
}


if (data != null)//make sure we got something
{
//assign shared memory values to our text boxes so we can see
//what's in there!
txtFTIT.Text = data.ftit.ToString();
txtNozzle.Text = data.nozzlePos.ToString();
txtOil.Text = data.oilPressure.ToString();
txtRPM.Text = data.rpm.ToString();
//txtNoseGear.Text = data.gearPos.ToString();
//txtRefuelRDY.Text = data.lightBits.ToString();




}
else
{
txtFTIT.Text = "UNAVAILABLE";
txtNozzle.Text = "UNAVAILABLE";
txtOil.Text = "UNAVAILABLE";
txtRPM.Text = "UNAVAILABLE";
txtNoseGear.Text = "UNAVAILABLE";
txtRefuelRDY.Text = "UNAVAILABLE";
}
Application.DoEvents(); //stay responsive to Windows events
}
}


private void txtTest_TextChanged(object sender, EventArgs e)
{

}

private void Brows_Click(object sender, EventArgs e)
{

}

private void lblLeftGear_Click(object sender, EventArgs e)
{

}

private void Analog_Click(object sender, EventArgs e)
{

}

private void cmdStop_Click(object sender, EventArgs e)
{

}

}
}



Diesen Code habe ich schon versucht aber mein Resultat war nichts :) obwohl er selbsterklärend ist. Zu C# ich bin seit einer Woche dran und meine Zeit ist wirklich begrenzt da icheinen Sohn habe und meine Frau mich langsam erschlägt wegen dieser Sache ;) Einer der Gründe warum ich das auch bezahlen würde wenn mir jemand die Anbindung realisiert.
Gruß Thomas

shedepe
18.04.2011, 19:31
Du wirst dir also eine Art Protokoll für die Datenübertragung überlegen müssen z.B.
Startbedingung - ID des Befehls - Daten - Endbedingung

in C# kannst du das ganze dann in etwa so machen:


SerialPort port = new SerialPort(...);
port.Open();
byte[] DatenZumSenden new byte[Gewünschte Größe];
DatenZumSenden[0] = Startbedingung;
DatenZumSenden[1] = BefehlsID;
DatenZumSenden[2] = Daten;
DatenZumSenden[3] = Endbedingung;
port.Write(DatenZumSenden, 0, DatenZumSenden.Length);

und in Bascom musst du das halt dann entsprechend zerlegen

Richard
18.04.2011, 22:47
Also ich kann auch kein Englisch trotzdem bin ich erfolgreich Elektroniker geworden. Die nötigen Fachbegriffe habe ich halt auswendig gelernt und aussprechen kann ich nach über 30 Berufsjahren immer noch keinen. Alles was ich vom µC's weiß habe ich mir in ? 10.000 oder mehr Stunden durch lesen und ausprobieren selber bei gebracht hauptsächlich Assembler recht wenige Befehle die man lernen muss, und Basic in verschiedenen Dialekten. Mit Cxxx stehe ich immer noch auf Kriegsfuss, die sytax ist einfach nichts für mich, b.z.w. für deutsche Tastatur Belegungen. :-(

Das größte Problem bei Hochsprachen ist das mangelnde Verständnis was der Compiler aus den Befehlen letztendlich generiert. :-( Das lernt man NUR durch Assembler als Grundlage. Da muss man halt jede Speicherstelle und jedes Register selber setzen, auf den Stack aufpassen und Speicher Überläufe vermeiden....

Mitten drin quer Einsteigen ist immer sehr sehr schwer wenn die Grundlagen fehlen. Ist wie beim Tapezieren, fehlt die Grundlage fällt die Tapete von der Wand. :-(

Trotzdem viel Glück und eine menge Hartnäckigkeit, dann wird das schon! :-) Wenn der Simulator eh überwiegend 0 oder 1 liefert, Beschäftigen Dich auch mit Bit Operationen, dann kannst Du mit einem Word, Doppel Word oder Long einen Haufen Infos übertragen.

Gruß Richard

Thomas Glas
19.04.2011, 13:40
So habe nun gestern Abend noch etwas versucht.
Einschalten der Led von der Software aus via Buttons.

Nun ist der erste Schritt getan ich muss nun noch herrausfinden wie ich
nun meine Daten bündele und in einen Satz an meinen Mega sende.

Aktuell öffne und schliesse ich ja per Klick auf den Button den Port ständig.
Bei 50 Abfragen ,... muss es anders laufen es muss ein Paket versendet werden was alles beinhaltet.
*Kopfkratz*

Also mein nächster Test wird sein "1 Button(openPort)" & "1 Button(closePort)" den Port zu öffnen & zu schliessen und 2 weitere Buttons um Led an oder auszuschalten.
Die Buttons zum ein und ausschalten der LEDs würde ich mit einer IF Abfrage gestalten somit würde das ständige open&close des Ports entfallen.
Ausserdem würde es Sinn machen alle relevanten Daten am Anfang des Script zu defenieren so das später an besagten Stellen so wenig Code wie nötig zum versenden der Daten entsteht.

Melde mich wenn ich weiter bin :)

Richard
19.04.2011, 19:05
Lege doch einfach eine Liste mit den Daten an.......
1.Kappen
2 Ruder
3.
4.
5.
u.s.w. das in einer Data Anweisung 1,2,3,4,5..........X
Dann Print#1, Data,1...x

Beim Empfänger dann den umgekehrtten Weg und erst nach der Übertragung aller Daten diese in der Hauptschleife einzelnd auswerten. Die Daten Übertragung selber zyklisch über IRQ alle xyz ms. Du weist ja an welcher Stelle, Data 1 Klappe, Data 2 Ruder.....was zu finden ist. :-) Open/Close dann am Beginn/Ende des IRQ.

Sollte vom Schema her zu machen sein.

Gruß Richard

Thomas Glas
19.04.2011, 19:21
Habe es nun so geschrieben mit Port-Open/Close das die Anweisung vorher prüft ob der Port open ist wenn nicht wird er geöffnet unabhängig davon wird durch starten meiner Abfrage auch der Port geöffnet. Falls aus irgendeinem Grund der Port gecloset wird ... öffnet er sich wieder automatisch. Eigentlich ne simple IF Else Abfrage.

Ich weiss nicht was eine Dataanweisung ist.
Verstanden habe ich deinen Vorschlag nur umsetzen ist etwas anderes.

Ich versuche es mal wenn jemand Tipps Tricks oder kniffe hat oder gar snippet oder Hilfe Tutorials immer her damit.


Gruß Tom

Richard
19.04.2011, 20:12
Bascom Hilfe nach DATA suchen....Gibt es in c sicher auch! Mit Data wird ein Ram Bereich ab Adresse x bis Adresse y mit Daten gefüllt. Auf diese Daten kann man mit Data x x+1, x+2, x+y wieder zugreifen. wenn Du also eine Tabelle mit allen zu übertragenden Parametern als Data 1 bis Data (Ende der Tabelle) anlegst und die dann in einem Rutsch überträgst und damit beim Empfänger eine gleiche Tabelle anlegst, kannst Du z.B. Mittels Data 15 auf die 15. Stelle (Speicherplatz) zugreifen.

Die genaue Syntax habe ich nicht im Kopf, in C sowieso nicht. :-( Natürlich kann man ähnliches auch mit einem Arry machen.


Tabellen und Data http://www.rn-wissen.de/index.php/Bascom_Tabellen

Gruß Richard

Thomas Glas
19.04.2011, 22:19
Also ich habe mich ganz flüchtig in das Thema Array eingelesen und wenn ich das richtig verstanden habe mache ich nun eine Kette

array(1,3,4,5,6,5,4,33,221,11,22,88,);

so speicher ich das ab und dann

gehe ich in Bascom raus und spreche die einzlnen Stellen an?

Es schaut einfach aus aber ist sicherlich so nicht funktionell?!
Auf diese Weise haut er immer alles raus da aber nicht ständig sich alles verändert...

So müssten nur die Daten übertragen werden die auch aktualisiert werden das würde
enormen Speed sicherlich ausmachen?

Oder ist das mit einem Array möglich durch auslassen eines Wertes in dem Array ergo

Array(1,"",4,5,"","",4,33,"",11,22,88,);

Gott ist das wieder kompliziert *grins*

Thomas Glas
21.04.2011, 07:02
Ok ich benötige bitte Hilfe ich möchte zum testen erstmal 3 zustände realisieren wobei es schon beim ersten Zustand zu Problemen kommt. Mit folgendem Code funktioniert es das eine Led an oder aus geht das allerdings äusserst selten. Ich glaube das sich da bei der Übertragung überschlägt. Die Leitung habe ich geprüft es kommen keine fehlerhaften Zeichen an ,... ich denke es liegt an einem ordentlichen Timing?

Warum wird trotz das ich eine eins oder zwei sende das bei der Led so nicht geschaltet?


Gruß Thomas

C# code


if ((data.lightBits3 & 0x10000) != 0)
{
txtNoseGear.Text = "1"; // ausgefahren
serialPort1.Write("2"); // sende eine 2 an den Chip
} else {
txtNoseGear.Text = "0"; // eingefahren
serialPort1.Write("1"); // sende eine 1 an den Chip

}
Thread.Sleep(1);



Bascom code


'LED1 an PB0
Led1 Alias Portb.0
Config Led1 = Output


Dim A As Byte


Do

A = Inkey()



If A = 1 Then
Led1 = 0 //Rad eingefahren LED ausschalten
End If

If A = 2 Then
Led1 = 1 //Rad ausgefahren LED ausschalten
End If


'If A > 0 Then 'we got something
' Print "ASCII code " ; A ; " from serial"
'End If

Loop


A = Waitkey() 'wait for a key

'Print Chr(a)

Do

Loop Until Inkey() = 27

End



Gegentest mit Putty // Werte in Bascom als ASCII ersetzt
Nun kann ich per Tastatur und den Tasten 1 & 2 die Led ein oder ausschalten.
Bei dieser Variante viel mir auch auf das wenn die Led eigentlich angehen sollte sie ausgeht und umgekehrt.
Tastatur 1 = Led geht an / Tastatur 2 = Led geht aus
Irgendwie ist doch hier der Wurm drin?



'LED1 an PB0
Led1 Alias Portb.0
Config Led1 = Output


Dim A As Byte


Do

A = Inkey()



If A = 49 Then
Led1 = 0 //Rad eingefahren LED ausschalten
End If

If A = 50 Then
Led1 = 1 //Rad ausgefahren LED ausschalten
End If


'If A > 0 Then 'we got something
' Print "ASCII code " ; A ; " from serial"
'End If

Loop


A = Waitkey() 'wait for a key

'Print Chr(a)

Do

Loop Until Inkey() = 27

Richard
21.04.2011, 07:41
Bei dieser Variante viel mir auch auf das wenn die Led eigentlich angehen sollte sie ausgeht und umgekehrt.
Tastatur 1 = Led geht an / Tastatur 2 = Led geht aus
Irgendwie ist doch hier der Wurm drin?




Das kann an der Verdrahtung liegen, wenn die LED's an Vcc Liegen werden die mit GND Ausgang = 0 An geschaltet.


Gruß Richard