Im Beitrag Beitrag "Modbus RTU Slave Protolollstack" ging es um die Implementierung von Modbus auf einem AVR, ich hatte da angeboten meinen Code zu posten, wenn sich jemand findet der diesen Code in eine representable Form bringt. Es kamen immer wieder Anfragen per PM somit mache ich einen neuen Thread auf und poste mal den RTU Slave Teil meiner Implementation. Dieser Code basiert auf der UART Implementation von P.Fleury, mit einigen Anpassungen um die Lib modbus-faehig zu machen. Der Modbus code ist auch irgenwo abgeschrieben, ich erinnere mich an zwei quellen, eine davon war freemodbus. Freemodbus war mir aber zu gross fuer einen uC somit hab ich Ihn auf das notwendigste zusammengekuerzt. Im aktuellen Code sind auch einige Modbus Funktionen auskommentiert, zBsp. READ_INPUT_STATUS, das ist aber ziehmlich das selbe wie READ_COIL_STATUS nur mit anderem Address-Bereich FORCE_MULTIPLE_COILS PRESET_MULTIPLE_REGISTERS Hab ich auch nicht fertig implementiert da es in meinen Anwendungen nie gebraucht wurde und ich auch keine Modbus-Geraete habe die danach gefragt haben. Also dann probiert mal ob Ihr mit dem Code was anfangen koennt. Fragen an mich hier im Forum, nicht per PM, das gleiche gilt fuer Verbesserungen, somit haben alle was davon. Ju
Nochmal an Alle, Fragen bitte hier im Thread posten, nicht per PM. PM's kann nur ich lesen, die Posts jeder den es interessiert. Die Frage nach den Bus Treibern. Obiger code basiert auf der UART Lib von P.Fleury. Peters Lib wurde insoweit angepasst, das sie mit RS232 und mit RS485 funkioniert. Es muss nur die entsprechende init routine im main aufgerufen werden. Bei Verwendung von RS485 ist ein zusaetzlicher Pin am AVR zum senden notwendig. Als Bustreiber sollte alles gehen was dem entsprechenden Standard unterstuetzt. ju
Hi, leider mangelt es mir da noch an Verständnis.... 1. Wie kann man z.B. einem bestimmten Holding einen Wert zuweisen? 2. Wie kann ich einen bestimmten Holding auslesen? Ist die Datei BSP_Modbus ein Beispiel? Was soll hier passieren? Gruß Flo
> Ist die Datei BSP_Modbus ein Beispiel? Ja, das ist ein Slave er bekommt seine Adresse aus der Datei JG_Modbus.h #define SLAVE_ID 11 in diesem Beispiel Die Holdingregister sind in dem Array int16_t actProfileData[MAX_WordAddress]; und die Coil Register in int8_t systemBits[MaxActionBytes]; untergebracht, beide in der BSP_Modbus_main.c deklariert und in der JG_Modbus.c referenziert. Da kannst Du entsprechend Werte zuweisen. Der Slave ist in einer Endlosschleife. Wenn ueber den UART eine Anfrage vom Master kommt und diese vom Slave als ordentliches Modbus Datagramm erkannt wird, wird diese Anfrage vom Slave beantwortet. Die Validation ist ein Zusammenspiel von UART RX ISR und Timer2 um die Timeouts und Pausen zu erkennen, danach wird die Checksum und der Inhalt der Daten von den eigentlichen Modbus Funktionen ueberprueft und beantwortet. Der Slave lauft soweit stumm und beantwortet die Anfragen die vom Master kommen. Wenn ein Master ein Holdingregister schreibt, dann findet sich das Resultat an der entsprechenden Stelle im Array actProfileData[WordAddress] Wenn der Master ein Holdingregister liest, bekommt er den Wert der an actProfileData[WordAddress] steht. Das gleiche gilt fuer die Coil Register respektive das Array systemBits[MaxActionBytes] hier wird jede Coil-Register Adresse durch ein Bit representiert. Ein Fallstrick ist hier, das die meisten Modbus Master bei 1 anfangen zu zaehlen und die entsprechende Array Position dann Adresse-1 ist. > > 1. Wie kann man z.B. einem bestimmten Holding einen Wert zuweisen? ist somit glaube ich geklaert > 2. Wie kann ich einen bestimmten Holding auslesen? > Du kannst das nicht, das kann nur ein Modbus Master der ein entsprechendes Datagramm generiert. Da gibts einige Programme die sogar frei sind, frag mich aber nicht welche das sind. Wenn Du HTerm verwendest und Deinen AVR ueber den UART an Deinen PC haengst, kannst Du Datagramme in HEX eintippen und sie dem AVR senden, er wird Dir antworten. > Ist die Datei BSP_Modbus ein Beispiel? > Was soll hier passieren? > Ist glaub ich auch weiter oben schon beantwortet. Ju
Hallo, habe nun mal folgendes gemacht: Diese Defines für den Atmega16 angepasst: #define RS485_CPort DDRD #define RS485_Port PORTD #define RS485_Pin PIND #define RS485_Send PD1 #define RS485_PSend PIN1 Ansonsten habe ich nix verändert. Nun versuche ich über Modbus Poll auf den Slvae Atmega16 zuzugreifen. Getaktet wird der Controller mit 8Mhz mit dem internen Quarz. In Poll eingestellt: Baudrate: 9600 8 Datenbits Parität: keine 1 Stopbit Modus: RTU Mein USB Com Adapter blinkt bei TX, sprich da wird was gesendet nur auf dem Board tut sich nix. Als Polldefinition habe ich Holding Funktion 3 angegeben von 3 - 11 lesen und die Slave ID 11. Als Fehler kommt Timeout. Gruß Florian
Modbus RTU ist zeitabhaengig, die Pausen muessen exakt eingehalten werden, sonst wird das Paket nicht als gueltig erkannt. Die Timer in meinem Beispiel sind glaube ich fuer einen 16MHz Crystal konfiguriert. Da also mal als erstes ansetzen und deinen Timer so konfigurieren das er der Zeit von einem Bit Deiner serial Uebertragung entspricht. Mit dem internen RC vom Atmel und einem zeitkritischen Serial Protokoll zu arbeiten ist auch keine glueckliche Wahl. Klemm an Deinen AVR mal einen 16MHz Crystal und dessen C's dran, dann sollte es mit dem Beispiel code klappen. Ist glaube ich fuer den Einstieg das beste, spaeter wenn Du ein paar Erfolgserlebnisse hast, kannst Du immer noch mit dem RC vom AVR experimentieren. Ju
Hab jetzt mal den 16Mhz Quarz in Bewegung gesetzt. Allerdings bekomme ich nur Timeout..... Hab an deinem Code nur auf PD1 geändert, da dies am Atmega16 der TxD Pin ist.... Ansonsten ist alles unverändert... mal schauen ob es an der Hardware liegt. da verwende ich die hier: http://www.sedu-board.de/ Gruß Flo
Mit was für einem Controller hast du bei deinem Beispiel gearbeitet? Gruß Flo
flo schrieb: > Mit was für einem Controller hast du bei deinem Beispiel gearbeitet? > > Gruß Flo Die Entwicklung war auf einem m644, weil der 2 UARTs hat, der BSP Code lauft auf einem m32, sollte also Pin kompatibel zu Deinem m16 sein. Zu dem von Dir geaenderten Pin. Ich weiss nicht was Du da wo geaendert hast, es ist aber normalerweise keine Aenderung noetig wenn Du mit RS232 an den PC gehst. Die Definitionen RS485_CPort RS485_Port RS485_Send und deren Verwendung sind nur da wenn Du mit RS485 arbeitest, da gibt es einen Send_Enable Pin am Bus Treiber der vor dem senden auf High gesetzt werden muss. RS232 hat das nicht. Wenn Du obige definition auf deinen TX pin geaendert hast, dann kann das nicht funktionieren. Ju
Hi, ich nutze natürlich den RS485 Mode der wird doch auch im Beispiel genutzt. Der RTS mit dem wird die Richtung normalerweise beim Modbus dann bestimmt. Diesen hab ich auch auf einen Pin gelegt. Zunächst hatte ich hier noch nen Denkfehler drin. Aber der von dir angesprochene RS485_CPort liegt auf PD7 bei mir. Das scheint auch so zu passen. Nur bekomm ich leider nur Timeout..... Ich werd jetzt mal das Beispiel von freemodbus org testen. Gruß Flo
Hi Ju, irgendwie komme ich da nicht weiter: Hardware - Sedu Board: Atmega16 Ich habe einen USB zu RS485 Wandler am PC dran. In deinem Beispiel steht auch, dass das Beispiel für RS485 ist. Der CPort ist bei mir jetzt PD6 hab das nochmal durchgemessen, das passt jetzt eigentlich so. Bei dir war dieser Pin auf PD5 was ja eigentlich egal ist und halt nur wegen der Beschaltung ist. Als Antwort bekomme ich immer Read error : break --> Write error : break. Vielleicht liegt es auch an den Einstellungen in Modbus Poll? Auch an der Slave ID oder Baudrate habe ich nix geaendert. Kannst du mir vielleicht mal eine funktionierende Version kompilieren, die mit dem Sedu Board laufen sollte Gruss Florian
@flo Ich kenne das SEDU board nicht und habe auf der o.g. Seite auf die Schnelle keinen Schaltplan gefunden. Kannst Du mir den Link zum Schaltplan posten. Auf der Seite steht was von einem FT232, von einem Bus Treiber und Jumpern. Vielleicht solltest Du mal direkt an Deinem uC messen ob da was ankommt und das das was der uC sendet auch bis zu Deinem PC durchkommt. Ist die Baudrate richtig eingestellt? ju
Zum Besseren Verstaendniss der Definitionen in meinem Beispiel RS485_CPort => Das DDR Register RS485_Port => Der Port RS485_Send => der Ausgangs Pin des PORT Ju
Ich nutze nicht den FT232 der auf dem Sedu Board ist! Folgende Topologie: PC mit USB---> Wandler auf RS485 ---> SN75176 --> RX-TX am Atemga16 Auf dem Sedu Board wird der Jumper auf Software gesetzt und die Jumper für Tx und Rx werden gesetzt. An PD6 kann die Richtung wenn auf Software gejumpert ist geändert werden. Leider kann ich in Modbus Poll einstellen was ich will ich bekomme ständig Timeout oder Read und Write Error. Habe die Belegung am Stecker mehrmals überprüft, dass sollte passen. Welche Einstellungen müssen gemacht werden, damit die Kommunikation funktioniert? Gruß Florian
Hier noch der direkte Link zu den Unterlagen: http://www.sedu-board.de/docs/SEDU-Board_Datenblatt.pdf Gruß Flo
Fuer die Kommunikation im Beispiel ist Baud 9600 Bits 8 StopBit 1 voreingestellt. Hast Du schon mal eine ganz normale serielle Komunikation ueber RS485 zwischen Deinem PC und dem uC probiert, ohne Modbus. Ich weiss nicht wie Dein USB/RS485 Adapter funktioniert. Vielleicht versuchst Du es einfach mal mit dem FT232 vom SEDU Board und RS232. Da faellt mir gerade ein, es gab mal das Problem, das einige Modbus Poll Programme nicht mit virtuellen COM Ports arbeiten. Ist das Windows mit dem du werkelst? Ju
Hi, Naja RS232 bringt mich nicht wirklich weiter, da ich eben über den PC auch auf mehrere Slaves zugreifen will. Der FT232 ist direkt onboard..... Ich werde mal noch versuchen im Auschlussverfahren zu schauen wo es hängt.... evtl. mal einen anderen USB zu RS485 Converter nehmen.... Da ich oft mit Adaptern zu tun hab ist es mir auch bekannt, dass es da ab und an zu Problemen kommt. Ansonsten muss ich halt auch mal noch eine andere Hardware nehmen..... Gruß Flo
Mit welchem Tool hast du den ganzen Code überprüft? Vielleicht kannst du mir ja auch mal eine compilierte Version anhängen. Vielleicht läuft da was schief.... Einzige Änderung im Code wäre ja die oben angesprochene mit PD6 als RS485_send. Der Adapter blinkt in jedem Fall und es wird mir auch angezeigt, dass auf TxD was ausgegeben wird aber eben keine Antwort kommt. Dadurch entsteht ein Time Out. Baud 9600 Bists 8 Stop Bit 1 Parität: Ohne ? Inputs: Slave ID: 11 Functions Code: 4 Startadress: 0 Quantity: 10 Das sollte doch hinhauen oder....von den Konfigurationen Gruß Flo
Startadress: 0 und Functions Code: 4 geht in die Hose, Wie weiter oben schon geschrieben, Modbus faengt bei 1 an zu zaehlen und Funktionscode 4 ist READ_INPUT_REGISTERS will also Input Register lesen die im Beispiel nicht verwendet werden. Das Beispiel liest und schreibt Holding Register und Coils. Im Beispiel sind actProfileData[IDX_DW_Debug01] = 101; actProfileData[IDX_DW_Debug02] = 102; actProfileData[IDX_DW_Debug03] = 103; Holding Register und haben die angegebenen Werte. die Positionen im Array sind IDX_DW_Debug01 35 IDX_DW_Debug02 36 IDX_DW_Debug03 37 Somit musst Du modpoll mit Slave ID: 11 Functions Code: 3 Startadress: 36 Quantity: 3 aufrufen und solltest 101, 102 und 103 zurueck bekommen. Ju
Hi, ja inputs wird nicht unterstützt.... aber ich bekomme auch keinen Holding zum laufen. Slave ID: 11 Functions Code: 3 Startadress: 36 Quantity: 3 Ergebnis: TimeOut Baud 9600 Bists 8 Stop Bit 1 Parität: Ohne ? Ja ich werkle mit Windwos.... aber der RS485 Adpater gibt auch saubere Signale aus, dass sieht man am TxD Pin... nur kommt nix zurück?! Die Antwort fehlt. Komme hier auf keinen wirklich grünen Zweig.... Hast du am verlinkten Schaltplan irgendwas gesehen was es sein könnte, dass die Funktion nicht gewährleistet ist? Werde mir wohl doch einen anderen AVR schnappen und einen Bustreiber dran bauen und dann mit dem USB --> RS485 Adapter nochmal versuchen.... wird aber noch bisschen dauern, da ich da sicher nicht alle teile parat habe.... :) Gruß Flo
Hi, habe beim stöbern im Internet den Beispiel Code gefunden und habe festgestellt das er recht übersichtlich ist. Allerdings bekomme ich den Modbus Slave nicht zum laufen, vielleicht kann mir ja jemand helfen oder hat eine Idee wodran es liegen könnte. Ich benutze ein Stk500 mit einem Atmega32. Habe einen externen Quarz mit 16Mhz angeschlossen. Als Bustreiber verwende ich einen Max487. RE/ und DE des Bustreibers habe ich mit PD5 des Stk500 verbunden. RO und DI sind mit PD0 und PD1 (RX und TX) verbunden. Nun Versuche ich mit Hilfe von Modbus Poll die Holding Register auszulesen. Allerdings bekomme ich immer ein Read Error:Break condition. Habe in Modbus Poll folgende einstellungen vorgenommen: Connection: Serial Port - 9600 Baud - 8 Data Bits - None Parity - 1 Stop Bit Read Write Definition: Slave ID 11 Function:03 Address: 36 Quantity:3 Scan Rate 1000 ms Über eine gute Idee oder anmerkung wo mein fehler liegen könnte würde ich mich freuen. Gruß Hauke
Hallo Hauke, die Einstellungen von Modbus Poll sind OK. Ich tippe auf ein Hardware Problem. Kannst Du die Signale zum Max487 verfolgen? Und die Signal A und B (oder + und -) auf der RS485 Leitung. Evtl vertauscht. Gruss Ju [edit] check auch die PD0 und PD1 Verbindung zwischen Atmega und MAX RO sollte auf RXD und DI auf TXD sein. [noch ein edit] und an die RE/ und DE Pins des Max sollte ein PullUP oder PullDown hin
Hallo Juergen, erstma recht vielen dank fuer deine schnelle Antwort. Habe die Leitungen zwischen dem Atmega und dem MAX nochmals verfolgt. Die Verdrahtung ist wie du oben geschrieben hast. Habe das Signal am RXD des Atmegas mal mit einem Oszi aufgezeichnet und im Anhnag gepostet. Zusätzlich habe ich ´RE/ und DE des MAX mit einem 2k2 Widerstand auf GND gelegt. Allerdings bekomme ich immer noch keine Antwort vom ATmega bin langsam ein wenig am verzweifeln. Muss ich vielleicht irgendwelche Fuse Bits setzten? Nutze seit neustem AVR Studio 5, habe nur unter Tools --> AVR Pogramming --> Fuses ---> SUT_CKSEL die Fuses auf EXTHIFXTALRES_1KCK_64MS gesetzt. Vielleicht habe ich da auch einen Fehler gemacht? Über weitere Anregungen, wo ich noch nach fehlern suche könnte würde ich mich freuen. Wie gesagt bin bei diesem Projekt ein wenig am verzweifeln. Danke schon mal im vorraus Gruß Hauke
Fuses, uff, lass mich mal nachdenken. Ich meine wenn die Clock fuses richtig gesetzt sind, also so das Dein Atmega mit dem 16MHz Cristal auch mit 16MHz rennt sollte es gut sein. Allerdings hat der AtMega32 auch noch die JTag Fuse, diese betreffen aber nur den PortC. AVR Studio hab ich keine Ahnung, bei mir stehen die lfuse auf 0xFF hfuse auf 0xD9 Ju
Moin, ok die waren richtig gesetzt. Am code habe ich nichts geändert. Vielleicht sonst noch eine Idee, wo sich ein Fehler eingeschlichen haben könnte? Gruß Hauke
Wenn das soweit alles OK ist, hilft nur zu untersuchen an welchem Punkt die Komunikation aussteigt. Ich gehe davon aus dass Du den Code http://www.mikrocontroller.net/attachment/113765/BSP_Modbus.zip verwendest. Als erstes: rufe den modpoll mal so auf das nur nach einem Word gefragt wird Also Connection: Serial Port - 9600 Baud - 8 Data Bits - None Parity - 1 Stop Bit Read Write Definition: Slave ID 11 Function:03 Address: 36 Quantity:1 und im main()
1 | if (uart0_status.status == RS_FrameComplete) { |
2 | if (UART_RxHead) { |
3 | modbus_processSlaveFrame((uint8_t*) UART_RxBuf, UART_RxHead); |
4 | }
|
5 | uart_flush(); |
6 | uart0_status.status = RS_Wait; |
7 | }
|
wackelst Du an den entsprechenden Stellen mal an einem Pin des uC's um zu sehen welcher Teil der Bedingungen erfuellt ist. Wenn Du siehst das modbus_processSlaveFrame() aufgerufen wird dann etwas tiefer gehen und im File JG_Modbus.c am Ende des Files in der Funktion modbus_processSlaveFrame()
1 | void modbus_processSlaveFrame(uint8_t *query, int query_length) { |
2 | uint8_t cnt = 0; |
3 | |
4 | if (check_crc16(query, query_length) == query_length) { |
5 | modbus_slave_manage(query, query_length); |
6 | } else { |
7 | for (cnt = 0; cnt < UART_RX_BUFFER_SIZE; cnt++) { |
8 | query[cnt] = 0; |
9 | }
|
10 | }
|
11 | }
|
sehen ob der CRC Check durchgeht. Ich hatte schon modpoll Programme die einen eigenen CRC Key verwendeten. Wenn der CRC check durchgeht, im selben File in der Funktion modbus_slave_manage()
1 | switch (sft.function) { |
2 | ...
|
3 | }
|
sehen mit welcher Funktionsnummer der modpoll tatsaechlich daherkommt. Ich hatte es schon, das der Master eigentlich mit 03 READ_HOLDING_REGISTERS daherkommen sollte tatsaechlich kam er aber mit 04 READ_INPUT_REGISTERS daher. und da in meinem Code nicht alle Funktions Nummern komplett implementiert sind kann es da unter Umstaenden zu Missverstaendnissen kommen. Gruss Ju
Moin, schön dank für die Anregungen. Habe den Fehler nun auf dem STK500 festgestellt. Den Grund dafür kenne ich aber nicht. Habe die Schaltung nochmal auf einem extra Board aufgebaut und nun funktioniert es. Allerdings bekomme ich immer nur ein bis 2 Antworten. Den Fehler hierfür habe ich in der Sende Empfangs Umschaltung festgestellt. Also PD5 bleibt auf hight Pegel stehen und Schaltet nicht wieder zurück aul low. Wenn du hier zu noch eine idee hättest wäre ich dir echt dankbar. Gruß Hauke
Freut mich das es jetzt klappt. Ich kann mir nicht vorstellen warum das mit dem zurueckschalten in den Empfangsmodus nicht tut. Wenn es einmal tut sollte es immer tun, da es per ISR gemacht wird. Wenn kein bit mehr zu senden ist geht der Pin Low. im File Modbus_uart.c
1 | ISR(USART0_TX_vect) { |
2 | |
3 | if (is485) { |
4 | RS485_Port &= ~(1<<RS485_Send); |
5 | }
|
6 | }
|
Moin, der Code scheint so weit zu passen. Habe das Signal an RE/ und DE mal mit dem osi aufgezeichnet. Nehme ich die Betriebsspannung vom Atmega weg und steck sie wieder ran bekomme ich immer einmal eine Antwort und wie vermutet schaltet der PD5 nach dem senden nicht wieder ab. Gruß Hauke
Laeuft der Compiler im AVR Studio fehlerfrei durch wenn Du erst ein "make clean" und dann ein make machst?
Wenn der Compiler auf speed otimiert ist habe ich keinen Fehler beim Compilieren, auch wenn ich vorher auf Build --> clean gehe. Stelle ich allerding ein das nicht optimiert werden soll bekomme ich den Fehler undefined reference to 'setBitValForSysBit' nehme ich allerdings das inline vor der funktion weg, so ist auch der Fehler verschwunden.
Das ist soweit OK, lass das inline besser dort und compilire das es damit lauft. Ich wollte wissen ob der Compiler evtl. irgendwelche Definitionen vermisst und folglich nicht die TX ISR anspringt. Da das aber in Ordnung ist, ist irgendwo anders der Wurm drin. Es sieht so aus als ob der Atmega noch etwas zum senden hat, dein Master es aber nicht haben will. Gruss Ju
Habe den Signal verlauf von PD5 nochmal aufgezeichnet, so wie es aussieht scheint der Atmega nach dem ersten senden den PD5 PIN wieder auf low zu setzen. Allerdings wird der PIN dann nach dem zweiten senden nicht wieder zurückgesetzt. Vielleicht eine Idee woran es liegen könnte?
Der einzigste Punkt im ganzen Code wo der RS485_Send (PD5) auf high gesetzt wird ist im File Modbus_uart.c in der Function uart_putc() bevor gesendet wird, und wenn alle Bytes raus sind wird er in der ISR USART0_TX_vect wieder auf Low gesetzt. Wenn Du keinerlei Aenderungen am code gemacht hast sollte dieser Pin nur zum senden High sein. Durchsuch mal Deinen Code ob Du diesen Pin nicht zufaellig als irgend einen indikator fuer debug zwecke nimmst oder Du uart_putc() irgendwo anders noch aufrufst. Dein Oszi zeigt das der Pin etwa 800ms nach dem er nach dem senden abgeschaltet wurde wieder auf High geht. Das ist zu lange um eine Antwort auf ein Packet zu sein. Das erste High kommt gleich nach der Anfrage, das zweite High kommt 1s nach der ersten Anfrage. Das sieht aus als ob Dein modpoll 2 mal fragt, die zweite Antwort jedoch ignoriert. Rufe mal Dein modpoll so auf, dass er nur einen Versuch macht. Ju
Moin, habe es seit langem mal wieder geschafft am Projekt zu basteln. Habe einen zweiten Slave aufgebaut und einen Wago Buskoppler als MAster eingesetzt. Nach der Pause habe ich den auch den kleinen Fehler im Code gefunden und zwar in der Modbus_uart.h im Teil wo der Atmega32 definiert wird steht: #define TXCIE TXEN das TXEN habe ich nun durch TXCIE ersetzt und es funktioniert. Nochmals vielen dank für deine Hilfe. Gruß Hauke
Danke für den Kode! Ich habe ein Testprogramm auf einem ATmega48 fast ohne Probleme zum Laufen bekommen. Ein erster Vorschlag zur Verbesserung besteht darin, die Interruptrate aus der gesetzten Baudrate abzuleiten:
1 | void initInterrupts(void) |
2 | {
|
3 | // TC2 used for Modbus Timeout
|
4 | // CTC mode 32 prescaler
|
5 | // one interrupt per bit length
|
6 | // baudrate is F_CPU / (16*UBRRx)
|
7 | // UBRRx < 500 for common baudrates and F_CPU=8MHz
|
8 | //
|
9 | // call initInterrupts() after baudrate init!
|
10 | TCCR2A = (1 << WGM21) | (0 << WGM20); |
11 | TCCR2B = (1 << WGM22) |
12 | | (0 << CS22) | (1 << CS21) | (1 << CS20); |
13 | OCR2A = UBRR0 >> 1; |
14 | TIMSK2 |= (1<<OCIE2A); |
15 | }
|
Gruß aus Uppsala, Uwe.
..bei der Abfrage der Coils bzw. Inputs wird eine falsche Anzahl von Daten Bytes zurück gesendet. Der Fehler scheint durch die Aufsummierung der Datenmenge + Startadresse in der for{} Schleife zu entstehen, da die Variable ic mit 0 und nicht mit der Startadresse beginnt, sollte hier die Datenmenge reichen! geänderter Code: static int response_io_status(sft_t *sft, uint8_t *stab, uint8_t *response, int offset) { uint8_t sBit = sft->address; uint8_t startByte = (uint8_t)(sBit / 8); uint8_t nOBytes = (uint8_t)(sft->nb / 8) + ((sft->nb % 8)?1:0); //uint8_t bytesToThread = nOBytes + ((sft->address % 8)?1:0); uint8_t ic; uint8_t destByte = 0, intermByte = 0; for (ic = 0; ic < nOBytes; ic++){ // getting the first byte where we have to get Bit's from ..
Hallo zusammen, ich habe das ganze mal probiert und komme leider nicht weiter. Ich bin so vorgegangen: -Neues Projekt im AVR Studio erstellt (Atmega16) -Dateien dem Projekt hinzugefügt. -F_CPU auf 10MHZ gesetzt in den Projekteigenschaften. -Timereinstellungen angepasst: void initInterrupts(void) { // TC2 used for Modbus Timeout and sysSec Counter TCCR2 |= ((1<<CS21)); //Prescaler auf 8 setzten OCR2 = 116; //Wert vorladen TIMSK |= (1<<OCIE2); } In der Beispieldatei auf RS232 umgestellt. rs323_init(UART_BAUD_SELECT(9600,F_CPU)); statt rs485_init(UART_BAUD_SELECT(9600,F_CPU)); Compilieren erzeugt keine Fehler und läuft sauber durch. Die Fuses sind auf externen Quarz gesetzt. JTAG ist aus. Das Board hängt direkt über RS232 am Rechner dran (MAX232 dazwischen) Hardwareaufbau funktioniert mit einfachem Sende/Antworte Programm. Denke daran liegt es nicht. Hab ich irgendwas noch übersehen? Besten Dank F.
Ich frage über Modbus Poll die SlaveID 11 und Adresse 36 ab. Bekomme abwechselnd Write Error und Read Error: Framing Error. F.
Hat sich erledigt, in Modbus Poll war noch die Parität auf Even eingestellt... Sehr vielen Dank an Juergen!
Juergen G. schrieb: > Modbus RTU ist zeitabhaengig, die Pausen muessen exakt eingehalten > werden, sonst wird das Paket nicht als gueltig erkannt. > > Die Timer in meinem Beispiel sind glaube ich fuer einen 16MHz Crystal > konfiguriert. Da also mal als erstes ansetzen und deinen Timer so > konfigurieren das er der Zeit von einem Bit Deiner serial Uebertragung > entspricht. Hallo, ich weiß, dass es ein alter Thread ist, aber ich habe eine Frage zur Bitzeit. Wie ist die zu verstehen? Nach meiner Rechnung passen die Einstellungen nicht zusammen, es funktioniert aber... Ich habe das Beispiel erfolgreich auf einem AT90CAN als RS232 Variante mit 9600 Baud und externen 16 MHz laufen. Vielen Dank für das kurze Beispiel! Timer zwei ist auf Prescaler 8 gestellt und wird mit 32 vorgeladen. Macht nach meiner Rechnung 16MHz/8=2MHz. (1/2MHz)*32=16us 9600 Baud (in bits per second laut Datenblatt) ist 1/9600=104us. Irgendwo muss ich da etwas falsch verstehen.
In der Datei JG_Modbus.c muss in der Funktion modbus_slave_manage() ein "break" entfernt werden. Es verhindert den Zusammenbau einer gültigen Nachricht und liefert nur FF FF als Antwort. Das richtige break ist schon da.
1 | case FC_PRESET_SINGLE_REGISTER: |
2 | |
3 | data = (query[offset + 3] << 8) + query[offset + 4]; |
4 | |
5 | if (sft.address >= MAX_WordAddress) { |
6 | |
7 | resp_length = response_exception(&sft, ILLEGAL_DATA_ADDRESS, |
8 | response); |
9 | } else { |
10 | |
11 | if ((sft.address < MAX_WordAddress)){ |
12 | actProfileData[sft.address] = data; |
13 | break; // <<<< remove this break; it breaks before a proper response could be built |
14 | }
|
15 | |
16 | memcpy(response, query, query_length); |
17 | resp_length = query_length; |
18 | }
|
19 | break; |
20 | case FC_FORCE_MULTIPLE_COILS: |
21 | //...
|
Hallo, hätte hier noch etwas: https://github.com/mbs38/yaMBSiavr Eine Implementierung, die auch die Function Codes "Force Multiple Coils" und "Force Multiple Registers" unterstützt. Allerdings muss man ihr die verschiedenen Baudraten noch per Hand beibringen, da sie nicht auf Fleurys Library basiert. Dafür ist die Lib recht gut kommentiert. Dabei ist auch ein Beispiel für den Atmega88, das bei mir zu 2,9k kompilliert. Vielleicht nützt das ja jemandem :) CB
Hallo Christian, die genannte Implementierung stammt von mir. Danke für die Blumen. Ich hab die Verlinkung hier mal als Anlass genommen mal ein Release zu machen und ein paar Sachen sauberer reinzuschreiben und so. Falls es jemand brauchen kann: https://sourceforge.net/projects/yambsiavr/
Hallo, ich versuche seit einigen Tagen meinen ATMega644PA den Modbus beizubringen. Ich plane ein derzeit ein Projekt mit dem ATMega und einem Siemens OP177.. die Kommunikation läuft deshalb zwangsweise über den Modbus. Nun versuche ich schon einige Tage mich durch diverse Beispiele zu wuseln um einen funktionierenden Code hinzubekommen. Ich arbeite derzeit mit einem Pollin Evaluation Board und einem USB zu RS485-Adapter. Habe jetzt den ATMega mit TX/RX und Richtungspin an einen MAX485 angeschlossen und diesen mit dem USB->RS485 Adapter verbunden. Leider bekomme ich über Modbus Poll nur ein TimeOut. Angehängt habe ich meine beiden Projekte mit den jeweiligen Beispielen. ModbusPoll: Baudrate je nach Bsp. 9600 oder 38400 8 Bit Daten 1 Stoppbit keine Parity keine Flowcontrol
Hallo Gorden, ich hab mir MB-yaMBSiavr.zip angeschaut. Dein Timer sorgt bei 16Mhz, und Prescaler 8 für einen Interrupt alle 128µs, anstatt alle 102,5µs wie im Beispiel. Daher solltest du in der yaMBSiavr.h in den Zeilen #define modbusInterFrameDelayReceiveStart 16 #define modbusInterFrameDelayReceiveEnd 18 #define modbusInterCharTimeout 7 die Werte auf 14, 15 und 6 ändern, damit das wieder passt. Das sollte allerdings nicht der Grund gewesen sein, warum es nicht funktioniert :P Aber: Du weißt, dass der UART1 verwendet wird und nicht UART0? In Modbuspoll hast du auch die richtige Device Adresse (hier 1) und auch nur die im Beispiel vorhandenen Register/Coils oder was auch immer ausgewählt? Viele Grüße, M
:
Bearbeitet durch User
Hi Max, danke für die schneller Antwort, und sorry dass ich dich zuerst per PN angeschrieben hab und dann das hier noch gepostet habe. Zur Sache: Erstmal danke für die Einstellungsanpassung. Auf die Gefahr hin, dass ich jetzt (jetzt erst recht wo ich es noch schreibe) gesteinigt werde: der ATMega644PA hat ja zwei USARTS und kein UART.. nun ist in der Library doch alles so angepasst, dass die Adressierung hinhaut, gibt ja auch beim Kompilieren keine Fehler.. soweit so gut. Da du sagst dass USART1 benutzt wird: USART1 geht laut Datenblatt auf den PORTD dementsprechend habe ich die PORTD PIN 0 und 1 (RX/TX) auch an den MAX485 angeschlossen.. sollte also auch passen. Das Modbus Poll-Programm hab ich entsprechend der in deinem Beispiel definierten Holdingregister eingestellt.. also 0..3, sollte diese Adresse falsch sein, sollte ich doch aber Read/Write-Error bekommen und kein plumpes Timeout oder? Slaveadresse 1 ist soweit auch definiert und die entsprechenden Einstellungen wie oben zusätzlich habe ich den USB-COM-Anschluss genauso eingestellt, falls das nicht eh schon das modbus poll programm macht. Ich werde gegen 18 Uhr nochmal die angepassten Daten einspeisen und dann testen. Es könnte auch sein, dass mein MAX485 irgendeinen defekt. Die Pegel an A/B ändern sich jedenfalls nicht wenn ich Polle, aber ich messe auch nur mit einem Multimeter, habe leider kein Oszi zuhause, wenn ich das mal im Labor teste, was müsste ich da "ungefähr" auf dem Oszi sehen?
Gorden H. schrieb: > PORTD PIN 0 und 1 (RX/TX) Nope. PD2 und PD3 sind es. Und das wird dann noch mit dem TXenable/RXdisable kollidieren. In der yaMBSiavr.h steht: /* * Definitions for transceiver enable pin. */ #define TRANSCEIVER_ENABLE_PORT PORTD #define TRANSCEIVER_ENABLE_PIN 2 #define TRANSCEIVER_ENABLE_PORT_DDR DDRD Das musst du dann noch auf irgendeinen anderen freien Pin deiner Wahl umkonfigurieren und die beiden RXdisable/TXenable pins des MAX485 da dran anschließen. M
:
Bearbeitet durch User
So ich bin jetzt wieder am Objekt. Danke für die Lesenachhilfe, manchmal ist man einfach zu blind :(. Habe jetzt folgenden Aufbau:
1 | ATMega MAX485 USB->RS485-Adapter |
2 | ________ |
3 | PD2 1|RO Vcc|8 5V |
4 | | | |
5 | PD7 2|/RE B|7 485- |
6 | | | |
7 | PD7 3|DE A|6 485+ |
8 | | | |
9 | PD3 4|DI GND|5 GND verbunden mit Board GND |
10 | |________| |
11 | |
12 | Vcc und GND hängt noch ein 10µF |
13 | Muss an PD7 ein Pullup/down Widerstand sein? |
Habe den Pin in der yaMBSiavr.h entsprechend angepasst auf 7. Somit sollte der HW-Aufbau jetzt ja endlich auch richtig sein (hoffentlich) Leider bekomme ich über den Modbuspoll weiterhin nur ein Timeout. Im Ruhezustand (USB-RS485 angeschlossen und verbunden mit dem Board, aber kein Modbuspoll) messe ich jeweils gegen GND: RO: 4,90 V DI: 4,90 V A: 0,30 V B: 0,17 V Wenn ich mit Modbuspoll polle genauso. Sind die Pegel an A/B nicht irgendwie zu niedrig, bzw. die an PD 2/3 zu hoch? Irgendwie hab ich das Gefühl, dass sich alle beteiligten Geräte gegen mich verschworen haben.
Gorden H. schrieb: > und diesen mit dem USB->RS485 Adapter verbunden. Könnte es sein, daß Dir dieser Adapter das Timing verdirbt?
m.n. schrieb: > Könnte es sein, daß Dir dieser Adapter das Timing verdirbt? Kann gut sein, leider habe ich keine reine Serielle Schnittstelle mehr in den PCs/Laptops, bin deshalb auf einen USB-Adapter angewiesen zum Testen. Link zum Adapter: http://www.digitus.info/mx/produkte/zubehoer/adapter-und-konverter/r-usb-seriell-adapter-usb-20-da-70157/ "Datenblatt" leider nicht viel Infos http://datasheet.digitus.info/de/4016032307433.html
Gorden H. schrieb: > Muss an PD7 ein Pullup/down Widerstand sein? nein. Gorden H. schrieb: > RO: 4,90 V > DI: 4,90 V > A: 0,30 V > B: 0,17 V Ist völlig normal. Hast halt keine Bias-Schaltung gebaut für den Bus.. http://www.ni.com/images/support/us/bias.gif Dürfte aber trotzdem funktionieren. Der Adapter müsste theoretisch gehen. Nimm mal HTERM oder so und schick mal ne Modbus Message per Hand. Vorher in yambsiavr.c einfach die crc funktion so verändern, dass sie immer 0x1234 liefert. Dafür musst du nur out=0x1234 einkommentieren. Dann einfach mal 01 03 00 00 00 03 34 12 hinschicken. Dann müsste was zurückkommen... Ansonsten mal mit nem zweiten seriell->usb wandler mal direkt auf den RO vom MAX485 hängen und gucken was da so kommt. Da sollte das gleiche ankommen. Wenn das schon nicht der Fall ist naja ne... ^^
Huhu, zum HTerm: Port COM4 (ist der USB 485 adapter) Data 8 Stop 1 Parity None und kein CTS Flow Control... Wenn ich Connecte sehe ich keine CTS DSR RI DCD LED - aber sind vielleicht eh nie an bei der Hardware.. Wenn ich jetzt "01 03 00 00 00 03 34 12" sende über "HEX" und dann Enter so dass es im Transmitted steht... habe also das Gesendet(?), erhalte aber nichts zurück.. :( Einen zweiten USB/Serielladapter habe ich leider nicht rumfliegen, der hier war schon eine Neuanschaffung für den Zweck.
:
Bearbeitet durch User
Gorden H. schrieb: > Wenn ich jetzt "01 03 00 00 00 03 34 12" sende über "HEX" und dann Enter > so dass es im Transmitted steht... habe also das Gesendet(?), erhalte > aber nichts zurück.. :( Dann hast du es gesendet. Ansonsten halt (Speicher-)Oszi an RO halten. So richtig gut sehen ob was Vernünftiges kommt kann man dann mit Hirnschmalz+Speicheroszi oder nem weiteren FTDI Ding: > Einen zweiten USB/Serielladapter habe ich leider nicht rumfliegen, der > hier war schon eine Neuanschaffung für den Zweck. Dann würde ich noch einen zweiten anschaffen. Kann man immer brauchen. Kostenpunkt unter 5 Euro bei ebay.
:
Bearbeitet durch User
Max B. schrieb: > Dann würde ich noch einen zweiten anschaffen. Aus Erfahrung: um Digitus mache ich schon seit vielen Jahren einen weiten Bogen.
m.n. schrieb: > Max B. schrieb: >> Dann würde ich noch einen zweiten anschaffen. > > Aus Erfahrung: um Digitus mache ich schon seit vielen Jahren einen > weiten Bogen. Ich meinte irgendein Board mit einem TF232 drauf...
Also um das ganze nochmal abzurunden.. am Code liegt es dann wohl nicht mehr? und Hardware ist soweit auch ok. dann besorg ich mir wohl nochmal nen neuen Max485 da bei dem den ich hab nicht zu 100% klar ist, ob er überhaupt noch ganz funktionabel ist. Das Problem ist, dass ich mit der ganzen Sache schon unter Zeitdruck stehe, da tut quasi jeder Tag an dem ich nicht weiter komme weh :/ Aber trotzdem nochmal ein großes Danke an euch, dass ihr mich soweit an die Hand genommen habt. Bin nur leider grad an dem Punkt wo ich überlegen muss, ob ich die RS485/Modbus-Sache begrabe und stattdessen auf ein herkömmliches 0815-LCD+Matrixtastertur downgrade, was ich direkt oder über einen zweiten µC anspreche.
:
Bearbeitet durch User
Hi, vielleicht würde das als Ersatz für meinen blanken max485 dienen um den fehlerhaften maxi auszuschließen. hoffe der Link geht so. http://www.segor.de/#Q=RS485-TTLModul&M=1 Der Direktlink geht leider nicht. Einmal auf neuer Katalog gehen dann nach RS485 suchen, dann taucht das RS485 TTl Modul auf. Und zusätzlich nochmal einen anderen USB RS485 Wandler meinst du?
:
Bearbeitet durch User
Einfach mal so gefragt. Wie lang sind denn Deine Leitungen zwischen den beiden "Endgeraeten" sind die Leitungen verdrillt hast Du Abschluss R's dran? wenn die Leitungen kurz sind und keine R's dran sind, haben es die Max schwer da was richtiges zu erkennen. Das Du einen Max gegrillt hast sehe ich eher als unwarscheinlich an. Die MAX sind meiner Erfahrung nach sehr robust, da brauchs schon einiges um die kaputt zu machen. Ju
In der Tat sind die Leitungen zur Zeit zum Testen sehr kurz, nur ein paar Zentimeter um genau zu sein. Hätte nicht gedacht, dass sich das noch negativ auswirken könnte. Was für einen Abschlusswiderstand würdest du empfehlen, habe jetzt zwischen 100 und 120 Ohm gelesen die ich dann am Max an den A/B anschließe, und das gleiche am USB-RS485 Wandler? Zum Grillen: Das Siemens OP177 hat eine serielle Schnittstelle mit SubD9 Buchse. Das Pinout ist abweichend zum RS422/485 und zusätzlich ist auf einem Pin auch noch +24V. Das hab ich aber quasi in meiner Naivität in den Anfängen nicht überprüft, deshalb kann es sein, dass der MAX (welcher ineinem rs458/rs232 Adapter verbaut war gegrillt wurde, habe den jetzt quasi ausgebaut um mir die RS232/485 Wandlung als Fehlerquelle zu sparen, und den ATMega direkt über RS485 kommunizieren zu lassen.
Gorden H. schrieb: > Bin nur leider grad an dem Punkt wo ich > überlegen muss, ob ich die RS485/Modbus-Sache begrabe und stattdessen > auf ein herkömmliches 0815-LCD+Matrixtastertur downgrade, was ich direkt > oder über einen zweiten µC anspreche. Ich kenn weder das Siemens Gerät noch Deine Anforderungen. Aber wenn eine Lösung mit eigenem µC reichen würde, würde ich das vermutlich so machen. Falls es noch woanders klemmt, hast Du größeren Spielraum bei der Anpassung. m.n. schrieb: > Max B. schrieb: >> TF232 > > ? Offensichlich ein unkorrigierter Tippfehler, aber auch zu TF232 gibt es etliche Treffer bei der Suche. Aktuell möchte hier jemand ein 433mhz-Signal über Antenne empfangen. Wieviel km Länge muß diese wohl haben?
Die Angabe des Siemens-Gerätes war auch nur der Vollständigkeit halber. Sinn ist halt eine Visualisierung von Füllständen von eingegrabenen Tanks. Diese sollen dann befüllt/entleert werden können bzw. der Gartenteich und die Rasensprenger durch diese Tanks gespeist werden. Mit einem kleinen 2 Zeilen Display wäre das mühselig. Die HMI würde da schon viel Comfort bieten zur Auswahl von Ventilen etc., und ich kann diese halt gut selbst Projektieren aus Erfahrung.
m.n. schrieb: > Max B. schrieb: >> TF232 > > ? > Ich lerne gerne dazu. Sorry. FTDI FT232 war gemeint. Gorden H. schrieb: > Hi, vielleicht würde das als Ersatz für meinen blanken max485 dienen um > den fehlerhaften maxi auszuschließen. hoffe der Link geht so. > http://www.segor.de/#Q=RS485-TTLModul&M=1 > Der Direktlink geht leider nicht. Einmal auf neuer Katalog gehen dann > nach RS485 suchen, dann taucht das RS485 TTl Modul auf. > Kannste machen. Kannst auch wenns drängt einfach zu Conrad oder so gehen und einen max481, max485 oder ähnlich verlangen. > Und zusätzlich nochmal einen anderen USB RS485 Wandler meinst du? USB zu UART auf TTL Pegel. Sowas kann man zum Testen eben auch ohne MAXxxx an den Atmel hängen. jup schrieb: > Wie lang sind denn Deine Leitungen zwischen den beiden "Endgeraeten" > sind die Leitungen verdrillt > hast Du Abschluss R's dran? Bei der Baudrate und Kabellänge ist Verdrilltheit und Reflektionsfreiheit durch Abschluss mit Sicherheit egal. Das Biasing mitsamt einem Widerstand in der Mitte des Teilers sollte man aber auf jeden Fall machen, da es ja vorkommen kann, dass keiner der auf dem Bus vorhandenen Treiber gerade nicht hochohmig ist. jup schrieb: > Das Du einen Max gegrillt hast sehe ich eher als unwarscheinlich an. Die > MAX sind meiner Erfahrung nach sehr robust, da brauchs schon einiges um > die kaputt zu machen. Kommt drauf an. RS485 Spec verlangt, dass man +-12V anlegen kann, ohne, dass etwas kaputtgeht. Nicht jedoch 24V. Damit habe ich auch schon mal um die 20 MAX481 auf einem Bus auf einen Schlag gegrillt... Es gibt natürlich zB. sowas wie MAX13442E, an den man sogar +-80V anlegen kann :P Gorden H. schrieb: > Zum Grillen: Das Siemens OP177 hat eine serielle Schnittstelle mit SubD9 > Buchse. Das Pinout ist abweichend zum RS422/485 und zusätzlich ist auf > einem Pin auch noch +24V. Sicher, dass das Ding Modbus spricht? Hab das nicht direkt finden können.
Max B. schrieb: > Gorden H. schrieb: >> Zum Grillen: Das Siemens OP177 hat eine serielle Schnittstelle mit SubD9 >> Buchse. Das Pinout ist abweichend zum RS422/485 und zusätzlich ist auf >> einem Pin auch noch +24V. > > Sicher, dass das Ding Modbus spricht? Hab das nicht direkt finden > können. https://cache.industry.siemens.com/dl/files/461/21084461/att_82592/v1/hmi_tp177a_tp177b_op177b_operating_instructions_en_US_en-US.pdf Lt. Datenblatt Seite 29 Spricht es Modbus unter Verwendung eines Siemens-Adapters. Meine Herangehensweise war bisher die: solange die Kommunikation zwischen PC und ATMega über RS485 und Modbus nicht funktioniert, will ich es erst gar nicht am Panel versuchen, weil das Gerät auch keinerlei Debug-Funktionen bietet um zu überprüfen ob überhaupt was passiert. Das einzige was man sich anzeigen lassen kann, ist ob der anzuzeigende Wert gelesen wird (wenn keine Kommunikation werden nur "####" angezeigt sonst halt der Wert). Aber vermutlich werde ich mal parallel als Notlösung mit einem kleinen Display anfangen, vielleicht mit einem zweiten µController für Matrixtastatur und LCD. eine Kommunikation ATTiny<->Atmega oder Atmega<->Atmega sollte ja hoffentlich für mich hinzubekommen sein.
Gorden H. schrieb: >> Sicher, dass das Ding Modbus spricht? Hab das nicht direkt finden >> können. > > https://cache.industry.siemens.com/dl/files/461/21084461/att_82592/v1/hmi_tp177a_tp177b_op177b_operating_instructions_en_US_en-US.pdf > > Lt. Datenblatt Seite 29 Spricht es Modbus unter Verwendung eines > Siemens-Adapters. Aha. Da steht nicht, dass das Ding Modbus-Master sein kann. Hört sich für mich mehr so an, als würde es ein Client für eine der in dem Tabellenfeld daneben aufgeführten SPSen sein. Gorden H. schrieb: > Aber vermutlich werde ich mal parallel als Notlösung mit einem kleinen > Display anfangen, vielleicht mit einem zweiten µController für > Matrixtastatur und LCD. eine Kommunikation ATTiny<->Atmega oder > Atmega<->Atmega sollte ja hoffentlich für mich hinzubekommen sein. Kannste prinzipiell auch Modbus für nehmen.
Also ich nutze für Modbus am AVR (ATmega88 und ATtiny841) immer freemodbus. Sowohl für RTU als auch TCP. Funktioniert super. http://www.freemodbus.org/ Für den PC nimm ich libmodbus. Z.B. für ein Modbus-Tester, der mir dann verschiedene Funktionen nacheinander durchtestet. Also selbstgeschriebene Programme. http://libmodbus.org/ Und als USB/RS485-Adapter den http://www.amazon.de/In-Circuit-901-274-USB-RS485-Adapter-Blau-Gr%C3%BCn/dp/B00I9H0998 Der hat die Bias-Schaltung auch schon mitdrin. Wenn das Panel ein Client/Master ist. Dann muss der AVR natürlich Server/Slave sein.
:
Bearbeitet durch User
Mathias O. schrieb: > Also ich nutze für Modbus am AVR (ATmega88 und ATtiny841) immer > freemodbus. > Sowohl für RTU als auch TCP. Funktioniert super. > http://www.freemodbus.org/ Hab ich auch schon benutzt. Habe dann dennoch eine eigene Implementierung speziell für den AVR geschrieben, weil ich es auch auf einem in einem Gerät bereits vorhandenen attiny2313 laufen lassen wollte - dafür ist freemodbus aber zu bloated. Mathias O. schrieb: > Für den PC nimm ich libmodbus. Z.B. für ein Modbus-Tester, der mir dann > verschiedene Funktionen nacheinander durchtestet. Also > selbstgeschriebene Programme. > http://libmodbus.org/ Schöner ist natürlich eine fertige GUI zum Testen. Ich hab auch immer einfach python script geschrieben mit pymodbus dahinter. Hast du eine nette GUI zur Hand?
Ja tut es. Stürzt allerdings sehr gerne ab und verliert manchmal Pakete wenn man es benutzt um mal richtig Durchsatz zu machen. Habe mir dann doch ein paar kleine Skripte mit modpoll geschrieben - zumindest für die Performance-Tests :)
Hallo, kann mir jemand sagen wie man diese Library https://github.com/mbs38/yaMBSiavr) bei Atmel Studio 7 einbindet? HG
Hans Günther schrieb: > kann mir jemand sagen wie man diese Library > https://github.com/mbs38/yaMBSiavr) bei Atmel Studio 7 einbindet? Einfach die .h und die .c Datei per Drag&Drop rechts in den Library-Explorer von AS7 ziehen. Im code dann #include "yambsiavr.h" e voila :)
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.