Forum: Mikrocontroller und Digitale Elektronik AVR ATTiny84A mit C++ Werte an bestimmte Speicherstelle schreiben


von Heinz M. (subi)


Lesenswert?

Hallo,
hab einen zweiten Thread erstellt, da das Problem doch sehr 
unterschiedlich ist. Gehört jedoch zu diesem Thread:
Beitrag "ATMega8a-PU ADC für PIR Sensor (ADC Einstellungen)"

Dieser Thread hat mir bereits etwas geholfen:
Beitrag "Bestimmte Speicheradresse mit C schreiben/lesen"
(Wollte in dem uralten Thread nicht posten.)

Nun zum Problem.
1
int adc = 1; //adc soll später der tatsächliche adc sein
2
int *adresse = (int*) (0x00);
3
*adresse = adc;
4
int wert = *adresse;

Compiler liefert keinen Fehler, es kommt in "wert" jedoch nicht das an, 
was vorher in adc stand.

Vermutungen:
1. Mit "*adresse = ..." weise ich eine neue Speicheradresse zu? Aber wie 
schreibe ich etwas an diese Stelle. Das ging im oben verlinkten Thread 
nicht hervor. Wenn nichts drin steht kann "wert" auch nur 0 enthalten.
2. 0x00 ist ein Speicherbereich den ich nicht nutzen kann. Wenn ich per 
TWI den nachfolgenden Bereich auslese steht da nur Text von MyAVR/SiSy 
drin.

Danke für die Hilfe.

von Oliver S. (oliverso)


Lesenswert?

Kauf dir ein C Buch. Das wurde dir aber im anderen Thread auch schon 
gesagt.

Und mit C++ hat deine Frage schonmal gar nichts zu tun.

Oliver

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

Musste diese Antwort wirklich sein?

Ich schreibe in C++ und dann gebe ich das nun mal an.
Weder in dem verlinkten Thread, noch in meinen anderen beiden 
Threads(die nichts mit C/C++ zu tun haben) wurde mir gesagt, dass ich 
ein Buch kaufen soll.

Ich habe eine halbe Woche in C online Büchern/Anleitungen und Foren 
geschaut. Trotzdem konnte ich das Problem nicht lösen. Die unfreundlich 
formulierte Aufforderung mir ein C Buch zu kaufen bringt mir gar nichts.


Über ernst gemeinte Hilfe würde ich mich freuen.

von Christian K. (the_kirsch)


Lesenswert?

So würde es sinnvoll aussehen:
1
int adc = 1; //adc soll später der tatsächliche adc sein
2
int* adresse = null;
3
adresse = &adc;
4
int wert = *adresse;


Hat aber nichts mit C++ zu tun, ist schlicht C.
Pointerarithmetik ist in jedem guten C Buch erklärt.

von Carl D. (jcw2)


Lesenswert?

Dir ist schon klar, daß dieser int Wert bei 0x0000 auch unter den Namen 
R0 und R1 bekannt ist. R1 wird der Compiler auf 0 halten wollen, denn 
das ist in der ABI so definiert und R0 wird nach ABI als temporäres 
Register benutzt, hat also kedetmold vorhersagbaren Wert. Also nicht 
"absolute Adresse" geht nicht, sondern eher diese spezielle. Aber auch 
bei anderen RAM-Adressen gibt es einen Compiler, der sich auch zur 
Verwaltung dieses Adressraums berufen fühlt. (mit Recht)
 Die Technik wird man (beim AVR) eher finden, um eine fixe Routine, z.B. 
einen Bootloader, anzuspringen.

von Karl M. (Gast)


Lesenswert?

Heinz M.,

ich denke es ist sinvoll zu beschreiben - warum du das so machen willst.

Evtl. ist es nur ein Array welche Daten erhalten soll ?

von Heinz M. (subi)


Lesenswert?

Danke für die beiden konstruktiven Antworten.

Mit 0x00 passiert nichts (Nein ist mir nicht bekannt, deswegen frage ich 
:-))
Bei anderen Adressen sagt er mir:
"invalid conversion from 'int' to 'int*'

Welche Speicherbereiche könnte ich denn nehmen?
Im Datenblatt vom ATTiny bin ich da nicht so richtig durchgestiegen.

von Heinz M. (subi)


Lesenswert?

Karl M. schrieb:
> Heinz M.,
>
> ich denke es ist sinvoll zu beschreiben - warum du das so machen willst.
>
> Evtl. ist es nur ein Array welche Daten erhalten soll ?

Ich muss die Sensordaten auswerten, damit ich darauf hin die 
Auswertelogik in den µC Programmieren kann. Was dann die eigentliche 
Studienarbeit ist.

Und an die Sensordaten zu kommen ist das Problem. Der µC soll die Daten 
an einer Speicherstelle ablegen und über ein SiSy Skript per Soft TWI 
werden die Speicherbereiche gelesen. Das ist also nur eine 
Behelfslösung.

Das Skript ist nicht von mir und liefert Daten, aber um es als 
Fehlerquelle vorerst auszuschließen wird erst mal nur geschrieben und 
gelesen. Wenn schreiben und lesen geklappt hat, sehe ich das an der LED.

So soll es später laufen:
Sensor -> adc -> Auswertelogik(meine Aufgabe) -> Speicheradresse -> 
TWI(nicht meine Aufgabe)

Das läuft:
Poti -> adc -> LED

Das ist der aktuelle Schritt, den ich versuche:
Poti -> adc -> Speicheradresse -> LED

von Oliver S. (oliverso)


Lesenswert?

Heinz M. schrieb:
> Musste diese Antwort wirklich sein?

Ja. Musste sein.
Damit kannst du die grundlegenden Prinzipien der Sprache nachlesen, und 
musst nicht völlig planlos drauflos raten. Denn das funktioniert nicht.

Deine Fragen hier zusammen mit deiner Aussage im anderen Thread, daß du 
den ADC schon zum laufen gebracht hast, passen nicht zusammen. Also, 
erst C lernen, dann nochmal das AVR-Tutorial anschauen. Dann wird dir 
klar, wie das ADC-Register im Riny auszulesen ist.

Heinz M. schrieb:
> Weder in dem verlinkten Thread, noch in meinen anderen beiden
> Threads(die nichts mit C/C++ zu tun haben) wurde mir gesagt, dass ich
> ein Buch kaufen soll.

Doch. Du hast den freundlichen Hinweis nur nicht verstanden. Ich darf 
mal zitieren:
Karl M. schrieb:
> C müsstest Du noch lernen

Daher gabs den hier nochmal, etwas unmissverständlicher.

Oliver

von Carl D. (jcw2)


Lesenswert?

Heinz M. schrieb:
> Danke für die beiden konstruktiven Antworten.
>
> Mit 0x00 passiert nichts (Nein ist mir nicht bekannt, deswegen frage ich
> :-))
> Bei anderen Adressen sagt er mir:
> "invalid conversion from 'int' to 'int*'
>
> Welche Speicherbereiche könnte ich denn nehmen?
> Im Datenblatt vom ATTiny bin ich da nicht so richtig durchgestiegen.

0x00 ist der einzige Integer-Wert, der (legal) auch Pointer existiert, 
der nullptr (C++11) oder (void *)0 (C).
Alle anderen brauchen einen Cast, d.h. der Programmierer muß explizit 
sagen, was er vor hat:
1
int* adresse = (int*) 0x005D;  // lass Zeiger auf eine 16bit-Zahl
2
                               // an Adresse 0x5D (das ist der SP) zeigen
3
int wert = *adresse;
So greift (prinzipiell) der Compiler auch auf alle IO-Register zu.

Um eine C-Variable von außen zu lesen, ermittelt man deren Adresse 
besser mit C-Sprachmitteln (&), falls die Leseroutine Teil des Programms 
ist.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Carl D. schrieb:
> So greift (prinzipiell) der Compiler auch auf alle IO-Register zu.

nein, kann man so nicht sagen. Das geht nur wenn die IO-Adresse in dem 
Ram eingeblendet sind. Beim AVR ist das aber nicht der Fall und sie 
müssen mit speziellen Funktionen angesprochen werden.

von C++ (Gast)


Angehängte Dateien:

Lesenswert?

Ich schreibe in C++
*************************************

die angefügten Code Schnipsel zeigen, wie REGISTER und GPIORn typisiert 
als Variablen in Code verwendbar sind.

Hoffe das hilft weiter
**********************
evt. sind meine Code-Zeilen zu breit...

von Carl D. (jcw2)


Lesenswert?

Peter II schrieb:
> Carl D. schrieb:
>> So greift (prinzipiell) der Compiler auch auf alle IO-Register zu.
>
> nein, kann man so nicht sagen. Das geht nur wenn die IO-Adresse in dem
> Ram eingeblendet sind. Beim AVR ist das aber nicht der Fall und sie
> müssen mit speziellen Funktionen angesprochen werden.

Aha, da sag das mal dem GCC (+libcavr). Der macht das schon lange 
falsch.

von Peter II (Gast)


Lesenswert?

Carl D. schrieb:
> Aha, da sag das mal dem GCC (+libcavr). Der macht das schon lange
> falsch.

nein sie macht es richtig. sie verwendet die passenden Funktionen dafür.

von Heinz M. (subi)


Lesenswert?

@Carl Drexler: Super, vielen vielen Dank. 0x005D funktioniert. Die LED 
wird jetzt über die Speicherstelle je nach adc geschalten.

läuft:
Poti -> adc -> Speicheradresse -> LED

Auslesen der Speicherstelle über TWI funktioniert natürlich nicht auf 
Anhieb...war klar. Deswegen der Weg über die LED. Da weiß ich jetzt 
schon mal, dass das funktioniert und kann mich jetzt um die andere 
Baustelle kümmern. Damit ich dann mit dem eigentlichen Thema anfangen 
kann.

Leseroutine wird nicht Teil des Programms. Wie gesagt ist die PIR Sensor 
Auswertung meine Aufgabe. Um die Übertragung kümmert sich jemand 
anderes.


@C++: Warum kann man im zweiten Bereich in eine uint8_t bis 16Bit 
zuweisen?
Den Rest muss ich mir später mal ansehen. Flags ist noch so eine "Oh 
mein Gott" Thema. Für die Studienarbeit werde ich das erst mal 
hoffentlich nicht brauchen.
Aber erst mal danke.


@Oliver S.: Wenn du hellsehen kannst, weil du 13:16 Uhr schon wusstest, 
dass mir jemand 15:39 Uhr den Tipp gibt C zu lernen. Warum sagst du mir 
nicht, wie ich das Problem lösen werde?

Deine Hellseherischen Fähigkeiten haben leider nicht dazu gereicht zu 
erkennen, dass der eine Thread mit "ATMega" und der andere mit "ATTiny" 
betittelt ist. Es geht also nicht um den selben µC.

Was du nicht wissen kannst, aber eine Schlussfolgerung daraus: Nicht nur 
anderer µC. Auch anderes Board und andere Anforderungen/Aufgaben.

Auch beim ATTiny habe ich den adc schon am laufen. Da ich aber keinerlei 
Anzeigemöglichkeit habe, was er ausliest, beschränkt sich die aktuelle 
Funktion auf einen Touchsensor, welcher die LED schaltet. Funktioniert 
hervorragend. Um aber einen PIR Sensor zu interpretieren muss ich erst 
mal sehen können was der überhaupt ausliest. Der Tiny soll dank des 
integrierten Verstärkers zum praktischen Einsatz kommen. Deswegen der 
kleine ATTiny.

Beim ATMega ist die Verbindung samt grafischer Anzeige Out of the Box 
bei SiSy dabei. Sein Problem ist, dass ich keinen internen Verstärker 
habe. Jetzt muss ich sehen, wie ich dieses alte Signal wieder 
hinbekomme. Einsatzmöglichkeiten wären für Lehrzwecke. Deswegen der 
günstige ATMega mit vielen Pins.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Peter II schrieb:
> nein, kann man so nicht sagen. Das geht nur wenn die IO-Adresse in dem
> Ram eingeblendet sind. Beim AVR ist das aber nicht der Fall und sie
> müssen mit speziellen Funktionen angesprochen werden.

Das widerspräche allerdings sämtlichen Atmel-Datenblättern, und auch 
praktischer Erfahrung...

Oliver

von spess53 (Gast)


Lesenswert?

Hi

>Sein Problem ist, dass ich keinen internen Verstärker habe.

Welchen ATMega meinst du denn? Eigentlich haben alle aktuellen ATMegas 
einen Verstärker.

MfG Spess

von Heinz M. (subi)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Sein Problem ist, dass ich keinen internen Verstärker habe.
>
> Welchen ATMega meinst du denn? Eigentlich haben alle aktuellen ATMegas
> einen Verstärker.
>
> MfG Spess

ja, die Aktuellen. Nicht aber der(zumindest nicht nach Datenblatt):

Heinz M. schrieb:
> Hallo,
> hab einen zweiten Thread erstellt, da das Problem doch sehr
> unterschiedlich ist. Gehört jedoch zu diesem Thread:
> Beitrag "ATMega8a-PU ADC für PIR Sensor (ADC Einstellungen)"

von C++ (Gast)


Lesenswert?

>Heinz M. (subi)
>****************
>@C++: Warum kann man im zweiten Bereich in eine uint8_t bis 16Bit
>zuweisen?

kann man nicht.
**************

Der Kompiler benutzt das angegebene und das nächstfolgende Register zur 
Speicherung einer Word-Variable.

Zugriff mit variablenName.word = ...

//registers
//************************************************************
  register bits16_t sineTableIncrement          asm ("14"); //reg14
//         ********                                         //reg13
  register bits16_t sineTableIndex              asm ("12"); //reg12
//         ********                                         //reg11
  register bits16_t commutationTicks            asm ("10"); //reg10
//         ********                                         //reg 9
  register bits8_t  amplitude                   asm ( "8"); //reg 8
  register bits8_t  advanceCommutationSteps     asm ( "7"); //reg 7
  register bits8_t  sineTableNextSectorStart    asm ( "6"); //reg 6
  register bits8_t  speedControllerTimer        asm ( "5"); //reg 5

**************************************************************

Register oder GPIORn können auch als uint8_t oder int8_t typisiert 
werden.
**********************************************************************
#define unsignedInt_8Bit (*(uint8_t*) &GPIOR0)

register uint8_t unsignedInt_8Bit asm ("14");

von Carl D. (jcw2)


Lesenswert?

> @Carl Drexler: Super, vielen vielen Dank. 0x005D funktioniert. Die LED
> wird jetzt über die Speicherstelle je nach adc geschalten.

Achtung, das war nur ein Beispiel mit einem Register, das in jedem AVR 
an der Stelle steht. (nicht zu 100% verifiziert)
Aber, das ist nicht als idealen Platz zum Speichern von Daten. Denn es 
ist der Stackpointer, den braucht man für jedes nichttriviale Program.

> Carl D. schrieb:
>> Aha, da sag das mal dem GCC (+libcavr). Der macht das schon lange
>> falsch.
>
> nein sie macht es richtig. sie verwendet die passenden Funktionen
> dafür.

Wenn der GCC Register mit (kurzen) In/Out-Befehlen erreichen kann, dann 
muß er 0x20 abziehen, das ist wohl die "passenden Funktionen". Sonst 
werden die IO-Register einfach memory mapped angesprochen. So steht das 
im DB und so verhält sich das gelieferte Silizium.

von Oliver S. (oliverso)


Lesenswert?

Carl D. schrieb:
> Wenn der GCC Register mit (kurzen) In/Out-Befehlen erreichen kann, dann
> muß er 0x20 abziehen,

Das ist so nicht ganz richtig formuliert. Wenn der GCC IO-Register im 
IO-Bereich mit (kurzen) In/Out-Befehlen erreichen WILL, dann muß er 0x20 
abziehen.

Über LDS/STS lässst sich der ganze Speicherbereich linear adressieren.

Carl D. schrieb:
> Aber, das ist nicht als idealen Platz zum Speichern von Daten. Denn es
> ist der Stackpointer, den braucht man für jedes nichttriviale Program.

Und ich dachte schon, du hättest bei der Empfehlung böse Hintergedanken 
;)

Heinz M. schrieb:
> Und an die Sensordaten zu kommen ist das Problem. Der µC soll die Daten
> an einer Speicherstelle ablegen und über ein SiSy Skript per Soft TWI
> werden die Speicherbereiche gelesen. Das ist also nur eine
> Behelfslösung.

Das mit einer explizit adressierten Speicherstelle ist keine 
Behelfslösung, das ist Murks. Wenn du in einer Programmiersprache wie C 
programmierst, nennt sich das Konzept dafür Variable. Der Compiler legt 
die dann schon intern an eine Speicherstelle, aber welche das genau ist, 
kannst du ruhig ihm überlassen. Dann passieren auch nicht solche 
sinnlosen Aktionen, wie das Überachrieben des Stackpointers auf 0x5d.

Bitte such dir doch endlich mal ein Tutorial oder besser ein gutes Buch, 
und lies dir zumindest die grundlegenden Konzepte der Programmiersprache 
C an.

Denn der Betreuer der Arbeit wird die hirnrissgen Programmierstunts, die 
du im Moment aus völliger Unkenntnis zusammenbastelst, nicht lustig 
finden.

Oliver

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

@Oliver S.: Du hast bisher noch KEINEN einzigen sinnvollen Post von dir 
gegeben. Sowas wie "kauf dir ein Buch" oder "das ist Murks" kann jeder 
sagen.

Die Idee über die direkt adressierte Speicherstelle stammt vom Betreuer! 
Wenn der Compiler die Speicherstelle vergibt weiß ich nicht wo sie liegt 
und kann von extern nicht zugreifen. Dazu kam von dir natürlich kein 
Alternativvorschlag. Wenn du jetzt sagst I²C/TWI: Das ist auf dem Board 
und dem Programmrahmen an den ich mich halten muss nicht so einfach und 
würde die Studienarbeit um ein vielfaches sprengen. Ich soll mich 
explizit darum nicht kümmern.
Und nochmal: Das ausgeben der Werte ist weder Bestandteil des Programms, 
noch taucht es irgendwo im schriftlichen Teil auf.
Das mir das Konzept von Variablen bekannt ist, sollte im Eingangspost 
klar werden.

Wenn du keine Lust hast zu helfen, dann lass es bleiben.
Ich möchte dich darum bitten in diesem Thread nicht weiter zu stören.


Allen anderen: Vielen Dank für die Mühe.

von Oliver S. (oliverso)


Lesenswert?

Heinz M. schrieb:
> Wenn der Compiler die Speicherstelle vergibt weiß ich nicht wo sie liegt
> und kann von extern nicht zugreifen.

Du kannst überhaupt nicht "von extern" auf den Speicher zugreifen. Das 
ginge nur über die Programmierschnittstelle, aber dann läuft auf dem 
Prozessor kein Programm. Wenn auf dem Prozessor ein Programm läuft, dann 
kommst du nur an Daten im SRam, in dem das Programm diese über irgend 
eine verfügbare Schnittstelle ausgibt. Und in dem Fall weiß der 
Compiler, wo die Daten sind. Du brauchst es nicht zu wissen.

Du solltest also nochmal mit deinem Betreuer sprechen, was da wirklich 
gefragt ist.

Und wenn du die Adresse einer Variablen wirklich brauchst, dann wurde 
dir oben schon der Hinweis gegeben, daß C dafür einen Operator hat. So 
etwas steht dann auch wieder im C-Buch...

Dein Problem ist, daß du hier nach Lösungen für das falsche Problem 
fragst. Wenn statt dessen fragen würdest, wie du deine eigentliche 
Aufgabe lösen könntest, und dazu zeigst, was du schon programmiert hast, 
dann gibt es auch sinnvolle Hilfe. Denn alle bisher hier gegebenen 
Antworten gehen entweder völlig an deinem Problem vorbei, oder führen 
dich direkt ins Chaos.

Das liegt nicht unbedingt daran, daß die Antwortenden nicht wissen, was 
sie tun. sondern daran, daß du deine eigentliche Aufgabenstellung nicht 
formuliert hast.

Oliver

von Rolf Magnus (Gast)


Lesenswert?

Heinz M. schrieb:
> @Oliver S.: Du hast bisher noch KEINEN einzigen sinnvollen Post von dir
> gegeben. Sowas wie "kauf dir ein Buch" oder "das ist Murks" kann jeder
> sagen.
>
> Die Idee über die direkt adressierte Speicherstelle stammt vom Betreuer!

Klingt für mich erstmal nach einer dämlichen Idee.

> Wenn der Compiler die Speicherstelle vergibt weiß ich nicht wo sie liegt
> und kann von extern nicht zugreifen.

Was heißt "von extern"? Du bist doch auf einem AVR. Wer außer deinem 
Programm soll denn darauf zugreifen?

> Dazu kam von dir natürlich kein Alternativvorschlag. Wenn du jetzt sagst
> I²C/TWI: Das ist auf dem Board und dem Programmrahmen an den ich mich
> halten muss nicht so einfach und würde die Studienarbeit um ein
> vielfaches sprengen. Ich soll mich explizit darum nicht kümmern.

Und dafür dann um irgendeinen Murks mit festen Adressen? Wenn du das 
machen willst, wirst du dich mit Linkerskripten beschäftigen müssen, 
denn den verfügbaren Speicher reserviert der Compiler sonst erstmal 
komplett für sich. Es gibt also keine Speicherstelle, die du nutzen 
darfst. Du musst deshalb das Linkerskript anpassen, um die 
Speicherstelle explizit für dein Vorhaben zu reservieren.

> Und nochmal: Das ausgeben der Werte ist weder Bestandteil des Programms,
> noch taucht es irgendwo im schriftlichen Teil auf.
> Das mir das Konzept von Variablen bekannt ist, sollte im Eingangspost
> klar werden.
>
> Wenn du keine Lust hast zu helfen, dann lass es bleiben.
> Ich möchte dich darum bitten in diesem Thread nicht weiter zu stören.
>
> Allen anderen: Vielen Dank für die Mühe.

von U. C. (Gast)


Lesenswert?

Ich habe hier etliche AVRs, welche den den ganzen Tag über einen ADC 
auslesen und die Daten über I2C schaufeln.

Niemals brauchte ich dafür eine feste Adresse!

Meine Diagnose lautet also:
Da stimmt was mit der Aufgabe nicht, oder sie wurde falsch verstanden.

von Peter D. (peda)


Lesenswert?

U. C. schrieb:
> Meine Diagnose lautet also:
> Da stimmt was mit der Aufgabe nicht, oder sie wurde falsch verstanden.

Dem kann ich nur zustimmen.
Der RAM gehört ganz allein dem Compiler/Linker!
Der Programmierer hat da nicht ins Handwerk zu pfuschen.
Der Programmierer greift immer nur über den Namen der Variable auf diese 
zu, den dann der Linker auflöst.

von Peter D. (peda)


Lesenswert?

Heinz M. schrieb:
> Die Idee über die direkt adressierte Speicherstelle stammt vom Betreuer!

D.h. also, Dein Betreuer hat vom Programmieren nicht die geringste 
Ahnung.
Da es aber nur eine Idee war, mußt Du sie ja nicht benutzen.
Und solltest Du auch nicht, wenn Du nicht von jedem Programmierer 
ausgelacht werden willst, der Deinen Quelltext zu Gesicht bekommt.

von Carl D. (jcw2)


Lesenswert?

Peter D. schrieb:
> Der RAM gehört ganz allein dem Compiler/Linker!
> Der Programmierer hat da nicht ins Handwerk zu pfuschen.
> Der Programmierer greift immer nur über den Namen der Variable auf diese
> zu, den dann der Linker auflöst.

Wobei man natürlich, wenn man wirklich fixe Speicherbereiche als 
"Mailbox" braucht (seltenst nötig), dies Compiler und Linker mitteilen 
kann.

gcc & ld angenommen:
 Dem Compiler sagt per Attribute in welcher (neu erfundenen) Section 
eine Variable liegen soll,
 dem Linker per Linker-Script (*.ld) wo er diese hin legen soll.

von Stefan F. (Gast)


Lesenswert?

Ich finde die Aufgabenstellung ziemlich bescheuert, vermutlihc wurde sie 
jedoch nur falsch verstanden.

Also wenn ich einen µC hätte, der zum beispiel 10 Messwerte speichert 
und über ein serielles Interface bereit stellt, dann würde ich dazu (wen 
wundert's?) ein Array verwenden.
1
int messwerte[10];
Irgendwo habe ich dann eine Routine, die auf Kommando eines der Zehn 
Messwerte abruft, etwa so:
1
char command=getchar();
2
if (command=='r') // r steht für read
3
{
4
   char index=getchar();
5
   int value=messwerte[index-'0'];
6
   printf("result=%d",value);
7
}
Wenn du jetzt das Kommando "r4" an den µC sendest, wird er Dir den Wert 
von messwerte[4] zurück liefern.

Warum du dich da auf Speicheradressen verbeisst, ist mir völlig unklar. 
Das konn wirklich nicht Sinn der Aufgabe sein. Never ever.

(Im obigen Beispiel gehe ich der Einfachheit halber davon aus, dass die 
serielle Verbindung mit stdin und stdout verbunden ist.)

von Sascha (Gast)


Lesenswert?

Der einzige Grund der mir einfällt ist, dass die Größe des Arrays vorher 
nicht bekannt ist und man daher malloc und realloc braucht.

Sonst muss ich auch sagen: Sehr wirr das ganze.

von Cyblord -. (cyblord)


Lesenswert?

Sascha schrieb:
> Der einzige Grund der mir einfällt ist, dass die Größe des Arrays vorher
> nicht bekannt ist und man daher malloc und realloc braucht.
Dafür braucht man aber immer noch keine fixen Adressen. Dafür nimmt man 
ja gerade malloc, damit das einem eine freie Adresse nennt.

von Jodel (Gast)


Lesenswert?

Heinz M. schrieb:
> @Oliver S.: Du hast bisher noch KEINEN einzigen sinnvollen Post von dir
> gegeben. Sowas wie "kauf dir ein Buch" oder "das ist Murks" kann jeder
> sagen.

http://wortgarage.myblog.de/wortgarage/art/6246521/Die-Fabel-von-der-Katze-und-von-der-Maus

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> Vermutungen:
> 1. Mit "*adresse = ..." weise ich eine neue Speicheradresse zu? Aber wie
> schreibe ich etwas an diese Stelle.

warum?

welche Speicherstelle? im FLASH, SRAM oder EEPROM?

Darüber muss man sich erst mal klar werden

Im SRAM werden die eh angelegt durch Initialisierung der Variablen, auf 
die kann ich ja zugreifen ohne mich um die Adressen zu kümmern und nach 
power off sind die auch wech.

Sollten die etwa im FLASH landen muss ich mich tiefer mit der Materie 
beschäftigen, gleiches gilt für EEPROM.

von Stefan F. (Gast)


Lesenswert?

> Mit "*adresse = ..." weise ich eine neue Speicheradresse zu?


Nein, damit schreibst du einen Wert in eine Speicherzelle, auf die 
adresse zeigt.

int i; // Variable i Speichert eine Integer Zahl

int* adresse=&i;  // Ermittle die Adresse der Variable i

*adresse=123; // Schreibe 123 in die Speicherzelle mit der adresse.
i=123; // bewirkt genau das Gleiche

Arrays können Variable Größe haben. Arrays werden durch einen Zeiger auf 
ihre erste Speicherzelle identifiziert.

int* messwert=malloc(100); // Reserviert Platz für 100 Integer Messwerte
int[0]=123; // Beschreibe den ersten reservierten Speicherplatz
int[99]=456; // Beschreibe den letzten reservierten Speicherplatz

"messwert" ist ein zeiger auf die erste Speicherzelle des Arrays. 
"messwert" ist nicht das gesamte Array. Deswegen kann "messwert" auf ein 
Array beliebiger Größe zeigen.

Mit realloc kann man die Größe von Arrays ändern. Aber Achtung: Manchmal 
ändert sich dadurch auch die Position des Arrays im Speicher. Es wird 
ein neuer größerer Platz belegt und die alten daten dorthin kopiert. 
Realloc ist auf µC riskant, man handelt sich damit leicht Probleme wegen 
fragmentiertem Speicher ein.

von Daniel A. (daniel-a)


Lesenswert?

Stefan U. schrieb:
> Mit realloc kann man die Größe von Arrays ändern.

Nein, mit realloc kann man die Grösse von mit malloc, realloc oder 
calloc allociierten Speicherbereichen ändern, freigeben, oder wie malloc 
benutzen. Der Speicherbereich muss nicht ein Array sein.

von Heinz M. (subi)


Lesenswert?

Nein, das ist alles weit entfernt von der Aufgabenstellung.

Im Post vom 13.03.2016 16:09 steht alles drin.
1. Meine Aufgabe ist es ein Programm zu schreiben, wo ein PIR Sensor 
interpretiert wird. Das Ergebnis wird in eine Variable gelegt.
Das wars, nicht mehr und nicht weniger.

Das ganze wird dann in ein großes System integriert. Damit habe ich 
absolut nichts zu tun. Ich habe ein Rahmenprogramm gegeben und muss mein 
Zeug da rein schreiben.

2. Damit ich überhaupt irgendeine Logik programmieren kann, muss ich 
erst mal wissen was der Sensor überhaupt ausgibt. Normalerweise würde 
man I²C benutzen(So wie ich es beim ATMega mache).

3. Wegen dem Rahmenprogramm und dem Board auf dem der µC sitzt kann ich 
I²C nicht nutzen. Ich möchte nichts falsches sagen, deswegen einfach das 
was der Betreuer gesagt hat: Eine Umprogrammierung der bestehenden Soft 
TWI Lösung übersteigt bei weitem meine Fähigkeiten und auch den 
Zeitumfang der Studienarbeit(und der Meinung bin ich auch). Also einfach 
als Fakt akzeptieren.

4. Das Skript kommuniziert mit dem µC und fragt nach den 
Speicherstellen. Ein Direktzugriff findet natürlich nicht statt.

5. In den Stack Pointer Schreiben ist nicht schön. Hat zumindest 
intern(Mikrocontroller) erst mal funktioniert. Ich hoffe 
extern(Computer) bekomme ich auch noch hin.
Laut Datenblatt sind die General Purpose Register von 0x00 bis 0x0F und 
die Working Register bis 0X1F. Wenn jemand einen besseren Speicherort 
hat: µC Typ steht in der Überschrift.
Ich weiß durch probieren über die LED, dass der ADC momentan ca 400 
ausgibt. Ich werde mal schauen, ob ich einen ähnlichen Wert im 
Speicherbereich der Register finde.
EEPROM wurde mir gesagt.

Ich werde im praktischen Einsatz also keine Daten irgendwohin senden und 
auch nicht an Speicheradressen schreiben. Das ist nur jetzt, damit ich 
arbeiten kann.

von Bernd K. (prof7bit)


Lesenswert?

Heinz M. schrieb:
> Ich werde im praktischen Einsatz also keine Daten irgendwohin senden und
> auch nicht an Speicheradressen schreiben. Das ist nur jetzt, damit ich
> arbeiten kann.

Dann deklariere ein array von ausreichender Größe und schreibe die Daten 
dort hin und lese sie auch wieder von dort. Fertig.

von U. C. (Gast)


Lesenswert?

Heinz M. schrieb:
> Ich werde im praktischen Einsatz also keine Daten irgendwohin senden und
> auch nicht an Speicheradressen schreiben. Das ist nur jetzt, damit ich
> arbeiten kann.

Dann schreibs doch einfach in Variablen/Array...
Dafür wurden sie erfunden.

Heinz M. schrieb:
> 5. In den Stack Pointer Schreiben ist nicht schön.
Nee, ist es nicht, den hauts dir damit kaputt.

Heinz M. schrieb:
> Laut Datenblatt sind die General Purpose Register von 0x00 bis 0x0F und
> die Working Register bis 0X1F.
Die haut dir der Compiler/Programm auch kaputt.
Werden verwendet.

Heinz M. schrieb:
> Wenn jemand einen besseren Speicherort
> hat
Ganz klassisch: In eine Variable/Array.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Heinz M. schrieb:
> 1. Meine Aufgabe ist es ein Programm zu schreiben, wo ein PIR Sensor
> interpretiert wird. Das Ergebnis wird in eine Variable gelegt.
> Das wars, nicht mehr und nicht weniger.

Wenn's das war, ist das ganze Gerede um "eine bestimmte Speicherstelle" 
vollkommener Blödsinn.

Und irgendwelche Register zu befummeln, ohne auch nur die Spur einer 
Ahnung zu haben, wozu die gut sind, ist auch kompletter Blödsinn.

von Robert S. (robert_s68)


Lesenswert?

Heinz M. schrieb:
> 1. Meine Aufgabe ist es ein Programm zu schreiben, wo ein PIR Sensor
> interpretiert wird. Das Ergebnis wird in eine Variable gelegt.
> Das wars, nicht mehr und nicht weniger.
>
> Das ganze wird dann in ein großes System integriert. Damit habe ich
> absolut nichts zu tun. Ich habe ein Rahmenprogramm gegeben und muss mein
> Zeug da rein schreiben.

Heinz M. schrieb:
> 4. Das Skript kommuniziert mit dem µC und fragt nach den
> Speicherstellen. Ein Direktzugriff findet natürlich nicht statt.

Ich würd mal rausfinden, wie dieses "Rahmenprogramm" aussieht bzw. wie 
das Skript mit dem zu schreibenden Programmteil kommunizieren soll, 
anscheinend ist das ja vorgegeben. Das lässt sich dann ja auch recht 
billig vorab testen, indem man einfach vorhersagbare Fake-Werte liefert, 
und schaut, ob diese auch am anderen Ende rauskommen.

von Oliver S. (oliverso)


Lesenswert?

Heinz M. schrieb:
> 4. Das Skript kommuniziert mit dem µC und fragt nach den
> Speicherstellen. Ein Direktzugriff findet natürlich nicht statt.

Wo läuft denn das Skript? Und was läuft noch außer deinem Programmteil 
auf dem Controller?

Nach wie vor verstehst du anscheinend den Begriff Speicherstelle falsch.
Leg Variablen für deine Werte an, und gib dem Skript deren Adresse, wenn 
es danach fragt. Die Adresse ist nichts weiter als ein Pointer auf deine 
Variable.

>  Wenn jemand einen besseren Speicherort
> hat: µC Typ steht in der Überschrift.

Das hat überhaupt nichts mit dem Typ des Mikroxontrollers zu tun. Der 
ganze Speicher wird vom Compiler und dem Laufzeitsystem verwaltet, 
welches du benutzt. Du müsstest also in deren Doku nachschauen, ob und 
wo es freie Bereiche gäbe. Das kannst du dir allerdings sparen, denn die 
gibt's nicht.
Man kann welche anlegen, das Stichwort Linkerscript ist schon gefallen, 
aber wie den Betreuer ganz treffen bemerkte, liegt das wohl außerhalb 
der Aufgaben Stellung dieser Arbeit.

Oliver

von Stefan F. (Gast)


Lesenswert?

>> int* messwert=malloc(100); // Reserviert Platz für 100 Integer Messwerte
>> ...
>> Mit realloc kann man die Größe von Arrays ändern.

> Nein, mit realloc kann man die Grösse von mit malloc, realloc
> oder calloc allociierten Speicherbereichen ändern

Ich meinte "Größe ändern" bezogen auf das Codebeispiel, das direkt 
darüber stand. Da habe ich das Array mit malloc erzeugt.

Aber um Missverständnisse zu vermeiden, war dein Hinweis schon wichtig.

von Heinz M. (subi)


Lesenswert?

Ich habe eine Alternativlösung umgesetzt. Je länger die LED an ist, 
desto höher ist der adc Wert. Wahlweise Bits der Werte auch als 
Morsecode (kurz=0, lang=1).

Das reicht für die Programmierung aus.
Jetzt habe ich mehr Zeit für die eigentliche Studienarbeit, was mir 
momentan wichtiger ist.

Vielen Dank für die Hilfe

von Oliver S. (oliverso)


Lesenswert?

Kannst du uns noch kurz verraten, an welcher Einrichtung du die 
Studienarbeit machst? Nur, um da immer eine großen Bogen drumrum machen 
zu können...

Oliver

von Stefan F. (Gast)


Lesenswert?

Was hat die LED jetzt mit den Speicherzellen tun tun?

By the way: statt "morsen" bietet sich serielle Übertragung an. Da 
kannst du die LED als Betriebs-Kontroll-Leuchte verwenden und zugleich 
seriell Daten senden. Die wiederum kannst du wahlweise elektrisch oder 
optisch auslesen.

Einfach ein handlesübliches USB-UART Kabel dranhängen und schon kannst 
du in lesbarer Form alles anzeigen, was du willst.

Code zum abgucken:
1
#include <util/delay.h> 
2
#include <avr/pgmspace.h>
3
#include <avr/interrupt.h> 
4
#include <avr/io.h>
5
6
#define SERIAL_BITRATE 2400
7
8
#define SOFTSERIAL_TXD_HIGH   { PORTD |= (1<<PD2); }
9
#define SOFTSERIAL_TXD_LOW    { PORTD &= ~(1<<PD2); }
10
11
// Calculate the time per bit minus 5 CPU cycles
12
#define US_PER_BIT 1000000/SERIAL_BITRATE-5/F_CPU
13
14
#if F_CPU/SERIAL_BITRATE<100
15
    #warning SERIAL_BITRATE is to high for this CPU clock frequency
16
#endif
17
18
// Send a single character or byte.
19
void softSerial_sendChar(char c)
20
{
21
    cli();
22
    // Send start bit
23
    SOFTSERIAL_TXD_LOW;
24
    _delay_us(US_PER_BIT);
25
    // Send 8 data bits
26
    for (uint8_t i=0; i<8; i++) 
27
    {
28
        if (c & 1)
29
        {
30
            SOFTSERIAL_TXD_HIGH;
31
        }
32
        else
33
        {
34
            SOFTSERIAL_TXD_LOW;
35
        }
36
        _delay_us(US_PER_BIT);
37
        c=c>>1;
38
    }
39
    SOFTSERIAL_TXD_HIGH;  
40
    sei();
41
    _delay_us(2*US_PER_BIT);
42
}
43
44
// Send a string.
45
void softSerial_sendStr(char* text)
46
{
47
    char c;
48
    while ((c=*text))
49
    {
50
        softSerial_sendChar(c);
51
        text++;
52
    }
53
}
54
55
// Send a string from program memory.
56
void softSerial_sendStr_P(PGM_P text)
57
{
58
    char c;
59
    while ((c=pgm_read_byte(text)))
60
    {
61
        softSerial_sendChar(c);
62
        text++;
63
    }
64
}
65
66
// Send an integer as text.
67
void softSerial_sendInt(int i)
68
{
69
    char buffer[7];
70
    itoa(i,buffr,10);
71
    softSerial_sendStr(buffer);
72
}

von Heinz M. (subi)


Lesenswert?

"Viele Wege führen nach Rom."
Ich brauche eine grobe Anzeige für den ADC Wert. Sonst wird das wie die 
Suche im Heuhaufen.

Soft TWI oder die Speicherstelle zu nutzen wäre eine Möglichkeit 
gewesen. In anbetracht der Zeit jedoch keine Option. Und da ich es auch 
nicht umsetzen soll wäre es vergebene Liebesmühe.
LED war eine gute Alternative.

Ne UART dort ran hängen wäre auch ne Idee. Schneller bin ich, wenn ich 
einfach die Frequenz der LED Ausgabe erhöhe(1 Variable) und ein 
Multimeter mit Elko oder das andere Board mit adc und Elko dran hänge.
Wird aber nicht nötig sein. 4Bit Morsecode sind ausreichend. Die 1Bit 
der LED war zu wenig.

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> "Viele Wege führen nach Rom."
> Ich brauche eine grobe Anzeige für den ADC Wert. Sonst wird das wie die
> Suche im Heuhaufen.
>
> Soft TWI oder die Speicherstelle zu nutzen wäre eine Möglichkeit
> gewesen. In anbetracht der Zeit jedoch keine Option. Und da ich es auch
> nicht umsetzen soll wäre es vergebene Liebesmühe.
> LED war eine gute Alternative.
>
> Ne UART dort ran hängen wäre auch ne Idee. Schneller bin ich, wenn ich
> einfach die Frequenz der LED Ausgabe erhöhe(1 Variable) und ein
> Multimeter mit Elko oder das andere Board mit adc und Elko dran hänge.
> Wird aber nicht nötig sein. 4Bit Morsecode sind ausreichend. Die 1Bit
> der LED war zu wenig.

hättest du das vorher geschrieben wäre es klar gewesen, statt dessen 
schreibst du was über Speicherzellen beschreiben.

Lösung schon vor Ewigkeiten wäre gewesen

Arduino nano328p unter 5,-€
10 LEDs aus einen LED Stripe 60 oder 144 LED/m
Die LIB zur Ansteuerung

ADC = n mal LED in %
ADC lesen WS ansteuern fertig

sogar jede LED in der Wunschfarbe von grün unter 50% z.B bis rot bei 
über 80%

Da man so einen Stripe auch aufhängen kann und er sehr hell strahlen 
kann sieht man das auch von weiter weg.

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

Joachim B. schrieb:
> hättest du das vorher geschrieben wäre es klar gewesen, statt dessen
> schreibst du was über Speicherzellen beschreiben.
>
> Lösung schon vor Ewigkeiten wäre gewesen
>
> Arduino nano328p unter 5,-€
> 10 LEDs aus einen LED Stripe 60 oder 144 LED/m
> Die LIB zur Ansteuerung

Weil ich nicht auf die Idee des Morsecodes kam. PWM an LED lässt sich 
schlecht ablesen, deswegen habe ich die Option über die LED nicht in 
Betracht gezogen.

An den Atiny bekomme ich nicht wirklich mehr LEDs ran. Mit nem anderen 
Controller sind die ADC Paramter wieder anders. Bringt mir auch nichts.

Das Auslesen mit dem Morsecode klappt auch in 10Bit recht gut. Also bei 
voller Genauigkeit.


So, Bewegungsmelder funktioniert schon mal auf 1m Entfernung.

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> Weil ich nicht auf die Idee des Morsecodes kam. PWM an LED lässt sich
> schlecht ablesen,

und wieso PWM ablesen, ein LED Balken vertikal in 10% oder 5% Schritten 
ggfs. pro % in anderen Farben ist was anderes.

Irgenwie wirkt dein Beitrag auf mich wie Getrolle.

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

Schau mal nach, wie viele Ports der ATTiny84A hat. 10% mit LED Balken 
geht gerade so mit Doppelbelegung bei dem geplanten Einsatz. 5% nur mit 
zusätzlicher externer Beschaltung. Also zusätzlichem unnötigem Aufwand, 
der nicht Teil der Studienarbeit ist und später auch keinerlei 
Verwendung findet(Oder hast du schon mal nen Bewegungsmelder mit vielen 
bunten LEDs gesehen?). Der Mikrocontroller und das Board ist gegeben, 
weil es bereits Teil des Systems ist. Da kann ich nicht einfach mit 
anderem Zeug ankommen. Es gilt das Problem zu lösen und nicht neue 
anzuschleppen.

Praktisch komme ich nur an 4 Pins ran, weil der µC schon verlötet ist. 
Davon brauche ich 2 für den PIR Sensor. Bleiben 2 für den LED Balken 
übrig. Macht 50% Schritte. 33% in Binärcode. Mit der Auflösung kann ich 
nichts anfangen.

Mit Morsecode kann ich mir die vollen 10Bit (0,1%) ausgeben lassen mit 
nur einer LED, die schon drauf ist. Ohne Verfälschung und ohne 
Genauigkeitsverlust.
Morsecode findet man auf nahezu jedem PC Mainboard. Besser bekannt als 
Beep Code. Warum nicht am Mikrocontroller?

Hier geht es nicht um schick und bunte Farbenspiele. Es geht um die 
Funktion. Und die Funktion eines Bewegungsmelders ist Bewegung zu 
erkennen. Das ist meine Aufgabe. Die LED Ausgabe ist nur Mittel zum 
Zweck die Aufgabe erfüllen zu können.

von Eric B. (beric)


Lesenswert?

Heinz M. schrieb:
> Im Post vom 13.03.2016 16:09 steht alles drin.
> 1. Meine Aufgabe ist es ein Programm zu schreiben, wo ein PIR Sensor
> interpretiert wird. Das Ergebnis wird in eine Variable gelegt.
> Das wars, nicht mehr und nicht weniger.

Also, im Grunde würde das etwa so aussehen:
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
   unsigned int *adc_storage = (unsigned int *) 0x1234;
6
7
   /* Configure ADC here */ 
8
   ...
9
10
   while (1)
11
   {
12
      *adc_storage  = ADCW;
13
   }
14
}
Das wars, nicht mehr und nicht weniger.

von Bernd K. (prof7bit)


Lesenswert?

Eric B. schrieb:
> Das wars, nicht mehr und nicht weniger.
1
#include <avr/io.h>
2
3
volatile unsigned int adc_storage
4
5
int main(void)
6
{
7
   /* Configure ADC here */
8
   ...
9
10
   while (1)
11
   {
12
      adc_storage  = ADCW;
13
   }
14
}

Ohne Pointer und ohne absolute Adressen (weil schwachsinnig und 
unnötig).

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

Mal ganz nebenbei, dass ich bereits eine Lösung habe.

Wie komme ich an die Adresse ran, wenn der Compiler diese vergibt?
Ich kann mit dem Skript nur Speicheradressen auslesen.

von U. C. (Gast)


Lesenswert?

Heinz M. schrieb:
> Wie komme ich an die Adresse ran, wenn der Compiler diese vergibt?

Mit dem Adressoperator!
&

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> Schau mal nach, wie viele Ports der ATTiny84A hat. 10% mit LED Balken

bei WS Stripes doch nicht, belegen genau 1 Port!

ach manno du trollst!

von Heinz M. (subi)


Lesenswert?

U. C. schrieb:
> Heinz M. schrieb:
>> Wie komme ich an die Adresse ran, wenn der Compiler diese vergibt?
>
> Mit dem Adressoperator!
> &

Hast du den Thread überhaupt gelesen?

Joachim B. schrieb:
> bei WS Stripes doch nicht, belegen genau 1 Port!

Ja hast Recht. Hab an die LED Baranzeigen gedacht mit 1 Pin pro LED.
Trotzdem: Für die Studienarbeit bringt es mir nichts, da ich sowas nicht 
da habe und bisher auch keinen Bedarf. Würde auch nur vom Eigentlichen 
abhalten.

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> Trotzdem: Für die Studienarbeit bringt es mir nichts, da ich sowas nicht
> da habe und bisher auch keinen Bedarf. Würde auch nur vom Eigentlichen
> abhalten.

och für die Dinge schnell zusammen gesteckt hast du bis hier aber ne 
Menge Zeit vertrödelt, hätte schon fertig sein können und der Bedarf 
wurde ja von dir benannt.

: Bearbeitet durch User
von U. C. (Gast)


Lesenswert?

Heinz M. schrieb:
> Hast du den Thread überhaupt gelesen?

Natürlich, du Tropf...

Bis jetzt hast du (mir) noch nicht erklärt, wozu du feste Adressen 
brauchst.
Auf alle Fragen daraufhin kommt immer nur:
"Das Script"
"Die müssen absolut/fixiert sein"
Oder was vergleichbares....

Aber wie man mit einem "Script", auf von außen, unzugängliche Adressen 
zugreift, bleibt im dunklen.

von Heinz M. (subi)


Lesenswert?

@U.C.:
Heinz M. schrieb:
> Ich muss die Sensordaten auswerten, damit ich darauf hin die
> Auswertelogik in den µC Programmieren kann. Was dann die eigentliche
> Studienarbeit ist.
>
> Und an die Sensordaten zu kommen ist das Problem. Der µC soll die Daten
> an einer Speicherstelle ablegen und über ein SiSy Skript per Soft TWI
> werden die Speicherbereiche gelesen. Das ist also nur eine
> Behelfslösung.
>
> Das Skript ist nicht von mir und liefert Daten, aber um es als
> Fehlerquelle vorerst auszuschließen wird erst mal nur geschrieben und
> gelesen. Wenn schreiben und lesen geklappt hat, sehe ich das an der LED.
Wenn ich danach frage, wie man Werte an eine Speicherstelle schreibt, 
welche Speicherstelle sinnvoll ist und schreibe, dass das Skript 
funktioniert bevor ich irgendwas programmiert habe, dann fragt das 
Skript logischerweise nach einer Speicherstelle der Form 0x00, die es 
dann ausliest.

Außerdem schrieb ich schon mehrfach, dass ich es nicht mehr brauche. 
Normalerweise würde ich es nie so machen und für das Projekt habe ich 
eine Alternative.

@Joachim B.:
Entschuldige, aber was weißt du, was ich den ganzen Tag mache?
Um das Ausleseprobleme kümmere ich mich doch schon lange nicht mehr. Ich 
optimiere den Auswertecode und schraube Tag für Tag die Reichweite hoch.

Heinz M. schrieb:
> So, Bewegungsmelder funktioniert schon mal auf 1m Entfernung.

von spess53 (Gast)


Lesenswert?

Hi

>...und schraube Tag für Tag die Reichweite hoch.

Ohne einiges an Analoggedödel zwischen Sensor und ADC wirst du da nicht 
weit kommen.

MfG Spess

von Bernd K. (prof7bit)


Lesenswert?

Heinz M. schrieb:
> dass das Skript
> funktioniert bevor ich irgendwas programmiert habe, dann fragt das
> Skript logischerweise nach einer Speicherstelle der Form 0x00, die es
> dann ausliest.

Was soll das für ein Script sein, auf einem Microcontroller laufen 
normalerweise keine Scripte, da laufen kleine meist in C geschriebene 
Progrämmchen die ganz normal mit ihren Variablen umgehen können, oder 
auch wenns sein muss mit Zeigern auf solche Variablen die man mit dem 
&-Operator erhält.

Also wenn Dein Programm etwas in die Variable xyz schreibt (egal wo die 
liegt) dann kann ein anderer Teil Deines Programms das später auch von 
dort wieder lesen und dem Script mitteilen wenn es bei Deinem Programm 
anklopft und danach fragt. An welcher Stelle im Speicher die Variable 
liegt muss keinen kümmern (und schon gar nicht das Script), das regeln 
Compiler und Linker ganz von selbst.

von Bernd K. (prof7bit)


Lesenswert?

Heinz M. schrieb:
> ann fragt das
> Skript logischerweise nach einer Speicherstelle der Form 0x00, die es
> dann ausliest.

Scripte lesen keine absoluten Speicherstellen in irgendwelchen 
Microcontrollern direkt aus. Sowas haarsträubendes könnte man vielleicht 
mit viel böser Energie und unter Einbeziehung eines Debuggers der den 
Controller anhält und sich dann mit roher Gewalt Zugang zum RAM 
verschafft irgendwie zusammenhacken aber warum sollte man das für ein 
produktives System so haarsträubend kompliziert implementieren?

Was soll das für ein Script sein?

Ich vermute Du hast da was komplett falsch verstanden und jetzt hast Du 
leider irgendwelche kruden Vorstellungen im Kopf die nicht ferner von 
der Realität sein könnten. Lass Dir gesagt sein, was immer da abläuft, 
es wird keine festen Adressen verlangen, wahrscheinlich wird es sogar 
überhaupt nichts mit Speicheradressen zu tun haben, eher vielleicht mit 
Indizes, also es wird nach dem n-ten Byte fragen, alles was Du tun musst 
ist in Deine Array-Variable greifen und das n-te Element da rausholen 
und abliefern wenn das Script (oder was auch immer) über irgendeine 
Schnittstelle (i2c, spi, uart, whatever) von außen anklopft und nach dem 
n-ten Element fragt.

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Nur damit das ganz klar gesagt wurde: Einfach so einen wert an 
irgendeine Speicherstelle zu schreiben ohne das dem Linker zu sagen ist 
ein Bug, der zufällig überall und fast nicht zurückverfolgbar zuschlagen 
kann und der wirklich alles bewirken kann.

Hier mal ein Beispiel:

https://ideone.com/SKR5S8

: Bearbeitet durch User
von Heinz M. (subi)


Lesenswert?

Es wurde bereits alles gesagt. Auch, dass das Skript nicht direkt den 
RAM ausliest, sondern per TWI den µC nach der Speicherstelle fragt.

Das Skript dient nur für Programmier/Debugzwecke.

Werte wollte ich nur für die Entwicklung in den EEPROM schreiben. Nicht 
für den produktiven Einsatz.

Es wird keine neuen Erkenntnisse zu dem Problem geben, weil ich nicht 
mehr nachforsche in der Richtung.

Steht alles schon mal hier im Thread. Lesen vor dem Posten würde viel 
Arbeit ersparen.


@spess53: Die 1m erfasse ich mit noch nicht optimiertem Code. Der ADC 
arbeitet dabei lediglich gegen die internen 1,1V.

Wenn der Code optimiert ist schalte ich den Turbo ein. Dann wird im 
Differenzmodus (Uref+=1,1V, Uref-=0,8V) und mit 20 facher interner 
Verstärkung des µC gemessen. 20m würde völlig ausreichen.

Größeres Problem ist das Rauschen. Bei beiden ist bei abgedecktem Sensor 
ein deutliches Rauschen erkennbar.
Glättungskondensatoren in der ADC-Referenzspannung haben beim Atmega(der 
andere Thread) schon mal sehr geholfen. Beim ATTiny wegen interner 
Referenzspannung schwieriger. Und die Sensoren haben auch so schon ein 
Grundrauschen.
Weitere Rauschunterdrückung erfolgt durch Mittelwertbildung, aber 
letzten Endes wird das der limitierende Faktor.

Ich hätte am Anfang auch nicht gedacht, dass es ausreicht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Heinz M. schrieb:
> Wie komme ich an die Adresse ran, wenn der Compiler diese vergibt?

Das magische Stichwort: "Map file".

von Bernd K. (prof7bit)


Lesenswert?

Rufus Τ. F. schrieb:
> Heinz M. schrieb:
>> Wie komme ich an die Adresse ran, wenn der Compiler diese vergibt?
>
> Das magische Stichwort: "Map file".

Er braucht die Adresse doch gar nicht! Von aussen wird per I²C was 
ausgelesen, also soll sein Programm einfach die Werte in den Puffer 
schreiben den sein I²C-Treiber verwendet. I²C hat doch nichts mit 
Speichereadresen am Hut. Da gehts um Offsets in irgendeinem array das er 
hinlegen kann wo er lustig ist.

von Bernd K. (prof7bit)


Lesenswert?

Heinz M. schrieb:
> Es wurde bereits alles gesagt. Auch, dass das Skript nicht direkt den
> RAM ausliest, sondern per TWI den µC nach der Speicherstelle fragt.

Na also.

Also brauchst Du überhaupt keine festen oder irgendwie bekannten 
Adressen, denn er wird direkt per TWI (auch I²C genannt) nach dem Wert 
an Stelle 42 fragen. Er fragt NICHT nach einer Speicheradresse er 
fragt nach dem soundsovielten Wert des TWI-Puffers, das ist ein Array 
mit einem Index, keine absolute Speicheradresse! Den Wert an diesem 
Index gibt Dein Programm dann raus. An welcher physikalischen Adresse im 
RAM der in Wirklichkeit liegt ist allen beteiligten herzlich egal.

Der TWI-Treiber (der Teil Deines Programms ist!) verwaltet irgendwo ein 
Array der Länge n, das kann von außen per TWI byteweise ausgelesen unter 
Angabe des INDEX (das ist keine Adresse, das ist nur eine Nummer, 0 
ist der erste Wert, n-1 ist der letzte). Du schreibst Deine Messdaten 
also in dieses vom TWI-Treiber veraltete Array und dann kann das Array 
von aussen ausgelesen werden. Wo genau das im RAM liegt spielt 
logischenweise keine Rolle denn nur zwei Komponenten greifen drauf zu: 
Der Teil deines Programms der die Daten da reinschreibt und der Teil 
Deines Programmes der den TWI implementiert um sie da wieder auszulesen. 
Beide kennen das besagte Array beim Namen und können auf normale Weise 
drauf zugreifen weil beide sind Teil ein und des selben Programms.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>Größeres Problem ist das Rauschen.

Und wie unterdrückst du z.B. die 100 Hz von Leuchtstoffröhren und 
ähnliche Störungen.

Andere haben so etwas schon gemacht->Anhang

MfG Spess

von Heinz M. (subi)


Lesenswert?

Ist mir bekannt, dass ich nicht der Erste bin. Deswegen habe ich nach 
fertigen Schaltungen gesucht. Bezogen auf das zweite Dokument hängt bei 
mir C1 parallel zu RB. R1 ist nur ein kleiner Schutzwiderstand. R2 und 
C2 existieren bei mir nicht, bzw werden mittels Spannungsteiler als 
Referenzspannung verwendet für ein höher aufgelöstes Signal.

Ich bekomme genau das unter AX+ dargestellte Signal heraus.

von Stefan F. (Gast)


Lesenswert?

> Werte wollte ich nur für die Entwicklung in den EEPROM schreiben.

Moment mal, bin ich tatterig, oder lese ich diesen Hinweis gerade zum 
ersten mal?

Ich dachte, es geht um RAM!!!!!! Das dachten wir wohl alle.

Beim EEPROM ist die Situation eine völlig andere. Denn das EEPROM wird 
vom Compiler zunächst gar nicht verwendet. Da kannst du in der Tat alles 
an beliebige Stellen rein schreiben. Und da kann das Vergeben fester 
Adressen durchaus sinnvoll sein.

Doku: http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
Du findest dort Funktionen, um Daten an bestimmte Adressen zu schreiben 
und wieder zu lesen.

Bedenke allerdings, dass die Speicherzellen des EEPROM nicht beliebig 
oft umgeschrieben werden können. Für produktiven Einsatz müsstest du Dir 
eventuell Gedanken über Wear-Levelling machen. Aber eins nach dem 
Anderen, das kommt später.

von otto 2 (Gast)


Lesenswert?

Man hat der Heinz M. ein an der Waffel...

Der geht ein auf den Geist.

von Heinz M. (subi)


Lesenswert?

@Steffan Us:
EEPROM schrieb ich am Montag schon ein mal. Letzten Endes ist es für die 
Erfüllung der Aufgabe egal welcher Speicher, solange das Skript es 
auslesen kann. Interessant ist es und ich werde weiterhin die Vorschläge 
lesen. Umsetzung jedoch äußerst unwahrscheinlich.

Nein, EEPROM wird nicht für Produktiveinsatz beschrieben.
Ich hoffe ja der Controller hier hält durch, da ich den nicht gerade 
selten flashe.


Btw.: Bin bei 4m Erfassungsbereich, wenn ich quer zum Sensor gehe.
ca 1,5m auf Sensor zu.


@otto 2: Dich zwingt keiner hier zu lesen.

von Stefan F. (Gast)


Lesenswert?

> EEPROM schrieb ich am Montag schon ein mal.

Wow, das stimmt. Hat keiner gelesen. Beeindruckend.

von Joachim B. (jar)


Lesenswert?

Heinz M. schrieb:
> @Joachim B.:
> Entschuldige, aber was weißt du, was ich den ganzen Tag mache?

ja ich entschuldige, ich weiss das du hier ne Menge Nebelkerzen wirfst 
und man zu deinem Problem bis du es dann mal richtig benennst immer 
wieder Fortsetzungen lesen muss, kommt mir vor wie die Bauserien in 
Heftchen die mit 1,-€ anfangen und man am Schluß wer solange durchhält 
ist man über 1000,-€ los für ein Plastik oder Holzboot.

: Bearbeitet durch User
Beitrag #6667248 wurde von einem Moderator gelöscht.
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
Noch kein Account? Hier anmelden.