Hallo zusammen, ich würde gerne einen Datenaustausch zwischen einem PIC18F2550 und LabView realisieren. Der PIC sitzt auf einem Starter Board mit integrierter USB Schnittstelle und vorinstalliertem Bootloader. Könnt ihr mir vielleicht eine Vorgehensweise ans Herz legen? Gibt es dafür Bibliotheken von Microchip? Finde leider nicht allzu viel Stuff dazu im Netz. Bin um jeden Tipp dankbar. Gruß Simon
Gurgle mal. Firmata für die CPU (picduino/ubw) Firmata DLL für labview/visa
Gibt es eine Art Treiber für PIC Mikrocontroller bzw fertige Bibliotheken vin Microchip für sowas ??
Ein 2550 ist nur ein leerer Microcontroller. Was für eine Art von USB-Geraet er darstellt und ob, bzw welche Treiber benötigt werden, entscheidet alleine das Programm, das darauf läuft. Darüber wissen wir bis jetzt aber noch gar nichts...
Der Mikrocontroller sitzt auf einem Board mit USB Schnittstelle und vorinstalliertem Bootloader: https://shop.mikroe.com/development-boards/starter/startusb/pic
Ok, das ist also erst Mal gar kein USB Device. Vom Bootloader abgesehen, aber mit dem willst du ja später nicht mit LabVIEW kommunizieren. Der ist dafür da, das Programm mit dem später LabView kommuniziert auf den PIC zu bringen. Das musst du natürlich erst Mal erstellen. Welche USB Geräteklasse schwebt dir denn so vor? (Falls dir das schon was sagt) Es gibt einige Beispiele in den Microchip Libraries for Applications. Die einfachsten sind wohl CDC und HID. Siehe auch: http://www.hs-ulm.de/nocache/wir/Personal/PersonalSaSchr/vschilli/Mikrocontroller/USB-Projekte/ (Mit LabView kann ich allerdings nicht dienen)
Volker S. schrieb: > Ok, das ist also erst Mal gar kein USB Device. Vom Bootloader > abgesehen, > aber mit dem willst du ja später nicht mit LabVIEW kommunizieren. Der > ist dafür da, das Programm mit dem später LabView kommuniziert auf den > PIC zu bringen. > Das musst du natürlich erst Mal erstellen. Welche USB Geräteklasse > schwebt dir denn so vor? (Falls dir das schon was sagt) > Es gibt einige Beispiele in den Microchip Libraries for Applications. > Die einfachsten sind wohl CDC und HID. Siehe auch: > http://www.hs-ulm.de/nocache/wir/Personal/Personal... > (Mit LabView kann ich allerdings nicht dienen) Hi Volker, ich würde gerne die CDC Klasse nutzen. Habe mir dazu die aktuelle Version der MLA gerunter geladen. Wie gehe ich nun weiter vor?
Wenn du noch nie mit Microcontrollern gearbeitet hast und auch sonst mit Programmieren noch nicht viel am Hut hattest, dann liegt vermutlich eine harte Zeit vor dir und du solltest zuerst ein paar blinkende LED Beispiele durcharbeiten um den MC und die Arbeitsumgebung kennen zu lernen bis du dich an das USB Projekt wagst ;-) http://microchipdeveloper.com/mplabx:start Bevor wir zu der MLA Geschichte gehen, noch eine Frage. Bietet MicroElectronika nur diese nackte Board mit dem Bootloader an? Keine Beispiele, nichts? https://libstock.mikroe.com/projects/view/481/startusb-for-pic-usb-hid-controlado-pelo-labview-startusb-for-pic-usb-hid-with-labview Die wären dann ja schon genau darauf abgestimmt und müssten nicht erst angepasst werden, wie die Beispiele der MLA. Zum Bearbeiten der MLA Beispiele brauchst du zunächst noch passende IDE und Compiler. Das wären MPLABX und XC8. Beide von der MCHP Seite runterladen und installieren, falls das noch nicht geschehen ist. Das Datasheet des 18F2550 brauchst du natürlich auch noch!!! Mit der MPLABX IDE üffnest du dann das am besten passende Beispiel in den MLA. Das ist in deinem Fall ...microchip/mla/v2016_11_07/apps/usb/device/cdc_basic/firmware/picdem_f s_usb.x Das versuchst du dann zu kompilieren bevor du irgendwas daran änderst! Am Ende des Kompilierens sollte da BUILD SUCCESSFUL stehen, ansonsten hast du das erste Problem. Sollte alles passen (wovon auszugehen ist) dann kannst du jetzt in den Projekt Properties den PIC vom 18F4550 auf den 18F2550 umstellen und erneut versuchen zu kompoilieren. Solltest du noch nicht wissen (oder es selber rausfinden können), wie man den gewünschten Controller auswählt, dann gehe zurück auf Los und mach noch ein paar blinkende LED Beispiele. Sollte es dir gelingen das Projekt auf den 2550 zu ändern, dann kommen beim kompilieren jetzt einige Fehlermeldungen, die du beheben musst. Mit Hilfe von PIC18Fxx50 DataSheet und den 2 Schaltplänen der beiden Boards (deinem und dem FSUSB von MCHP) müsste dir das gelingen. Dabei bekommst du dann den ersten Einblick in die Projektstruktur. Hast du die Fehler behoben, kannst du versuchen das Demo Projekt mit Hilfe des MicroE Bootloaders auf deine Hardware zu spielen. Das benötigte Hex-File musst du mit Export Hex im Projekt Menü erzeugen!!! Wenn du der mḾeinung bist, das Demo Programm läuft jetzt auf deinem Board, solltest du mit einem einfachen Terminal Programm wie HTerm, TeraTerm, Br@y Terminal, cuteCom ... mit dem Board zu kommunizieren. Wenn das alles geklappt hat, kannst du anfangen deine eigentliche Apllikation zu entwickeln ;-) <edit> Alternativ kannst du auch versuchen das Projekt hier http://www.hs-ulm.de/nocache/wir/Personal/PersonalSaSchr/vschilli/Mikrocontroller/USBProjekte/USBCDC/ anzupassen. Da wählst du am besten die Configuration PDFSUSB_4550_XC8
:
Bearbeitet durch User
Bist du zufällig dieser Simon? Beitrag "PIC 18F2550 I²C Kommunikation XC8 Compiler"
:
Bearbeitet durch User
Volker S. schrieb: > Bist du zufällig dieser Simon? > Beitrag "PIC 18F2550 I²C Kommunikation XC8 Compiler" Ja genau, hast du richtig erkannt :-) Habe versucht das von dir vorgeschlagene Beispiel aus der MLA (microchip/mla/v2016_11_07/apps/usb/device/cdc_basic/firmware/picdem_f s_usb.x) zu testen. MPLAB, XC8 und 2550 Datasheet ist alles vorhanden. Habe nach erfolgreichem kompilieren des Beispielprojektes, auf meinen PIC18F2550 in den Projekteigenschaften umgestellt. Nun kommen wie du erwähntest einige Fehlermeldungen, da das Projekt auf meinen PIC angepasst werden muss. Und genau da ist das Problem, ich glaube dazu fehlt mir einfach noch zu viel Background. Ich weiß die Fehlermeldungen die auftreten nicht wirklich zu deuten.
simon schrieb: > Und genau da ist das Problem, ich glaube dazu fehlt mir einfach noch zu > viel Background. Ich weiß die Fehlermeldungen die auftreten nicht > wirklich zu deuten. Na dann poste doch einfach die erste der Fehlermeldungen, welche du nicht auflösen kannst und schreibe was dir dazu einfällt, bzw. warum dir dazu nichts einfällt ;-) <edit> Vergiss den Bootloader Quatsch, falls du ein PICkit oder so was hast...
:
Bearbeitet durch User
> Na dann poste doch einfach die erste der Fehlermeldungen, welche du > nicht auflösen kannst und schreibe was dir dazu einfällt, bzw. warum dir > dazu nichts einfällt ;-) > > <edit> Vergiss den Bootloader Quatsch, falls du ein PICkit oder so was > hast... Hallo Volker, im Anhang habe ich dir mal einen Screenshot meiner Bearbeitung und der Fehler die auftreten, angehangen. Anscheinend hat das Programm ein Problem mit der Klasse "leds.c". Außerdem meckert er: undefined identifier "LATDbits" Er kann wohl die Ausgangs Register nicht lesen, oder? Mal ganz allgemein die Frage: Warum gibt es in dem Projekt überhaupt so viele Klassen (leds etc)? Eigentlich geht es doch "NUR" um die Initialisierung der USB Schnittstelle, oder ? Gruß Simon
simon schrieb: > Eigentlich geht es doch "NUR" um die Initialisierung der USB > Schnittstelle, oder ? Nein, da kann man noch einen Taster abfragen und LEDs ansteuern. simon schrieb: > Anscheinend hat das Programm ein Problem mit der Klasse "leds.c". C kennt sowas wie Klassen gar nicht. simon schrieb: > Außerdem meckert er: undefined identifier "LATDbits" Er kann wohl die > Ausgangs Register nicht lesen, oder? Ein pic18f2550 hat keinen PortD! Wenn kein PortD da ist, musst du überlegen, ob du das was da gemacht werden soll an einem anderen Port machst, oder ob du einfach darauf verzichten kannst...
Hi Volker, danke das du so ausführlich hilfst :-) Ich habe nun das Beispiel, für das er den Port D braucht einfach gelöscht. Und siehe da, es gibt nur noch eine Fehlermeldung (s. Anhang). undefinied Symbol "_APP_LEDUpdateUSBStatus" Leider finde ich das in keiner der übrig geblieben Klassen :( Gibt es eine Möglichkeit die Kommunikation zu testen? Sprich z.B. ein Byte schreiben, und mit HTerm gucken ob was ankommt?
simon schrieb: > Ich habe nun das Beispiel, für das er den Port D braucht einfach > gelöscht. Und siehe da, es gibt nur noch eine Fehlermeldung (s. Anhang). > > undefinied Symbol "_APP_LEDUpdateUSBStatus" > > Leider finde ich das in keiner der übrig geblieben Klassen :( Klar, das hast du doch gelöscht ;-) Jetzt müssen natürlich auch die Aufrufe gelöscht werden! (Du musst danach suchen, ohne den Unterstrich am Anfang. Den hat der Compiler dazu gemacht...) simon schrieb: > Gibt es eine Möglichkeit die Kommunikation zu testen? Sprich z.B. ein > Byte schreiben, und mit HTerm gucken ob was ankommt? Natürlich ;-) Anscheinend wurde das Projekt etwas abgeändert. Wenn ich mich richtig erinnere, dann konnte man früher LEDs ansteuern. Jetzt schickt es wohl einfach das was empfangen wurde leicht modifiziert zurück.
1 | switch(readBuffer[i]) |
2 | {
|
3 | /* If we receive new line or line feed commands, just echo
|
4 | * them direct.
|
5 | */
|
6 | case 0x0A: |
7 | case 0x0D: |
8 | writeBuffer[i] = readBuffer[i]; |
9 | break; |
10 | |
11 | /* If we receive something else, then echo it plus one
|
12 | * so that if we receive 'a', we echo 'b' so that the
|
13 | * user knows that it isn't the echo enabled on their
|
14 | * terminal program.
|
15 | */
|
16 | default:
|
17 | writeBuffer[i] = readBuffer[i] + 1; |
18 | break; |
19 | }
|
Leider finde ich in keiner der Klassen einen Aufruf zu: "_APP_LEDUpdateUSBStatus". Auch ohne den Unterstrich finde ich nirgends etwas. Wenn ich auf den Fehler draufklicke, springt er auch nicht an eine bestimmte Stelle im Quelltext :-(
Wie suchst du denn? <edit>Sorry, ignoriere bitte die Treffer in meiner main_cdc.c. Die sind aus einem anderen Projekt und entsprechen denen in usb_events.dc
:
Bearbeitet durch User
Volker S. schrieb: > Wie suchst du denn? > > <edit>Sorry, ignoriere bitte die Treffer in meiner main_cdc.c. > Die sind aus einem anderen Projekt und entsprechen denen in > usb_events.dc Hi Volker, ich habe die letzte C Datei "usb_events.c" nicht durchsucht bzw vergessen! Nun klappt es und es kommt kein Fehler mehr :-) Nur das mit dem Schreiben funktioniert nocht nicht. Ich habe mir gedacht ich versuche einfach mal folgendes Beispiel: putUSBUSART(writeBuffer,numBytesRead); Dieser Funktion habe ich (s. Screenshot) einfach zwei Integer Werte übergeben un HOFFTE, etwas über HTerm sehen zu können. Tut sich jedoch leider nichts...
simon schrieb: > ich habe die letzte C Datei "usb_events.c" nicht durchsucht bzw > vergessen! Beim nächsten mal einfach [Strg]+[Umschalt]+f simon schrieb: > Ich habe mir gedacht ich versuche einfach mal folgendes Beispiel: > > putUSBUSART(writeBuffer,numBytesRead); Das geht so nicht. Diese Funktion füllt nur den Sendepuffer. Weggeschickt wird der dann mit CDCTxService(); Schreib das jetzt bitte blos nicht einfach da hinten dran sondern lösch den Unsinn wieder ;-) ALLES passiert in APP_DeviceCDCBasicDemoTasks() die von main aufgerufen wird! Versuch doch zuerst zu verstehen was passiert, wenn du vom Terminal aus was zum Device schickst... Und keine while(1) Schleifen einbauen. Nirgendwo!!!
So ich bekomme etwas in HTerm angezeigt :-) Wenn ich z.B. schreibe:
1 | char data =7; |
2 | unsigned char length[7]; |
3 | |
4 | for (int test=0; test<50; test++) |
5 | {
|
6 | |
7 | putUSBUSART(data,length); |
8 | CDCTxService(); |
9 | |
10 | }
|
kommt was an. Allerdings kann ich meine Puffereingaben (data, length) in HTerm nicht wirklich deuten? Warum bekomme ich da so einen Kauderwelsch angezeigt (s. Screenshot) ? Ich Würde gerne für den Anfang einfach ein Byte in Form von einer Zahl senden.
simon schrieb: > Warum bekomme ich da so einen Kauderwelsch angezeigt > (s. Screenshot) ? Bei dem was du da übergibst wundert mich das nicht ;-) simon schrieb: > Ich Würde gerne für den Anfang einfach ein Byte in > Form von einer Zahl senden Syntax void putUSBUSART(uint8_t * data, uint8_t Length); -> putUSBUSART(&data,1); ? PS: Deine Schleife blockiert das Programm, vergiss das! Innerhalb von APP_DeviceCDCBasicDemoTasks() solltes du nicht mehrmals (zumindest nicht soooo oft) CDCTxService() aufrufen. Ach übrigens, falls du dich fragst wie ich das Diagramm oben erstellt habe: http://microchipdeveloper.com/mplabx:call-graph Noch was: Hast du jetzt eigentlich ausprobiert, was passiert, wenn du vom PC aus was wegschickst?
:
Bearbeitet durch User
Sooo, nun bekomme ich anständige Werte :-) Mein Code:
1 | char data =7; |
2 | unsigned char length=2; |
3 | int test=0; |
4 | |
5 | for (test=0; test<10; test++) |
6 | {
|
7 | writeBuffer[test] = data+test; |
8 | putUSBUSART(&writeBuffer[test], length); |
9 | |
10 | for (int test2=0; test2<50; test2++) |
11 | {
|
12 | __delay_ms(10); |
13 | }
|
14 | |
15 | }
|
16 | |
17 | CDCTxService(); |
Habe es nun so geändert, dass ich die Methode CDCTxService() nur noch am Ende aufrufe. >Noch was: Hast du jetzt eigentlich ausprobiert, was passiert, wenn du >vom PC aus was wegschickst? Das funktioniert leider noch nicht. Mein Code, den ich zum Senden vom PC aus nutze ist ähnlich wie der zum empfangen vom PC.
1 | char data; |
2 | unsigned char length=2; |
3 | int test=0; |
4 | |
5 | for (test=0; test<10; test++) |
6 | {
|
7 | |
8 | data=getsUSBUSART(readBuffer, 2); |
9 | |
10 | for (int test2=0; test2<50; test2++) |
11 | {
|
12 | __delay_ms(10); |
13 | }
|
14 | |
15 | }
|
16 | |
17 | CDCTxService(); |
Leider tut sich nichts, wenn ich über HTerm versuche, Bytes zu schreiben. Es wird leider nichts vom Microkontroller gelesen. Gibt es dazu vielleicht eine extra Methode wie auch zum senden (CDCTxService();) ? Rx statt Tx hab ich schon probiert ;-) Noch eine Frage nebenher: Weißt du warum ich eine Fehlermeldung erhalte, dass mein Projekt Dateien mit Fehlern enthalten würde? ("project contains files with errors", s. Screenshot") Ich weiß erlich gesagt nicht mehr, ab welchem Zeitpunkt der Fehler das erste mal da war. Fakt ist: Alle C Files lassen sich ohne Fehler kompilieren und auf den Mikrocontroller überspielen... (Vielen Dank für deine Hilfe bis hierhin :-) ) Gruß Simon (Vielen Dank schon mal für alles bis hier hin :-) )
Ignoriere das mit den Fehlern in irgendwelchen Dateien. Ich habe es auch aufgegeben, solange das Projekt sich ohne Probleme übersetzen lässt. Bei mir wird z.B auch in einem Projekt angezeigt: release_notes_mla.htm "Error parsing file" Die Delays in deinem Code solltest du tunlichst vermeiden. Das Betriebssystem deines PCs schaut praktisch immer wieder nach, ob das USB Gerät noch da ist. Reagiert es zu langsam (antwortet nicht schnell genug), dann fliegt es raus. Das macht alles das USB Framework im Hintergrund. Aber nur wenn es nicht blockiert wird. -> Vergiss Delays, sind eh Müll ;-) Das Empfangen und Verarbeiten von Daten die vom PC kommen müsste eigentlich out-of-the-box funktionieren. Die Größe der Sende- und Emfangs-buffer sollte den Endpunkten entsprechen, die in den Deskriptoren festgelegt sind (CDC_DATA_IN_EP_SIZE, CDC_DATA_OUT_EP_SIZE)
Volker S. schrieb: > Die Delays in deinem Code solltest du tunlichst vermeiden. > Das Betriebssystem deines PCs schaut praktisch immer wieder nach, ob das > USB Gerät noch da ist. Reagiert es zu langsam (antwortet nicht schnell > genug), dann fliegt es raus. Das macht alles das USB Framework im > Hintergrund. Aber nur wenn es nicht blockiert wird. -> Vergiss Delays, > sind eh Müll ;-) > > Das Empfangen und Verarbeiten von Daten die vom PC kommen müsste > eigentlich out-of-the-box funktionieren. Die Größe der Sende- und > Emfangs-buffer sollte den Endpunkten entsprechen, die in den > Deskriptoren festgelegt sind (CDC_DATA_IN_EP_SIZE, CDC_DATA_OUT_EP_SIZE) Hi Volker, sorry fürs späte Antworten, hatte gestern viel zu tun. Nun bekomme ich meine Werte schon sauber in LabView rein, ein echter Erfolg :-) 3 Fragen hab ich noch: 1. Du sagtest ja Delays wären nicht so dolle. Aber wie kann ich dann kontrolliert Daten in Zeitabständen schreiben, wenn nicht so? Sende ich Daten ohne Delay, stürzt HTerm ab, zu viele Daten auf einmal. Mit Delay funktioniert es. 2. Leider funktioniert das Senden vom PC noch nicht. Dazu habe ich den Controller wie folgt programmiert:
1 | char data2=5; |
2 | unsigned char length1=1; |
3 | int test2=0, test3; |
4 | |
5 | for (test2=0; test2<5; test2++) |
6 | {
|
7 | |
8 | writeBuffer[test2] = data2+test2; |
9 | putUSBUSART(&writeBuffer[test2], length1); |
10 | |
11 | data2=getsUSBUSART(&readBuffer[test2], 1); |
12 | |
13 | for (test3=0; test3<50; test3++) |
14 | {
|
15 | __delay_ms(10); |
16 | }
|
17 | CDCTxService(); |
18 | }
|
Mein Gedanke: -Ich Schreibe Daten in den writeBuffer -Im darauffolgenden Zyklus erhalte ich die Daten im readBuffer und speichere sie in der Variable "data2" Könntest du mir da nochmal weiterhelfen? 3. Ich habe nun 2 Projekte bei mir in MPLAB. Gibt es eine Möglichkeit, diese automatisiert zusammen zu fassen? Oder muss ich in den Project Properties gucken welche .h Files includiert sind und diese Manuell "kopieren" ? Einfach in MPLAB .c Files und .h Files verschieben klappt logischerweise nicht. Hättest du da einen Ratschlag zur Vorgehensweise? Viele Grüße, Simon Gruß Simon
simon schrieb: > 1. Du sagtest ja Delays wären nicht so dolle. Aber wie kann ich dann > kontrolliert Daten in Zeitabständen schreiben, wenn nicht so? Legst du dich Abends in's Bett und zählst bis zum Aufstehen? So kannst du dir Delays vorstellen. Die kontrollierten Zeitabstände werden (z.B) durch Timer erzeugt. Der Timer löst dann einen Interrupt aus (der Wecker klingelt) und im Interrupt wird irgendwas gemacht, ggf. das Resultat davon irgendwo gespeichert und ein Merker (Flag) gesetzt, dass es was zu tun (was zum wegschicken) gibt. Wenn das Programm das nächste mal die Funktion APP_DeviceCDCBasicDemoTasks() aufruft wird darin der Merker abgefragt und wenn der gesetzt ist wird z.B. was weggeschickt und der Merker wieder gelöscht. Beim nächsten Timerinterrupt beginnt alles von vorn... Die Abfrage des Tasters im original Programm ist auch so gemacht. Wenn der Taster gedrückt wird, wird "Button pressed.\r\n" gesendet. Wie schon gesagt, das originale Programm sollte eigentlich ankommende Bytes modifiziert wider zurück schicken. (Habe ich nicht selber getestet) Falls du so was wie ein PICkit hast, kannst du ja einen Breakpoint setzten und schauen, ob das Programm in die Schleife rein springt. /* For every byte that was read... */ zu 3. lass das lieber sein, bis du weißt, was du tust ;-)
Hallo Volker, liest du noch mit? Ich hab noch eine Frage zu meiner USB Kommunikation. Habe das Beispiel mittlerweile sehr abgespeckt und in eine Methode verpackt.
1 | USB_Kommunikation(unsigned int Aktualwert) |
2 | {
|
3 | |
4 | static uint8_t readBuffer[CDC_DATA_OUT_EP_SIZE]; |
5 | static uint8_t writeBuffer[CDC_DATA_IN_EP_SIZE]; |
6 | |
7 | char data =0; |
8 | unsigned char length=1; |
9 | |
10 | writeBuffer[0] = Aktualwert; |
11 | |
12 | putUSBUSART(&writeBuffer[0], length); |
13 | |
14 | |
15 | CDCTxService(); |
Nun habe ich folgendes Phänomen: Rufe ich in meiner Methode die Methode "USB_Kommunikation" auf, klappt es mit einem Sensorwert (Aktualwert) wunderbar. Übergebe ich mehrere Sensorwerte (Aktualwert), so bekomme ich nur jeden zweiten Wert angezeigt. Weißt du worann das liegt? Mein Beispiel:
1 | void main(void) |
2 | {
|
3 | unsigned int Messwerte[4]; |
4 | int x, y; |
5 | |
6 | |
7 | Messwerte[0]= 91; |
8 | Messwerte[1]= 22; |
9 | Messwerte[2]= 17; |
10 | Messwerte[3]= 44; |
11 | |
12 | for(x=0; x<4; x++) |
13 | {
|
14 | USB_Kommunikation(Messwerte[x]); |
15 | }
|
16 | }
|
Als Beispiel habe ich dir einen HTerm Screenshot angehangen, an dem man das Phänomen erkennt...Er liest immer nur 2 der Werte.....Disconnecte ich und connecte erneut, liest er immer die anderen beiden Werte... Gruß, Simon
Du kannst nicht einfach drauflos schicken. Du musst warten, bis die Kommunikation wieder bereit ist mUSBUSARTIsTxTrfReady() Ich verstehe gar nicht, was das soll mit der Funktion. Füll doch einfach ALLE Messwerte in einen Buffer und den schickst du dann ab...
> Ich verstehe gar nicht, was das soll mit der Funktion. Füll doch einfach > ALLE Messwerte in einen Buffer und den schickst du dann ab... So hab ich es jetzt gemacht, klappt, danke :-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.