Hallo Freunde der Elektronik.
Ich habe folgendes Problem. Für ein Projekt an dem ich arbeite, muss ich
unter anderem einen uC so implementieren, dass er beim Eingang von
Daten den PWM Pin auf High setzt(welcher für eine NPNTransistor
Schaltung von Nöten ist). Für dieses Vorhaben habe ich den Attiny25
ausgewählt welcher für mich genügend Flash zur Verfügung stellt.
Jetzt will ich hier aber keine TWI Kommunikation(USI), da es das ganze
unnötig verkompliziert, sondern den Attiny mit Hilfe eines Arduinos und
dem Software Serial Befehl programmieren. Leider ist es das erstemal,
dass ich mich mit dem Thema Kommunikation befasse, deshalb hab ich nicht
wirklich einen Plan von dem Vorgang.
Hat jemand eine Idee, wie ich hier vorgehen sollte? Ein Tutorial für das
flashen von Attinys mit dem Arduiono habe ich schon gefunden.
Datenblatt:
http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf
Danke für die Hilfe im Voraus.
Faisal
Es wäre auf jeden Fall hilfreich, wenn du dein Vorhaben noch etwas
genauer beschreibst.
100%'ig sicher was du vor hast bin ich mir nämlich nicht. Ich nehme mal
an du hast einen Standard Arduino Uno (mit Atmega328/168 oder 8) der dem
ATTiny irgendwelche Befehle schicken soll.
Dann kannst du wunderbar den UART vom Arduino zum Senden nutzen.
Allerdings musst du die Daten auch auf deinem ATTiny entgegen nehmen.
Im Moment gibt es nur den ATTiny 167/87 der einen Hardware Lin/UART hat.
Somit müsstes du auf Soft-UART zurück greifen. Da solltest du hier im
Forum genug zu finden AVR304/305 sind immer so ein Stichwort.
Ich nutze dann meist eine einfache Version der AVR305 Application Note,
welche in inline assembler gepackt wurde. Ist mit senden/empfangen etwa
100 Byte groß.
https://github.com/Whistle/avr305
Die eigentlichen Routinen sind in der avr305.h
@Johann
Danke erstmal für die Antwort.
Das Vorhaben sollte wie folgt sein:
Es sollen keine Befehle über dem Arduino geschickt werden, sonder
lediglich programmiert werden. Ja es ist ein Arduino mit dem Atmega 328.
Die Daten werden über eine Software an das Board geschickt(RS232
Protokoll-Standard) dementsprechend habe ich ein Max3221 davor
geschaltet. Jetzt soll der der Attiny die Daten einfach nur lesen bzw.
empfangen und daraufhin einen PWN pin auf High schalten. An diesem PWN
Pin ist einen NPN Transistor geschaltet. Dieser sollte nun seine übliche
Funktion(durch den HIGh Pegel am PWN) ausüben.
Ungefähr jetzt auf einer Höhe? :-)
Danke nochmal
Ahh okay,
jetzt weiß ich bescheid. Der Arduino wird als ISP genutzt.
Den Quelltext kannst du trotzdem nutzen, auch wenn ich dich nicht
richtig verstanden hatte.
Die Funktion readc() liest dir dann auf deinem Wunsch-Pin jeweils ein
Zeichen ein. Welcher Pin genutzt wird setzt du mittels der defines in
avr305.h. Die Baudrate kannst du dort auch setzen.
Ist eigentlich selbsterklärend. Wenn noch Fragen aufkommen ruhig fragen.
Ich helfe gerne.
Mit freundlichen Grüßen
Johann Schiller
@Johann
Danke nochmal für die Antwort. Den Quelltext habe ich mir erst jetzt
angeschaut.
Das wichtige war bei mir, dass ich das USI Interface nicht nutzen
wollte, da ich das Board schon erstellt habe und die Pins des Attinys´
schon für UART ausgelegt hatte... Deswegen fällt das TWI weg.
AVR305 sieht gut aus. Vor allem, dass ich den Pin einstellen kann.
Ich Versuch das gleich am Montag im E-lab aus und sag Bescheid ob es
geklappt hat.
Grüße
Faisal Alam
So ich habe das nochmal getestet. Das ganze sieht jetzt gut aus, jedoch
bräuchte ich weitere Hilfe. Wie liest man beim Softuart einen String
ein? Muss da jeder einzelne Char abgetastet werden?
Grüße
Faisal
> Wie liest man beim Softuart einen String> ein? Muss da jeder einzelne Char abgetastet werden?
Ja, natürlich. Der Soft-UART ist, genau wie ein Hardware-UART bei
anderen Atmels Einzelzeichen-orientiert.
So Leute. Danke bisher für die Hilfe. Muss die ganze jetzt nochmal kurz
aufwirbeln.
Ich habe jetzt das Protokoll meiner Hardware vor mir liegen.
VOn diesem Protokoll ist mir jetzt nur wichtig einen bestimmten string
einzulesen.
Ich hba mir dabei überlegt jeden char abzutasten, und daraufhin erst den
rest des strings zu lesen.
Hier ist der COde dafür:
1
#define F_CPU 8000000UL
2
3
#include<util/delay.h>
4
5
#include"avr305.h"
6
7
#include<string.h>
8
9
10
11
intmain(){
12
13
charc;
14
while(c=readc()){
15
16
17
if(readc()='p')
18
19
{charstringpwm[9],i=0,x;
20
21
22
while(x=readc()!=9){
23
24
stringpwm[i++]=x;
25
26
}
27
28
stringpwm[i]='\0';
29
30
31
if(strcmp(stringpwm,"wrc0001"))
32
33
{PORTB|=(1<<PB1);// PB1 auf high ;
34
35
};
36
37
38
39
40
elseif(strcmp(stringpwm,"wrc0000"))
41
42
{PORTB&=~(1<<PB1);// PB1 auf Low
43
};
44
45
46
else{
47
return;}
48
49
50
51
52
53
}
54
else{
55
return;}
56
57
}}
Die Länge des Strings wurde so gewählt, da das Protokol am Ende eines
Strings immer das Abbruch-Krit. <CR> hat.
Am schnluss muss eigentlich nur der string pwrc0000 bzw pwrc0001 aus dem
Protokoll herausgesucht werden.
KLappt das so.
Danke nochmal
und grüße Faisal
Hallo,
hier mal ein paar Anmerkungen.
Faisal Alam schrieb:> So Leute. Danke bisher für die Hilfe. Muss die ganze jetzt nochmal> kurz> aufwirbeln.>> Ich habe jetzt das Protokoll meiner Hardware vor mir liegen.>> VOn diesem Protokoll ist mir jetzt nur wichtig einen bestimmten string> einzulesen.>> Ich hba mir dabei überlegt jeden char abzutasten, und daraufhin erst den> rest des strings zu lesen.>> Hier ist der COde dafür:>> #define F_CPU 8000000UL>> #include <util/delay.h>>> #include "avr305.h">> #include <string.h>>> int main() {>> char c;> while(c=readc()){>> if(readc()='p')
Das Zeichen wird in der while-Schleife bereits eingelesen, daher reicht
ein Vergleich mit c. Außerdem musst du den Vergleich in C mit "=="
machen.
>> {char stringpwm[9],i=0,x;>> while(x =readc()!=9) {
Warum findet hier ein Vergleich mit 9 statt? Du liest ein Zeichen,
speicherst es in x und vergleichst es gegen 9 (mit Blick in die ASCII
Tabelle wäre dies ein Tabulator. Ich glaube eher, das du nicht mehr als
9 Zeichen lesen möchtest.
>> stringpwm[i++]= x;>> }>> stringpwm[i] = '\0';>> if (strcmp(stringpwm,"wrc0001"))
strcmp gibt eine 0 zurück wenn der Vergleich wahr ist. Daher muss noch
ein ! vor das strcmp
>> {PORTB |= (1 << PB1); // PB1 auf high ;>> };>> else if (strcmp(stringpwm,"wrc0000"))>> {PORTB &= ~(1 << PB1); // PB1 auf Low> };>> else {> return;}>> }> else{> return;}>> }}>> Die Länge des Strings wurde so gewählt, da das Protokol am Ende eines> Strings immer das Abbruch-Krit. <CR> hat.>> Am schnluss muss eigentlich nur der string pwrc0000 bzw pwrc0001 aus dem> Protokoll herausgesucht werden.>> KLappt das so.>> Danke nochmal> und grüße Faisal
Guck mal hier vielleicht:
http://stackoverflow.com/questions/5697047/convert-serial-read-into-a-useable-string-using-arduino
Kannst du ganz leicht adaptieren.
MFG
Johann
Erstmal Danke @Johann für deine Anmerkungen.
Ich hab die so erstmal mit aufgenommen. Eigentlich müsste doch jetzt so
das Programm jedes Zeichen erstmal abklappern nach einem 'p' .
Falls dieser dann vorhanden ist, soll er die 7 Zeichen danach einlesen
und diesen String erstmal vergleichen. Muss dafür der Platz für den
String jetzt 7 sein oder 9(da am Ende jeder Zeile im Protokoll der
carriage Return befehl kommt CR)?
Neben den powermode Befehlen habe ich leider noch einen weiteren Befehl
im Protokoll gefunden, der ein kleines 'p' in sich trägt.
Wie adaptiere ich den Code von der Stackoverflow Seite auf mein Problem?
Wie gesagt ich bearbeite diesen Teil des Projekts mit gefährlichem
Halbwissen:-)
Im Anhang findet ihr jetzt das komplette Protokoll.
Danke für die Hilfe. Super Communitiy hier.
FaisalTU schrieb:> Im Anhang findet ihr jetzt das komplette Protokoll.
Poste lieber noch mal dein jetziges Programm.
Das von da oben war voller Fehler, die du hoffentlich korrigiert hast.
> Falls dieser dann vorhanden ist, soll er die 7 Zeichen danach einlesen
Nein. er soll nicht 7 Zeichen einlesen.
Er soll solange Zeichen einlesen und abspeichern, bis ein CR daherkommt.
Erst danach hast du eine Chance, dass das was du bekommen hast auch
tatsächlich eine Message ist, ob sie komplett ist oder nicht, kommt
drauf an ob man mitten in die Übertragung eingestiegen ist oder ob man
auch das erste Zeichen mitgekriegt hat.
Das ist das was dein Protokoll dir als Vorgabe gibt. Halte dich daran
und du hast weniger Probleme.
> Wie gesagt ich bearbeite diesen Teil des Projekts mit gefährlichem Halbwissen:-)
Das ist das eigentliche Problem. Seine Fähigkeiten im Programmieren kann
man zwar ab einem gewissen Grad auch in einem Projekt voranbringen. Aber
erst mal muss man auf diesen Level kommen. Wer bei 0 anfängt, hat in
einem konkreten Projekt nichts verloren.
Karl Heinz schrieb:> Er soll solange Zeichen einlesen und abspeichern, bis ein CR daherkommt.> Erst danach hast du eine Chance, dass das was du bekommen hast auch> tatsächlich eine Message ist, ob sie komplett ist oder nicht, kommt> drauf an ob man mitten in die Übertragung eingestiegen ist oder ob man> auch das erste Zeichen mitgekriegt hat.
Dann müsste ich mehr Platz für den String anlegen. Muss ich das Abbruch
Kriterium mit in die While Schleife mit einbinden? Wie schaut sowas dann
aus?
Karl Heinz schrieb im Beitrag #4058681:
> avr305.h?> Wieso avr305.h?>> Du inkludierst IMMER#include <avr/io.h>
Ich hab die Header Datei so übernommen da ich schon eine fertige
Makefile habe für den Attiny25. Das Kompiliert soweit auch und habe
damit kein Problem .
Heruntermachen brauchste mich dafür nicht:-). Und ja ich bin sehr
schlecht im Programmieren. Aber das musst du mir nicht sagen, wenn ich
das schon erwähnt habe .
Hallo,
Peter Dannegger (peda) hat eine "Software UART mit FIFO" implementiert,
die wunderbar funktioniert. Auch kann man sie in andere Hochsprachen
übersetzen.
Beitrag "Re: Software UART mit FIFO"
Ich verwende sie, neben Peter Danneggers Bootloader "fastboot 2", auf
einem attiny85 mit 8MHz.
Peter Dannegger "Software UART mit FIFO" habe ich dahingehend erweitert,
dass sie bei 9600Bit/s 8/N/2 mit Timer1 und PCINT für beliebige RXD
Eingänge auf einem attiny85 funktioniert.
Natürlich muss man bei allen anderen Interrupt-Service Routinen auf
kurze Ausführungszeiten achten und ich setze das globale Interrupt Flag
über SEI sofort wieder am Anfang der anderen ISR-Routine.
Atomarer Zugriff auf Variable mit mehr als 8 Bit muss man auch so kein
wie möglich in CLI und SEI verpacken.
Hallo,
noch eine Anmerkung zur Atmel AVR AP305 Umsetzung aus:
https://github.com/Whistle/avr305
Hier blockiert natürlich die Sende- und Empfangsroutine und der gesamte
Prozessablauf wartet bis das Zeichen (1 Startbit, 8 Datenbit, 1
Stoppbit) versendet wurde.
Dafür wird natürlich der Software Uart Programmcode sehr klein gehalten.
FaisalTU schrieb:>> Du inkludierst IMMER#include <avr/io.h>>> Ich hab die Header Datei so übernommen
ja, ich habs zu spät im GIT gesehen.
In diesem Fall gehört dem, der die Vorlage gemacht hat, eine mit dem
nassen Fetzen eine übergebraten.
> Heruntermachen brauchste mich dafür nicht:-). Und ja ich bin sehr> schlecht im Programmieren. Aber das musst du mir nicht sagen, wenn ich> das schon erwähnt habe .
Immer dasselbe. Ich kanns zwar nicht, will aber machen.
Das funktioniert so nicht, hat noch nie funktioniert und wird auch nie
funktionieren.
FaisalTU schrieb:> Karl Heinz schrieb:>> Er soll solange Zeichen einlesen und abspeichern, bis ein CR daherkommt.>> Erst danach hast du eine Chance, dass das was du bekommen hast auch>> tatsächlich eine Message ist, ob sie komplett ist oder nicht, kommt>> drauf an ob man mitten in die Übertragung eingestiegen ist oder ob man>> auch das erste Zeichen mitgekriegt hat.>> Dann müsste ich mehr Platz für den String anlegen.
Musst du nicht notwendigerweise.
Wenn du tatsächlich weisst, dass kein Kommando (zur Zeit) länger als 7
Zeichen sein wird (exklusive CR), dann legst du halt ein Array der Länge
8 an (wegen dem abschliessendem \0, damit daraus ein String wird).
Einen Zähler zu machen, der mitzählt wieviele Zeichen bisher
eingetrudelt sind und wenn der Zähler größer als 7 ist, dann nichts mehr
ins Array speichern, ist ja jetzt nicht wirklich das grosse Problem.
> Muss ich das Abbruch> Kriterium mit in die While Schleife mit einbinden? Wie schaut sowas dann> aus?
Am besten machst du überhaupt keine while Schleife, weil das dein ganzes
Programm blockiert.
Karl Heinz schrieb:> In diesem Fall gehört dem, der die Vorlage gemacht hat, eine mit dem> nassen Fetzen eine übergebraten
Wie meinst du das?
Ist das etwa falsch?
Karl Heinz schrieb:> Immer dasselbe. Ich kanns zwar nicht, will aber machen.> Das funktioniert so nicht, hat noch nie funktioniert und wird auch nie> funktionieren.
Das Problem ist, dass das ein Teil meiner Bachelorarbeit ist, jedoch ein
sehr kleiner, trotzdem wichtiger Teil. Es steht soweit alles, jedoch mag
die Software nicht wirklich.
Karl Heinz schrieb:> Am besten machst du überhaupt keine while Schleife, weil das dein ganzes> Programm blockiert.
Du machst das so (ungetesteter Code)
1
#define BUFFER_SIZE 10 // nicht kleckern. Klotzen!
2
3
charInputBuffer[BUFFER_SIZE];
4
uint8_tBufferCnt;
5
6
intmain()
7
{
8
9
10
...Initialisierung
11
12
BufferCnt=0;
13
14
while(1){
15
16
c=readc();
17
if(c!=0){// ein Zeichen liegt vor
18
19
if(c!='\n'){// war es kein CR? Dann ist die Nachricht noch
20
// nicht zu Ende. Zeichen speichern, wenn noch Platz ist
21
if(BufferCnt<BUFFER_SIZE-1){
22
InputBuffer[BufferCnt]=c;
23
BufferCnt++;
24
}
25
}
26
27
else{// es war ein CR. Theoritisch liegt ein Kommando vor
28
InputBuffer[BufferCnt]='\0';// erst mal einen richtigen String
FaisalTU schrieb:> Das Problem ist, dass das ein Teil meiner Bachelorarbeit ist
Autsch.
Das wenn ich früher gesehen hätte, dann hätt ich mich verabschiedet.
Ich mag es nicht, wenn jemand einen akademischen Grad für etwas kriegt,
von dem er keine Ahnung hat.
FaisalTU,
was Karl Heinz (kbuchegg) sagt, ist *.h Dateiendungen stehen für
Header-Dateien.
In *.h Datei stehen die Prototypen der Proceduren / Funktionen und allg.
globale Definitionen wie Variable, Strukturen etc.
In *.c Datei wird dann der Code nun implementiert.
So dass man aus der einen Datei nun zwei machen würde und die *.c Datei
im Makefile ablegt.
Karl Heinz schrieb:> Du machst das so (ungetesteter Code)
Ihr seid die Besten hier. Danke dir. Ich versuch diesen Code mit
eingefügter Programmlogik für ab und anschalten sowie die richtigen
Kommandos demnächst aus, und sag Bescheid, wenn es geklappt hat.
Karl Heinz schrieb:> Autsch.> Das wenn ich früher gesehen hätte, dann hätt ich mich verabschiedet.> Ich mag es nicht, wenn jemand einen akademischen Grad für etwas kriegt,> von dem er keine Ahnung hat.
Keine Sorge. Das ist nur ein Teil den ich persönlich mit eingefügt habe
um eine bessere Note zu bekommen. Ich bekomme den Abschluss auch ohne
dem :-).
Faisal Alam schrieb:> Karl Heinz schrieb:>> Du machst das so (ungetesteter Code)>> Ihr seid die Besten hier. Danke dir. Ich versuch diesen Code mit> eingefügter Programmlogik für ab und anschalten sowie die richtigen> Kommandos demnächst aus, und sag Bescheid, wenn es geklappt hat.
Den wichtigsten Punkt hast du übersehen!
Schaff dir eine Möglichkeit, wo du dir die Zeichen die reinkommen
ausgeben lassen kannst!
Nichts ist hier schlimmer als das Stochern im Nebel, das man nicht
weiss, ob überhaupt das von der UART ankommt, was man denkt das ankommen
sollte. Da gibt es viele Fehlerquellen!
Karl Heinz schrieb:> Faisal Alam schrieb:>> Karl Heinz schrieb:>>> Du machst das so (ungetesteter Code)>>>> Ihr seid die Besten hier. Danke dir. Ich versuch diesen Code mit>> eingefügter Programmlogik für ab und anschalten sowie die richtigen>> Kommandos demnächst aus, und sag Bescheid, wenn es geklappt hat.>> Den wichtigsten Punkt hast du übersehen!>> Schaff dir eine Möglichkeit, wo du dir die Zeichen die reinkommen> ausgeben lassen kannst!>> Nichts ist hier schlimmer als das Stochern im Nebel, das man nicht> weiss, ob überhaupt das von der UART ankommt, was man denkt das ankommen> sollte. Da gibt es viele Fehlerquellen!
Ja werden ich auf jedenfall machen.
Uwe S. schrieb:> FaisalTU,>> was Karl Heinz (kbuchegg) sagt, ist *.h Dateiendungen stehen für> Header-Dateien.> In *.h Datei stehen die Prototypen der Proceduren / Funktionen und allg.> globale Definitionen wie Variable, Strukturen etc.> In *.c Datei wird dann der Code nun implementiert.>> So dass man aus der einen Datei nun zwei machen würde und die *.c Datei> im Makefile ablegt.
Steht auf Github sogar in der Readme, dass es so wie es ist eigentlich
nicht richtig ist ^^
FaisalTU, der Fehler ist stilistisch nicht funktionell.
Sorry muss das ganze hier noch mal rausholen. Ich bin mit der Arbeit
jetzt fertig. Jedoch wollte ich jetzt eine Version mit einem Hardware
Uart machen. Dafür habe ich einen Attiny2313 genommen. Die Library
findet ihr im Anhang. Reicht es hierbei, die Funktion des
Soft-uart(read()) durch das receive_uart() auszutauschen, um den
gleichen Effekt zu bekommen?
Grüße