Show Posts
|
|
Pages: 1 [2] 3 4 ... 14
|
|
16
|
International / Deutsch / Re: PWM Ausgabe
|
on: February 18, 2013, 10:25:13 am
|
Hi, ich hab zwei Programme, jedoch ist mir nicht klar warum das eine Funktioniert und das andere nicht. [...] !! Der Unterschied besteht nur im setup{},loo{} bzw main{} !! [...] Vielleicht hat ja von euch einer ne idee...
Ich hätte mal 'ne Idee: Im ersten Programm kümmerst du dich ja anscheinend um alles selbst: eigenes main(), nicht das von der Arduino-IDE bereitgestellte main() verwendet und kein Aufruf von setup() oder loop(). Ist nicht schlimm, wenn man weiß, was man macht. Im zweiten Fall scheinst du aber das main() der Arduino-IDE aufzurufen (Datei main.cpp - reinschauen schadet nicht  ). Da wird (für dich verborgen) eine Funktion init() aufgerufen (zu finden in der Datei "wiring.c" - reinschauen macht klug). Und in dieser Funktion werden schon vorab einige Bits in den Registern des Timers 1 (TCCR1A, TCCR1B) gesetzt. Und du 'ODER'st jetzt im 2. Programm deine eigenen Bits noch zusätzlich rein. Die bisherigen bleiben aber gesetzt. In deinem ersten Programm sind die Register ja alle noch 'jungfräulich' auf 0 gesetzt, im 2. Beispiel aber nicht mehr. Setze doch mal versuchsweise im 2. Programm am Anfang von setup() die beiden Register TCCR1A, TCCR1B auf 0. setup() wird ja nach init() aufgerufen und beschreibt die Register neu. Vielleicht funktioniert dann auch das 2. Programm? Als Konsequenz kann es dann natürlich sein, dass bestimmte Funktionen aus der Arduino-Core-Library nicht mehr funktionieren. Viel Erfolg beim Test und teile mal mit, ob es daran gelegen hat. Gruß Wolfgang
|
|
|
|
|
17
|
International / Deutsch / Re: analogRead
|
on: February 11, 2013, 06:27:59 am
|
Wo ist eigendlich der Unterschied zwischen const und #define?
Mit const uint8_t A0 = 14; // Beipiel aus pins_arduino.h
wird eine (konstante) Variable angelegt, die den Wert 14 hat. Klasse Ausdruck, oder? "Konstante Variable". D.h. sie kann nach der Initialisierung mit dem Wert 14 nicht mehr verändert werden, aber wie jede andere Variable gelesen werden. Mit #define A0 14 wird vom Präprozessor des C-Compilers ein Text-Ersatz durchgeführt (also im Programmcode überall A0 durch 14 ersetzt) und dann der Programmcode mit den durchgeführten Textersetzungen an die nächste Stufe des Compilers weitergegeben.
|
|
|
|
|
18
|
International / Deutsch / Re: analogRead
|
on: February 11, 2013, 06:13:45 am
|
analogRead(A0) oder analogRead(0)? Oder ist es egal?
Wie hat damals Wolfgang Petry in einem seiner Lieder gegrölt? Schei*egal! OK, ich weiß nicht, ob du den Typen mit den bunten Freundschaftsbändchen noch kennst, aber die Erklärung ist wie folgt: AO ist in "pins_arduino.h" als Konstante mit dem Wert 14 definiert. Und im Code von analogRead() in der Datei "wiring_analog.c" wird ziemlich am Anfang kontrolliert, ob die Pin-Nummer gleich oder größer als 14 ist und dann wird 14 abzogen. Was wiederum in deinem Beispiel auch 0 ergibt. Dadurch ist die Angabe entweder als Arduino-Pinnummer oder als Nummer des Kanals möglich.
|
|
|
|
|
19
|
International / Deutsch / Re: Frage: Direkte Port Manipulation
|
on: January 23, 2013, 05:12:59 am
|
Danke für die tolle Hilfe. Leider ist mein Mega 2560 definitiv zu langsam!
Jetzt zum Hintergrund:
Ich habe als Input ein Taktsignal, das ca. 1,5 MHz schnell ist. Jetzt wollte ich schauen ob mein Arduino Board schnell genug ist dieses Signal zu verarbeiten. Sprich Taktsignal lesen und auf einen anderen Pin schreiben. Den Pin dann mit einem Oszilloskop betrachten und schauen, ob ich da auch 1,5 MHz erhalten.
Für mich erschließt sich noch nicht der Sinn der ganzen Aktion mit dem Lesen und Schreiben der Port-Bits. Geht es nur um das Prinzip, ob man ein 1,5 MHz-Eingangssignal mit einem mit 16 MHz betriebenen 8-Bit Mikrocontroller softwaremäßig verarbeiten kann oder steckt da noch etwas "sinnvolles" dahinter, was du uns noch nicht verraten hast (wobei natürlich auch der Lerneffekt und das Wissen sinnvoll sein kann)  Ich denke, auch wenn du einen schnelleren Controller verwendest und das Lesen und Schreiben der Port-Bits damit halbwegs funktionieren sollte, wirst du spätestens bei einer etwas umfangreicheren Verarbeitung des Eingangssignals an die Grenzen eines Mikrocontollers stoßen. Das sollte dann meiner Meinung nach der Zeitpunkt sein, über das Konzept generell nachzudenken. Ich sehe gerade, nachdem ich diesen Beitrag gepostet hatte, dass sich MaFu im Beitrag vorher die gleiche Frage gestellt hat  Wolfgang
|
|
|
|
|
20
|
International / Deutsch / Re: Frage: Direkte Port Manipulation
|
on: January 21, 2013, 12:45:43 pm
|
Ich habe ein Arduino Mega 2560 und würde gerne Pin 52 = PC1 (INPUT) lesen und den digitalen Zustand dieses Pins auf Pin 36 = PC1 (OUTPUT) schreiben.
Mit welchen Befehlen geht das lesen des Pins 52 und das schreiben des Zustands auf Pin 36? Kann mir da jemand helfen, wie der Programmcode aussieht? Vielen Dank!
Hallo DANINO24, zuerst muss man mal wissen, dass Pin 52 des Arduino-Boards das Bit 1 (also das 2. Bit) auf Port B des Controllers ist und Pin 36 das Bit 1 auf Port C des Controllers. Dieses Wissen bekommt man durch Ansehen des Schaltplans hier http://arduino.cc/en/uploads/Main/arduino-mega2560_R3-schematic.pdf oder einfacher durch Benutzung dieser Tabelle hier: http://arduino.cc/en/Hacking/PinMapping2560 (rechte Spalte in der Tabelle). Kleine Anmerkung: Pin 52 ist PCINT1/PB1 und nicht PC1. Alsdann ist alles weitere ganz perfekt hier in einzelnen Schritten beschrieben: http://hekilledmywire.wordpress.com/2011/02/23/direct-port-manipulation-using-the-digital-ports-tutorial-part-3/(ganze Ports oder einzelne Port-Bits als Ausgang oder Eingang konfigurieren; bei Eingängen ggfs. die Pull-Up-Widerstände einschalten; Ports komplett setzen, Port komplett einlesen; Einzelbits setzen und lesen). Wenn du danach glaubhaft machst, dass du dann noch Fragen hast (und welche) wird dir hier sicher weitergeholfen (versprochen!)  Diese Anmerkung nur deshalb, weil es meiner Meinung nach keinen Sinn macht, dir 5 oder 10 C-Anweisungen hinzuschreiben, wo dann die Erklärung, was da passiert, einen wesentlich größeren Umfang hat und es anderswo sowieso schon steht. Viel Erfolg! Gruß Wolfgang
|
|
|
|
|
21
|
International / Deutsch / Re: Inline Assembler
|
on: January 17, 2013, 04:13:46 pm
|
Was die Frage nach einem Programmer angeht: nimm einen AVRISP mk II. Der funktioniert garantiert mit dem Studio. Wenn Du erfahrerner bist kannst Du auch andere nehmen, mir wäre das aber die geringe Ersparnis den Ärger nicht wert (ich habe 2 MK II Programmer und ein No Name Teil hier).
Ich kann hier Udo nur zustimmen. Ich selbst verwende den AVRISP mk II mit dem Atmel Studio 6.0 (allerdings nur für die C/C++-Entwicklung). Ist sehr gut in das Atmel-Studio integriert. Direktes Flashen des Controllers und Starten des übersetzten Programms mit einem Maus-Klick (Menüpunkt Debug->Start without Debugging). Auslesen und Setzen der Fuses, Auslesen des Flash aus dem Controller, Löschen des Speichers, usw. Und wenn du Assembler lernen willst (und zum Debuggen), brauchst du teilweise eigentlich noch nicht einmal einen Controller und einen Programmer, denn du kannst das Programm stattdessen im Simulator des Atmel Studio laufen lassen. Schritt für Schritt oder bis zu einem Breakpoint, du kannst die Prozessor- und I/O-Register anzeigen lassen und setzen, Speicherbereiche anzeigen lassen, usw.
|
|
|
|
|
23
|
International / Deutsch / Re: Frage zur bedingten Compilierung (#ifdef) ...
|
on: January 07, 2013, 05:54:01 am
|
paulinchen, kannst du noch folgendes ausprobieren: #if I2C_LCD_4_20 == true #pragma message ("Wir durchlaufen den Zweig für I2C_LCD_4_20 gleich true") // oder brutaler: #error Wir wollen den Zweig für I2C_LCD_4_20 gleich true durchlaufen #include <Wire.h> #include <LiquidCrystal_I2C.h> #else #pragma message ("Wir durchlaufen den Zweig für I2C_LCD_4_20 gleich false") // oder brutaler: #error Wir wollen den Zweig für I2C_LCD_4_20 gleich false durchlaufen #endif Die Meldungen erscheinen im Compiler-Output. Wie man den in der Arduino-IDE anzeigt, weiss ich nicht genau, da ich schon seit einiger Zeit nur noch das Atmel Studio 6.0 als Entwicklungsumgebung verwende. Damit sollten wir erkennen können, welcher Zweig ausgeführt wird und ob die #if-Direktive richtig ausgeführt wird. Vielleicht kann man zumindest hier einen Hinweis bekommen, ob wire.h eingefügt wird oder nicht. Weiterhin kannst du ja zur Fehlersuche temporär am Anfang der Datei wire.h (liegt im Arduino-Libraries-Verzeichnis) oder in anderen Header-Files etwas einfügen wie #pragma message ("Wir sind jetzt in wire.h - wollen wir das?????") um zu sehen, wo es lang geht. Eventuell auch mal nachsehen, ob es auf deinem System mehrere Versionen von wire.h gibt und dort jeweils einen unterschiedlichen Text bei #pragma message verwenden, um zu sehen welche Version eingefügt wird.
|
|
|
|
|
24
|
International / Deutsch / Re: Frage zur bedingten Compilierung (#ifdef) ...
|
on: January 06, 2013, 12:44:45 pm
|
Wenn man #define I2C_LCD_vorhanden schreibt, ist es definiert (wie define schon sagt). Welchen Wert es ggfs. noch bekommt (true, false, 4711, "Ich bin ein String") spielt da keine Rolle. Aber nimmt doch statt #ifdef mal den Bruder #if. Syntax siehe hier http://www2.informatik.uni-halle.de/lehre/c/c_if.html oder auch hier http://msdn.microsoft.com/en-us/library/ew2hz0yd%28v=vs.80%29.aspxDas folgende müsste dann funktionieren: #define I2C_LCD_Vorhanden false // oder alternativ #define I2C_LCD_Vorhanden true
#if I2C_LCD_vorhanden == true // #if I2C_LCD_Vorhanden reicht auch bei boolschen Werten #include <Wire.h> #include <LiquidCrystal_I2C.h> #else // false // wenn nicht true, wird nichts eingefügt; #else-Zweig kann dann natürlich weggelassen werden #endif
Ich kanns im Augenblick nicht ausprobieren, aber so sollte es gehen. Wolfgang
|
|
|
|
|
26
|
International / Deutsch / Re: Segmentanzeige
|
on: January 02, 2013, 05:09:39 am
|
Vielen Dank für die Hilfe, aber ich benötige 10 Ausgänge :-/ oder hab ich da was überlesen.
Nein, du hast nichts überlesen. MueThos hat dir nur verschwiegen, dass du mehrere von den Dingern hintereinander hängen kannst und so die Anzahl der Ausgänge nahezu beliebig erweitern kannst (Einzelheiten siehe Tante Google ( http://lmgtfy.com/?q=+74hc595 +kaskadierung) oder wahrscheinlich auch hier im Board).  [Edit]MueThoS hat dir doch nichts verschwiegen, er hat dich nur nicht ausdrücklich darauf hingewieden, bis zum Ende zu lesen (was aber elektron_ netterweise nachgeholt hat)  Viel Erfolg Wolfgang
|
|
|
|
|
27
|
International / Deutsch / Re: PulseIn im Fahrtenregler
|
on: December 20, 2012, 11:35:14 am
|
Wer kann helfen, was macht PulseIn?
Hallo ArduStemmi, pulseIn() wartet in einer Schleife ganz brutal, bis sich der Zustand des Pins auf LOW/HIGH ändert und dann wieder bis sich der Zustand des Pins zum anderen Pegel HIGH/LOW ändert. So richtig fies in einer Dauerschleife. Na ja, eigentlich sind es sogar fast 3 fiese Schleifen. Siehe Code: /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds * to 3 minutes in length, but must be called at least a few dozen microseconds * before the start of the pulse. */ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) { // cache the port and bit of the pin in order to speed up the // pulse width measuring loop and achieve finer resolution. calling // digitalRead() instead yields much coarser resolution. uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); uint8_t stateMask = (state ? bit : 0); unsigned long width = 0; // keep initialization out of time critical area // convert the timeout from microseconds to a number of times through // the initial loop; it takes 16 clock cycles per iteration. unsigned long numloops = 0; unsigned long maxloops = microsecondsToClockCycles(timeout) / 16; // wait for any previous pulse to end while ((*portInputRegister(port) & bit) == stateMask) if (numloops++ == maxloops) return 0; // wait for the pulse to start while ((*portInputRegister(port) & bit) != stateMask) if (numloops++ == maxloops) return 0; // wait for the pulse to stop while ((*portInputRegister(port) & bit) == stateMask) { if (numloops++ == maxloops) return 0; width++; }
// convert the reading to microseconds. The loop has been determined // to be 20 clock cycles long and have about 16 clocks between the edge // and the start of the loop. There will be some error introduced by // the interrupt handlers. return clockCyclesToMicroseconds(width * 21 + 16); }
Dazwischen passiert dann sonst nichts mehr, wenn der restliche Code nicht mit Interrupts arbeitet (vollständig und zuverlässig!). Kann deine PWM-Signal-Erzeugung es vertragen, dass da unter Umständen für etliche Millisekunden nichts passiert. Bist du mit deiner Interrupt-Programmierung ganz konsequent? Du weißt ja schon, dass der Controller ein PWM-Signal rein hardwaremäßig erzeugen kann, wenn man den Counter/Timer zuvor mit den passenden Werten gefüttert hat? Dann kann ein noch so stures Programm ihn nicht dabei stören (mal von Extremfällen abgesehen)! Ich sehe sonst nichts, wie pulseIn() deine Interrupts stören könnte. Gruß Wolfgang
|
|
|
|
|
28
|
International / Deutsch / Re: Arduino IDE für eigene Boards
|
on: November 17, 2012, 09:55:07 am
|
Hmmm.... OK, der Bootloader ist weg, aber die Fuses haben doch noch immer die Einstiegsadresse vom Bootloader. Und die liegt doch im oberen Speicherbereich. Wie startet dann der AVR nach einem Reset wieder mit dem Anwenderprogramm?? Ob Bootloader oder Start von 0x0000h wird doch durch das BOOTRST Fusebit gesteuert. Und wenn das nicht geändert wird, dann will doch der AVR wieder an der Startadrese des Bootloaders starten und da ist dann keiner mehr.
In der Praxis dürfte es aber trotz eigentlich falsch gesetzten BOOTRST Fuse oft funktionieren: Wenn die BOOTRST Fuse programmiert ist, springt der Controller bei einem Reset an den Anfang des Bootloader-Bereichs (statt auf die Adresse 0). Dort enthalten bei einem fehlendem Bootloader bis zum Ende des Flashs alle Speicherzellen üblicherweise den Wert FF (hex) / 11111111 (bin). Immer vorausgesetzt, dass das eigentliche Programm nicht so groß ist, dass es schon in den Bootloader-Bereich hineinreicht. Im gelöschten/noch nicht programmierten Flash-Speicher sind alle Bits auf 1 gesetzt! FF FF ist für den Controller ein ungültiger Befehlscode, der nichts tut, aber auch nicht zur Exception oder zu ähnlichem führt. Nach dem "Nichtstun" wird der Program Counter erhöht und das nächste FF FF tut ebenfalls wieder nichts. Und irgendwann kommen wir am Ende des Adressbereichs an. Und jetzt wird wieder alles gut! Der Program Counter wird beim Überlauf als nächstes auf Adresse 0 gesetzt und dort sollte in der Interrupt-Vektor-Tabelle hoffentlich der Sprungbefehl zum eigentlichen Beginn des Programms stehen, der sonst bei einem Reset direkt ausgeführt würde. Aber die feine Art ist das auf keinen Fall!Gruß Wolfgang
|
|
|
|
|
29
|
International / Deutsch / Re: ATMega 328 Brennen
|
on: September 19, 2012, 03:36:33 am
|
Hallo melmann, wie du siehst, wäre es wahrscheinlich sinnvoll, die 15,95€ für einen Programmer locker zu machen. Das macht vieles einfacher, gerade wenn du nicht die Standard Arduino-Boards, sondern einen Selbstbau-Barebone verwenden willst. Und du kannst dich beim Lernen auf die wesentlichen Dinge konzentrieren und muss nicht jedesmal beim Programmieren des Controllers mit einen zweiten Board "rumhampeln"  Am Anfang meiner "Arduino-Karriere" hat man mir hier im Forum den Tipp gegeben, mir einen externen Programmer (ist zwar ein AVRISP MK II und nicht der mySmartUSB light) zuzulegen und ich habe das nie bereut. Übrigens, ich bekomme keine Provision für verkaufte Programmer und ich denke, alle anderen die hier einen externen Programmer empfehlen, auch nicht.  Schönen Gruß und viel Erfolg bei deinem Projekt Wolfgang
|
|
|
|
|
30
|
Community / Website and Forum / Re: mit timer interrupt auslösen
|
on: August 08, 2012, 01:28:27 pm
|
Hallo e-moler, du solltest deine Frage im deutschen Teil des Forums stellen. Dort wirst du sicherlich eine Antwort auf deine Fragen bekommen. Die Leute dort sind nett und garnicht "fies". Hier wird man dir nicht helfen können, weil die meisten hier nicht deutsch sprechen und du deine Fragen in einem Teil des Forums gestellt hast, dass sich mit dem Forum selbst, dem Server, der Web-Site, usw. befasst. Deshalb auch die Frage von PaulS, was deine Frage damit zu tun hat. Also, trau dich  Gruß Wolfgang Short summary for the English speaking forum members: I gave e-moler the advice to better post his question in the general German part of the forum.
|
|
|
|
|