Was wollst du da skalieren? Es gibt nicht die Einstellung, den ADC mit 3V3 oder 5V zu nutzen ohne externe Referenz. Bei Spannungen > 3V3 muss du Spannungsteiler einsetzen, um diese zu messen.
Problem ist aber, dass mir eine Spannung von 0-3,23V (am Poti) per DEFAULT analogReference als Werte zwischen 0-51 ausgelesen werden und per INTERNAL Referenz als Werte zwischen 0-200.
Wenn das automatisch funktionieren würde, müsste mit DEFAULT Referenz bei 3,23V ein Wert nahe 1024 rauskommen...
Interessant ist auch, dass beim umstellen des Potis von 0 nach 10k Ohm der Wert erstmal ÜBER den statischen wert geht (bei INTERNAL steigt es erst auf 277 und fällt dann wieder auf 200 und bei DEFAULT geht es bis 62 und fällt dann auf 51).
Klar kann ich map() nutzen um es in den korrekten bereich zu "pfuschen", aber das muss ich dann bei jedem gelesenen Wert machen - und das kann so nicht der normal Weg bei einem auf 3.3V betriebenen µC sein.
Was soll DEFAULT sein, das wird auch wieder nur ein Makro der IDE sein, welches zwischen diversen µC entscheiden kann, was wo gesetzt werden muss. Das ist nicht selbstverständlich, dass dieses hier einfach so funktioniert.
Arbeite bei Werten, die dir nicht bekannt sind, mit den direkten Schreibbefehlen fürs Register.
ADMUXB &= ~((1<<REFS2) | (1<<REFS1) | (1<<REFS0)); // Ref Vcc
Nur als Beispiel, du musst schon im Datenblatt nachschlagen, ob die Register zu deinem µC überhaupt passen.
In der Datei c:\Program Files (x86)\Arduino165\hardware\arduino\avr\cores\arduino\wiring_analog.c ist int analogRead(uint8_t pin) definiert.
Wird Dein µC wirklich von 3,3 V betrieben? Die Batterie liefert doch nur 2,4 V oder verwendest Du externe 3,3 V?
Ich verwende externe und gemessene 3,23V.
Hast Du schon mal versucht, das ADIF Flag auszulesen, das das Ende einer Konvertierung anzeigt?
Ggf. warten bis es gesetzt ist, und dann erst/nochmal die Datenregister (ADCL/H) auslesen?
Ähmm...
wie macht man das denn, während es gelesen wird (oder generell)?
Ich lese einfach so aus:
boardSoftSerial.println(analogRead(PF1)); //PF1 ==A1 und pinMode(PF1, INPUT);
Was genau analogRead() tut, weiß ich nicht, aber ich denke mal es wird eine Routine drinne haben, die wartet, bis die Konvertierung zuende ist oder nicht?
Wenn ich deine Antwort richtig verstehe, ist der µC zu lahm um den Wert, den er am analogen Pin bekommt in einen Zahlenwert zu wandeln.
Wie kann ich sicherstellen, dass er genug Zeit bekommt?
PF1 als Makro ist doch nicht A1! Sondern einfach 1. Also Pin 1. Du musst da die Arduino Pin Nummer übergeben. Die Prozessor Pin-Namen kennt die IDE nicht.
Ich hab das Kommentar da hin geschrieben, weil eben doch PF1 ==A1 ist, wegen
#define PF1 A1 // PF1 ** 51 ** A1
am Anfang des Sketches.
Hab jetzt mal alles gelöscht, was ich momentan auskommentiert habe (der Sketch ist ja noch hart "under construction") und leserlich hier für euch:
#define PE0 0 // PE 0 ** 0 ** USART0_RX
#define PE1 1 // PE 1 ** 1 ** USART0_TX
#define PE2 2 // PE 2 ** 2
#define PE3 3 // PE 3 ** 3
#define PE4 4 // PE 4 ** 4 ** I2C_SCL
#define PE5 5 // PE 5 ** 5 ** I2C_SDA
#define PE6 6 // PE 6 ** 6
#define PE7 7 // PE 7 ** 7
#define PB0 8 // PB 0 ** 8 ** SPI_SS
#define PB1 9 // PB 1 ** 9 ** SPI_SCK
#define PB2 10 // PB 2 ** 10 ** SPI_MOSI
#define PB3 11 // PB 3 ** 11 ** SPI_MISO
#define PB4 12 // PB 4 ** 12 ** PWM
#define PB5 13 // PB 5 ** 13 ** PWM
#define PB6 14 // PB 6 ** 14 ** PWM
#define PB7 15 // PB 7 ** 15 ** PWM
#define PG3 16 // PG 3 ** 16
#define PG4 17 // PG 4 ** 17
#define PD0 18 // PD 0 ** 18
#define PD1 19 // PD 1 ** 19 ** INT0
#define PD2 20 // PD 2 ** 20
#define PD3 21 // PD 3 ** 21
#define PD4 22 // PD 4 ** 22
#define PD5 23 // PD 5 ** 23
#define PD6 24 // PD 6 ** 24
#define PD7 25 // PD 7 ** 25
#define PG0 26 // PG 0 ** 26
#define PG1 27 // PG 1 ** 27
#define PC0 28 // PC 0 ** 28
#define PC1 29 // PC 1 ** 29
#define PC2 30 // PC 2 ** 30
#define PC3 31 // PC 3 ** 31
#define PC4 32 // PC 4 ** 32
#define PC5 33 // PC 5 ** 33
#define PC6 34 // PC 6 ** 34
#define PC7 35 // PC 7 ** 35
#define PG2 36 // PG 2 ** 36
#define PA7 37 // PA 7 ** 37
#define PA6 38 // PA 6 ** 38
#define PA5 39 // PA 5 ** 39
#define PA4 40 // PA 4 ** 40
#define PA3 41 // PA 3 ** 41
#define PA2 42 // PA 2 ** 42
#define PA1 43 // PA 1 ** 43
#define PA0 44 // PA 0 ** 44
#define PF7 A7 // PF 7 ** 45 ** A7
#define PF6 A6 // PF 6 ** 46 ** A6
#define PF5 A5 // PF 5 ** 47 ** A5
#define PF4 A4 // PF 4 ** 48 ** A4
#define PF3 A3 // PF 3 ** 49 ** A3
#define PF2 A2 // PF 2 ** 50 ** A2
#define PF1 A1 // PF 1 ** 51 ** A1
#define PF0 A0 // PF 0 ** 52 ** A0
#include <SoftwareSerial.h>
SoftwareSerial boardSoftSerial(11,10); // RX | TX => MISO | MOSI
#define baudrate 9600 // bei 8MHz
int wertPF0;
int wertPF1;
int wertPF2;
int wertPF3;
int wertPF4;
int wertPF5;
int wertPF6;
int wertPF7;
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 20000; // interval at which to blink (milliseconds)
bool weiche = true;
void setup()
{
//baudrate mit dem Programmer-Board
boardSoftSerial.begin(baudrate); // mit einer baudrate von 19200 mit dem Board kommunizieren
//motorSteuerung
pinMode(PE6, OUTPUT);
digitalWrite(PE6, LOW);
pinMode(PE7, OUTPUT);
digitalWrite(PE7, LOW);
//Thermistor
pinMode(PF1, INPUT);
pinMode(PF3, OUTPUT);
digitalWrite(PF3, HIGH);
//Motorstrom messen
pinMode(PF2, INPUT);
// unbelegt
// pinMode(PF0, INPUT);
// pinMode(PF4, INPUT);
// pinMode(PF5, INPUT);
delay(3000);
}
void loop()
{
if(boardSoftSerial.available())
{
boardSoftSerial.println("Das Board hat folgendes empfangen:");
boardSoftSerial.print((char)boardSoftSerial.read());
while(boardSoftSerial.available())
{
// vom Board lesen und per HardwareSerial schreiben (an den PC übertragen)
boardSoftSerial.print((char)boardSoftSerial.read());
}
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
// save the last time you blinked the LED
previousMillis = currentMillis;
if(weiche)
{
boardSoftSerial.println("Default:");
analogReference(DEFAULT);
weiche = false;
}
else
{
boardSoftSerial.println("INTERNAL:");
analogReference(INTERNAL);
weiche = true;
}
}
//ThermistorWert-Ausgabe
boardSoftSerial.println(analogRead(PF1));
delay(50);
}
Diese Makros sollten doch intern schon definiert sein. Und zwar als Bit-Nummern in den Registern. Nicht als Pin-Nummern. Also z.B. PE0 = 0, PF0 = 0, PF1 = 1
Bekommst du da keine Warnung angezeigt dass du die neu definierst? (sofern Warnungen aktiviert sind).
Öhmm, also Warnungen bekomme ich keine.
Grund für die Definition am Anfang ist, dass ich in den PinNamen des ATmegas denke und nicht nach Pin-Nummern.
Meinst du, dass wird das Problem sein?
Ich check das gerade mal...
Ich würde sowas versuchen
adcVal1 = analogRead(A1); //Konvertierung starten
while (ADCSRA* & (1<<ADIF) == 0) ; //warten bis fertig
adcVal2 = (ADCH << 8) | ADCL;
Zu Deinen vielen seltsamen #define: die Pin-Namen sind alle bekannt nach #include <io.h>.
Es gibt keine Warnungen, wenn ein #define nochmal deklariert wird.
Normal ist es doch so dass wenn du das direkt machst, machst du sowas:
PORTB |= _BV(PB1);
Um Pin 1 von Port B zu setzen. Und so wird das auch von der Arduino IDE im Hintergrund gemacht. Dafür waren doch diese ganzen PROGMEM Tabellen da! Um die Arduino Nummern auf die Prozessor-Bezeichnungen zu übersetzen.
Wenn du du in Prozessor-Bezeichnungen denken willst, dann verzichte auf die Arduino Komfort Funktionen.
Also das raushauen der ganzen Definitionen bringt keine Änderung.
Ich werde jetzt mal DrDiettrichs Vorschlag testen.
Wie soll ich den Schaltplan eigentlich versorgen?
Momentan habe ich ein 3.3V Netzteil (1A) an 0V und VCC.
Zwischen Arduino UNO und dem Target-Board hängt ein Level-Konverter für 5V<=>3.3V, damit das Arduino nicht über die DigitalenPins das Target-Board versorgt.
Soll ich das Netzteil lieber an GND und VCC hängen?
GND ist natürlich alles auf einem Potential.
Sollte so doch eigentlich passen oder? (nur um ein Hardware/Anschlussfehler meinerseits auszuschließen).
EDIT:
Beim Testen deines Codes DrDiettrich kommt:
error: lvalue required as unary '&' operand
#define PF1 A1 // PF1 ** 51 ** A1
Das ist doch wie beschrieben lediglich die Pin Nummer. Nicht aber ein verweis darauf, dass es sich um einen Pin an Portxy handelt. Um das Projekt weiter voranzutreiben, solltest du Schrittweise immer erst wieder zur arduino typischen Anwendung zurückgreifen. Soll heißen, du testest die ganzen Sachen erst einmal auf avr-gcc Ebene. Sollte das soweit funktionieren, hast du eine Referenz in Bezug auf die Verschleierung der IDE. Sollte Punkt 1 nicht klappen, brauchst du noch garnicht weitergehen.
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe
Edit: Zur Versorgung
Microcontroller und Last sollte getrennt von einander behandelt werden. Ein 3V3 Netzteil halte ich da für wenig Sinnvoll. Eher etwas richtung 5V aufwärts. Die Spannung für den µC erzeugst du mit einem Linearregler.
Stefan ich habe leider keine Ahnung wie ich den µC auf avr-gcc Ebene anspreche und auch der Artikel ist mir nicht nahe genug an der Arduino IDE um davon auf meinen Anwendungsfall schließen zu können.
Ich merke definitiv, dass mir einiges an Wissen fehlt, aber kurzfristig will ich "einfach nur" ein paar analoge Werte einlesen und ein paar Digitale Pins HIGH und LOW setzen um meine Heizung jetzt in der kalten Phase besser zu Regeln.
Es steht aber definitiv schon auf meine ToDo-Liste mich ab Mai intensiver mit der Materie zu beschäftigen.
EDIT zu deinem EDIT:
Das Target-Board hat ja schon einen kompletten Schaltplan, der "normalerweise" ja auch nur mit maximal 3V versorgt wird. Wenn ich jetzt das Board mit mehr Spannung versorge, befürchte ich etwas zu brutzeln oder zumindest, dass ich alles aufgrund von falschen Werten programmiere, da nicht alle Bauteile Linear sind und zwischen 5V und 3V schon zum Teil deutliche Unterschiede auftreten.
Du kannst vielleicht mal testen ob die Pins als digitale I/Os zu funktionieren wie sie sollen. Da würde man auch sehen ob die Zuordnung Arduino Pin <-> Prozessor Pin passt.
Du meinst die AnalogenPins als digitale I/Os?
Zum Beispiel. Andere Pins gehen auch, aber so wie ich es verstehe kommst du nicht an alle Pins ran.
Es geht nur darum zu sehen ob z.B. digitalWrite(A1, HIGH) oder digitalWrite(10, LOW) macht was es soll.
Leon333:
Beim Testen deines Codes DrDiettrich kommt:
error: lvalue required as unary '&' operand
Tja, mein C ist wirklich stark eingerostet
Versuch mal *ADCSRA oder nur ADCSRA (wie beim Zugriff auf Ports).
Das Auslesen des 16 Bit Wertes könnte direkt mit ADCW erfolgen, wenn ich das _SFR_MEM16 Makro richtig interpretiere, im Unterschied zu _SFR_MEM8?
Und natürlich kein pinMode() für die Pins, die als Analogeingänge verwendet werden sollen.