Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Benutzeravatar
Raja_Kentut
Beiträge: 1557
Registriert: Mi 14. Aug 2013, 13:11
Wohnort: Veitsbronn-Bernbach

Re: Der AVR-/ARDUINO-Faden

Beitrag von Raja_Kentut »

vielen Dank erstmal!
Da lag ich ja bis auf die Klammern schonmal richtig - und hätte mich totgesucht wenn ich es auf der HW ausprobiert hätte und nix geht :-)
Das "schon auf" oder "schon zu" nicht geprüft wird ist nicht schick, aber es läuft - und macht mir als Anfänger alles übersichtlicher.
Die Feinheiten kommen so nach und nach ins Hirn :-)
Das mit dem Überlauf soll nach ca. 50 Tagen passieren. Dann stimmen halt worst case einmal die 10 Minuten nicht. Das steht tatsächlich ein paar Seiten im Thread weiter oben.

Das Gesamtprogramm falls es wer haben möchte :
// (c)Rolf Kowalsky 02.01.2021 / Kellerfenstersteuerung_V3
// Änderung zu Version Kellefenstersteuerung :
// 1)Einfügung einer Hysterese bei der Entscheidung Fenster öffnen oder Fenster schließen
// durch rechnen mit INTEGER. Dadurch werden sehr kleine Änderungen ignoriert. Das soll
// vermeiden das bei Wettersituationen im Grenzbereich das Fenster mehrmals kurz hintreinander
// auf- und zu fährt.
// 2)Berichtigung, so dass Fenster öffnen per Hand auch funktioniert,
// wenn Aussentemperatur kleiner Innentenperatur
// 3)Funktionsroutinen hinter Hauptprogramm geschoben
// Änderung zu Version Kellefenstersteuerung_V2 :
// 1)Verzögerung um "VerzAuf" ms beim automatischen öffen des Fensters.
// Dadurch soll das Fenster erst geöffnet werden nach Ablauf der Zeit "VerzAuf". Dadurch soll bei
// Wetteränderungen abgewartet werden bis sich Temperatur und Luftfeuchtigkeit stabilisiert haben.
// VerzAuf in Millisekunden.
// Verzögerung eingebaut in Funktion "fenster_oeffnen_auto ()"
//
//*************** HW Pinbelegung Leonardo Micro ***************************
//Pin 2 - I2C SDA
//Pin 3 - I2C SCL
//Pin 4 - OneWire Data (mit PullUp 4k7 an Vcc)
//Pin 5 - ZylAus_O Output für Signal Zylinder ausfahren (Relais oder SSR für Ausfahrmotor [oder Drehrichtung 1]
//Pin 6 - ZylEin_O Output für Signal Zylinder einfahren (Relais oder SSR für Einfahrmotor [oder Drehrichtung 2]
//Pin 7 - ZylAus_I Input für Signal Zylinder ausgefahren (Endschalter Endposition belegt)
//Pin 8 - ZylEin_I Input für Signal Zylinder eingefahren (Endschalter Anfangsposition belegt)
//Pin 9 - Hand_Auf Input für Schalter-Signal Fenster manuell öffnen
//Pin10 - Hand_Zu Input für Schalter-Signal Fenster manuell schliessen

// ************* Libraries **************************
#include <OneWire.h> // für Dallas 18B20 Temp.-Chip
#include <DallasTemperature.h> // für Dallas 18B20 Temp.-Chip
#include "Wire.h" // für SHT31 Temp./RH-Chip
#include "SHT31.h" // für SHT31 Temp./RH-Chip

OneWire oneWire(4); // Data Pin von Sensor am Pin 4 angeschlossen (4)
DallasTemperature sensors(&oneWire); // Library starten
SHT31 sht; // Library starten

// ************* Variablen ******************************
float gradC_I; // Innentemperatur in Grad Celsius
float gradC_A; // Aussentemperatur in Grad C
float humid_RH; // Relative Luftfeuchtigkeit
float tp; // Taupunkt in Grad C

unsigned long altMillis = 0; // Speichert alten millis Wert
unsigned long neuMillis = 0; // Speichert aktuellen millis Wert
const long VerzAuf = 600000; // Verzögerungszeit für Fenster öffen in Automatikbetrieb im ms (600.000 = 10 minuten)

int ZylAus_O = 5; // Output für Signal Zylinder ausfahren
int ZylEin_O = 6; // Output für Signal Zylinder einfahren
int ZylAus_I = 7; // Input für Signal Zylinder ausgefahren (hinter Endschalter Endposition)
int ZylEin_I = 8; // Input für Signal Zylinder eingefahren (hinter Endschalter Anfangsposition)
int Hand_Auf = 9; // Input für Signal Fenster manuell öffnen
int Hand_Zu = 10; // Input für Signal Fenster manuell schliessen
int gradC_Ii = 0; // Integerwert gradC_I
int gradC_Ai = 0; // Integerwert gradC_A
int tpi = 0; // Integerwert für Taupunkt in Grad C

// ************* Setup ******************************
void setup()
{
Serial.begin (9600); // UART Kommunikation initialisieren und auf 9600 Baud
sensors.begin(); // Dallas 18B20 initialisieren

Wire.begin(); // I2C Initialisieren
sht.begin(0x44); // SHT31 initialisieren
Wire.setClock(1000); // I2C Geschwindigkeit auf 1000 setzen

// ************* Pinzuweisungen I/O *****************
pinMode(ZylAus_O, OUTPUT);
pinMode(ZylEin_O, OUTPUT);
pinMode(ZylAus_I, INPUT);
pinMode(ZylEin_I, INPUT);
pinMode(Hand_Auf, INPUT);
pinMode(Hand_Zu, INPUT);

digitalWrite(ZylAus_O,LOW); //Bei Programmstart Ausgänge für Zylindermotoren auf LOW setzen
digitalWrite(ZylEin_O,LOW);
}

// ************* Hauptprogramm ***********************
void loop()
{
werte_einlesen(); //Sensorwerte einlesen
taupunkt_berechnen(); //Routine taupunkt_berechnen anspringen

tpi = (int)tp; // Umwandeln von tp in Integerwert. Verhindert öffnen/schließen bei minimalen Änderungen
gradC_Ii = (int)gradC_I; // Umwandeln von gradC_I in Integerwert. Verhindert öffnen/schließen bei minimalen Änderungen
gradC_Ai = (int)gradC_A; // Umwandeln von gradC_A in Integerwert. Verhindert öffnen/schließen bei minimalen Änderungen

// --- Prüfung Hand- oder Automatikbetrieb ---
if(digitalRead(Hand_Auf) == HIGH)
{ //WENN "Handbetrieb öffnen" dann Routine fenster_oeffnen anspringen
fenster_oeffnen(); //Routine fenster_oeffnen anspringen
Serial.println("Handbetrieb(öffnen)"); //Statusmeldung "Handbetrieb(öffnen)" auf UART ausgeben
}
else if(digitalRead(Hand_Zu) == HIGH)
{ //SONST1, wenn "Handbetrieb schliessen" dann Routine fenster_schliessen anspringen
fenster_schliessen(); //Routine fenster_schliessen anspringen
Serial.println("Handbetrieb(schliessen)"); //Statusmeldung "Handbetrieb(schliessen)" auf UART ausgeben
} //SONST2, wenn kein Handbetrieb ausgewählt, dann Automatikmodus
else if(tpi > gradC_Ii) //Vergleich mit Integerwerten um öffnen/schließen bei kleinsten Aänderungen zu vermeiden
{ //SONST3, wenn Taupunkt über Innentemperatur, dann Routine fenster_schliessen anspringen
Serial.println("Automatik schliessen TP>I");//Statusmeldung "Automatik schliessen TP>I" auf UART ausgeben
fenster_schliessen(); //Routine fenster_schliessen anspringen
}
else if(tpi < gradC_Ii) //Vergleich mit Integerwerten um öffnen/schließen bei kleinsten Aänderungen zu vermeiden
{ //SONST4, wenn Taupunkt unter unter Innentemperatur, dann Routine fenster_oeffnen anspringen
Serial.println("Automatik öffnen TP<I"); //Statusmeldung "Automatik öffnen TP<I" auf UART ausgeben
fenster_oeffnen_auto(); //Routine fenster_oeffnen anspringen
}
}

// ***************FUNKTIONSROUTINEN *****************
//void fenster_oeffnen() // Funktion Fenster öffnen
//void fenster_schliessen() // Funktion Fenster schliessen
//void fenster_oeffnen_auto() // Funktion Fenster öffnen mit vorheriger Prüfung ob Aussentemperatur über Innentemperatur
// und Verzögerung um "VerzAuf" ms
//float werte_einlesen() // Funktion Sensoren ausesen

// ************* Routinen für öffnen und schliessen *****

// ******** öffnen Handbetrieb *******************
void fenster_oeffnen() // Starten der Funktion Fenster öffnen (Zylinder Eingefahren = fenster auf)
{
digitalWrite(ZylAus_O,LOW); // Sicherstellen, dass nie beide Zylindermotoren gleichzeitig laufen
digitalWrite(ZylEin_O, HIGH); // Zylinder ausfahren über Pin ZylEin_O (Pin6)

while(digitalRead(ZylEin_I) == HIGH) // Solange Endschalter nicht belegt, bleibt ZylEin_O = HIGH, sonst ZylEin_O zurücksetzen
{
digitalWrite(ZylEin_O, HIGH);
}
digitalWrite(ZylEin_O, LOW);
}
// ******* öffnen Automatikbetrieb *******
void fenster_oeffnen_auto () // Starten der Funktion Fenster öffnen NUR wenn Aussen wärmer als Innen (Zylinder Eingefahren = fenster auf)
{
if(gradC_Ai < gradC_Ii) // wenn Aussentemperatur kleiner Innentemperatur (Integerwerte) dann Fenster schließen
{
fenster_schliessen(); // Routine fenster_schliessen anspringen
}
else // sonst prüfen ob Zeit "VerzAuf" vergangen ist und dann fenster öffnen
{
neuMillis = millis(); // beim allerersten Programmdurchlauf ist altMillis = 0 wegen Deklaration
if ((neuMillis - altMillis) >= VerzAuf) // vor öffnen prüfen ob Verzögrungszeit "VerzAuf" in ms vergangen ist
{ // wenn das der Fall ist...
fenster_oeffnen(); // Routine fenster_oeffnen anspringen
} // sonst zurück zum Hauptprogramm springen aber vorher noch
altMillis = neuMillis; // altMillis auf neuMillis hochsetzen
}
}
// ******** schließen ***************
void fenster_schliessen()
{
digitalWrite(ZylEin_O,LOW);
digitalWrite(ZylAus_O, HIGH);

while(digitalRead(ZylAus_I) == HIGH)
{
digitalWrite(ZylAus_O, HIGH);
}
digitalWrite(ZylAus_O, LOW);
}
// ************* Ende Routinen für öffnen und schliessen *****

// *************Routine Werte aus Sensoren einlesen***********
float werte_einlesen()
{
// --- Messwerte aus Sensoren einlesen ---
// Anfang Messung Innentemperatur ( gradC ) vom Dallas Temperatursensor
sensors.requestTemperatures(); // Temperaturmessung starten
gradC_I=sensors.getTempCByIndex(0); // gemessene Temperatur der Variablen gradC_I zuweisen
gradC_I=gradC_I-3; // KORREKTURWERT minus 3 Grad Celsius für Innentemperatur,(Meßaufbau mißt zu hohe Innentemperatur weil nicht direkt am Boden gemessen wird)
//Ende Messung Innentemperatur vom Dallas Temperatursensor. Temperatur nun in der Variable gradC_I

// Anfang Messung Aussentemperatur (gradC_A) und Feuchte (humid_RH) vom SGT31 Sensor
sht.read(); //SHT31 Messung starten
gradC_A=sht.getTemperature(), 1; //SHT31 Temperaturwert in Variable gradC_A speichern
humid_RH=sht.getHumidity(), 1; //SHT31 Feuchtewert in Variable humid_RH speichern
// Ende Messung Aussentemperatur (gradC_A) und Feuchte (humid_RH) vom SGT31 Sensor
// --- Messwerte sind eingelesen ---
}
// ************** Routine Taupunktberechnung ****************
float taupunkt_berechnen()
{
// verwendete Variablen :
// float gradC_I; // Innentemperatur in Grad Celsius
// float gradC_A; // Aussentemperatur in Grad C
// float humid_RH; // Aussenfeuchte in %RH
// float tp; // Taupunkt in Grad C
//--- Formel für Taupunktberechnung ---------------------
tp = 243.12*((17.62*gradC_A)/(243.12+gradC_A)+log(humid_RH/100))/((17.62*243.12)/(243.12+gradC_A)-log(humid_RH/100));

// *************Ende Routine Taupunktberechnung***********
// --- Messwerte ausgeben ---
Serial.print("Innentemperatur: ");
Serial.println (gradC_I); // Variable gradC_I auf UART ausgeben
Serial.print("Aussentemperatur: ");
Serial.println(gradC_A); // Variable gradC_A auf UART ausgeben
Serial.print("Aussenfeuchte RH: ");
Serial.println(humid_RH); // Variable humid_RH auf UART ausgeben
Serial.print("Taupunkt: ");
Serial.println(tp);
delay(1000);
// --- Messwerte sind ausgegeben ---
// *************Ende Routine Werte aus Sensoren einlesen***********
}
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

Hat schon mal jemand den digispark usb tiny85 benutzt?
ich würde den gern am moped verwenden, jetzt gibt's da unterschiede:
bei reichelt max spannung 12v.
bei ebay clonen werden 16v oder 35v behauptet.
alles lüge?
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Hier ist der Schaltplan dazu: https://s3.amazonaws.com/digispark/Digi ... cFinal.pdf
Kommt drauf an, welcher spannungsregler bestückt wurde. Zu dem hier gezeigten gibt es hier das Datenblatt: https://www.mouser.de/datasheet/2/308/M ... 773627.pdf
Da hast du 35V Maximum Rating
unlock
Beiträge: 635
Registriert: Sa 31. Dez 2016, 20:21

Re: Der AVR-/ARDUINO-Faden

Beitrag von unlock »

Ja, Problem ist Verlustleistung im Linearregler!
Am besten nochmal einen Regler vorschalten.

Achtung auch bei Signale, nicht über 5V!
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

danke.
also das gleiche gemache wie bei nano etc. um den halbwegs automotive zu bekommen.
das macht(e) halt den Formfaktor wieder zunichte :(
hier gehts mir jetzt konket um eine einzelne rgb led als Ladekontrolle.
wie er hier die anbietet:
https://gammatronixltd.com/epages/bae94 ... /Category1
(für das geld würde ich da jetzt nicht anfangen zu basteln, aber meine anfrage ob er das auch für life anbieten kann, verläuft anscheinend im sand.)

so, es geht ja um nix, daher würde ich hier kein gefatze machen, und mich mit mindestens dem 7805 zufrieden geben. :?:
würde so eine "neopixel" LED sinn machen um den strom für die led nicht von den pwm Pins zu holen sondern direkt vom bordnetz?

edit, geht anscheinend nicht nur mir so:
https://sites.google.com/site/klaasdc/a ... ry-monitor
unlock
Beiträge: 635
Registriert: Sa 31. Dez 2016, 20:21

Re: Der AVR-/ARDUINO-Faden

Beitrag von unlock »

Grob geschätzt würde mit einer RGB Led schon funktionieren,
denn es herschen im Vehikel ja nie konstant 35V, schlimmer sind Spannungsspitzen.

Wenn z.B. 1W abgeführt werden, dann kann mann P/Ui-Uo = 1W/35V-5V = 33mA,
bei Ub 15V -> 100mA.

Wenn mann aber bei:
1. Layout-> viel Kühlfläche, Metalgehäuse usw.
2. Schaltungsentwurf-> Wärmeerzeuger verteilen, Widerstände vorschalten usw.
sich etwas gedanken macht, sollte es selbst im Kfz(hohe Ambienttemperatur) ohne kritischen Zustand wirken.
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

hab mal bestellt. und schon mal angefangen zu hacken.
ach herje, naiv wie ich bin dachte ich serielle Kommunikation geht wie beim nano.
ich will halt den eeprom zum konfigurieren benutzen. also die Spannungsgrenzen im eeprom ablegen und über die konsole ändern.
jetz ist das bisschen anders :( :lol:
hab ein usb terminal fürs android, das behauptet digispark zu können, ich bin gespannt.
unlock
Beiträge: 635
Registriert: Sa 31. Dez 2016, 20:21

Re: Der AVR-/ARDUINO-Faden

Beitrag von unlock »

Wenn der Tiny noch keinen Bootloader hat, dann mußt Du über ISP mit einem anderen Controller programmieren.

Bei den anderen Boards sind Anschlüsse für ISP vorhanden, mußt aber den Arduino entfernen,
oder ISP via Arduino.
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

sind heute gekommen. upload geht nicht, fuck, wasn das schon wieder...treiberterror?
verschiedene usb probiert...nix :cry:
wenn man ihn allerdings richtig rum reinsteckt, gehts auf einmal :lol:
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Hat jemand von euch schonmal den Nano auf niedrigeren Takt umgefrickelt? Ich hab ne Anwendung, da muss ich Strom sparen, muss also mit dem Takt runter. Alles kein Thema, aber wie bringe ich da dem Compiler bei, damit meine Timings (millis (), I2C, Uart etc) wieder stimmen? Wo zum Henker muss ich ihm das mitgeben?
Matt
Beiträge: 6091
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

avr-gcc oder ähnlich -> makefile anpassen

Code: Alles auswählen

F_CPU = 16000000
= 16Mhz
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Weißt du zufällig, wo die liegen?
Matt
Beiträge: 6091
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

Bei arduino bin ich einfach überfragt. Ich weiss gar nicht, wie du code complierst.

Bei C-code packe ich immer makefile ins Ordner zusammen mit C Code, da jeder Projekte nicht gleiche µC bzw. Takt nutzt.
Dann starte ich Complimieren per "make all", fertig. Ich nutze avr-gcc.

ich werfe mal makefile.txt rein, da sollst du dann .txt Endung entfernen.
Atmega328p, 16Mhz
Dateianhänge
Makefile.txt
(17.05 KiB) 25-mal heruntergeladen
Zuletzt geändert von Matt am Do 7. Jan 2021, 10:42, insgesamt 2-mal geändert.
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Bisher nutze ich da immer die Arduino-IDE, dann muss ich da wohl drin wühlen....
jodurino
Beiträge: 2106
Registriert: So 17. Nov 2013, 20:43

Re: Der AVR-/ARDUINO-Faden

Beitrag von jodurino »

ch_ris hat geschrieben: Mo 4. Jan 2021, 11:04 Hat schon mal jemand den digispark usb tiny85 benutzt?
ich würde den gern am moped verwenden, jetzt gibt's da unterschiede:
bei reichelt max spannung 12v.
bei ebay clonen werden 16v oder 35v behauptet.
alles lüge?
Ja habe den jetzt mehrfach in Autos verwendet,
aber immer mit 7812 1,5A TO220 Gehäuse vor dem VIN
ganz klassisch mit Elko und 2 100nF Kondensatoren
funktioniert tadellos als Türpiepser mit Melodiegenerve

cu
jodurino
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Ich hab jetzt stumpf die Boards.txt durch ein eigenes ergänzt, dann rennt das!
he25rb
Beiträge: 35
Registriert: So 4. Dez 2016, 14:18

Re: Der AVR-/ARDUINO-Faden

Beitrag von he25rb »

Arduino mini core

https://github.com/MCUdude/MiniCore

sind alle Möglichkeiten von Frequenz und Versorgung drinnen

mfg herb
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

jodurino hat geschrieben: Do 7. Jan 2021, 11:05
Ja habe den jetzt mehrfach in Autos verwendet,
aber immer mit 7812 1,5A TO220 Gehäuse vor dem VIN
ganz klassisch mit Elko und 2 100nF Kondensatoren
funktioniert tadellos als Türpiepser mit Melodiegenerve

cu
jodurino
ok, danke.
wie ist das mit dem usb wenn vcc schon drauf ist?
der arduino bootet ja neu beim an und abstöpseln.
geht das hier auch oder besser Stromversorgung unterbrechen wenn ich neu booten will nach Änderung am eeprom?
hab da im netz nichts zu gefunden.
IPv6
Beiträge: 2210
Registriert: Fr 17. Mär 2017, 22:05

Re: Der AVR-/ARDUINO-Faden

Beitrag von IPv6 »

@Finger:
Ich nehme dafür auch den Arduino MiniCore.
Kann man alle möglichen Taktfrequenzen nehmen und der Standardkrams funktioniert.

Zum Stromsparen mit einem Arduino Nano:
Spannungsregler weg und mit einer Brücke den mittleren Pin und das Kühlfahnenpad verbinden, da ist bei den chinesischen Nanos keine Leiterbahn dazwischen, der Strom muss einmal durch den Regler.
LEDs runtermachen und den USB-UART Wandler entfernen. Kann ja nach wie vor per ISP programmiert werden, serieller Monitor geht dann halt nicht mehr.

Problem war bei mir nur, dass bei internem 1 Mhz Oszillator die Arduino IDE, die ja avrdude aufruft, nicht die Programmiergeschwindigkeit runtersetzt, das war dann zu schnell für 1 Mhz. Also mit der Arduink IDE das hex file erzeugen und manuell per avrdude mit angepasstem Tempo hochschieben.

So ein umgebauter Nano liegt jetzt über ein halbes Jahr im Regel und wacht alle 8 Sekunden auf um eine Temperatur zu messen und diese zu verschicken. Das ganze läuft mit zwei AA Batterien aus meiner leere Batterien Kiste. Die Batterien haben immernoch unveränderte Spannung.
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

das mit dem V-USB von dem digispark (<DigiUSB.h>)ist ein bisschen frustrierend.
hab keine Möglichkeit gefunden per PC Terminal zu kommunizieren.
kann nur hoffen das es mit der Handy app klappt sobald ich ein otg adapter hab, meine kabel sind alle verschollen.
edit
treiberproblem mit win10 64
beim einstöpseln wird der digispark bootloader erkannt, wodurch der upload geht.
sobald der sich abmeldet nach 5sec hab ich ein unbekanntes gerät. :cry:
die weiteren nötigen treiber werden auch gar nicht im gerätemanager angezeigt.
wenns ein problem mit dem bootloader wäre, sollten doch trotzdem die installierten treiber im GM erscheinen denk ich.
edit2
tut
Zuletzt geändert von ch_ris am Fr 8. Jan 2021, 16:26, insgesamt 3-mal geändert.
sysconsol
Beiträge: 4059
Registriert: Fr 8. Jul 2016, 17:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von sysconsol »

Matt hat geschrieben: Do 7. Jan 2021, 10:31 avr-gcc oder ähnlich -> makefile anpassen

Code: Alles auswählen

F_CPU = 16000000
= 16Mhz
Ich dachte, das kann man via Arduino-IDE im Code-Editor mitgeben?
Benutzeravatar
ferdimh
Beiträge: 9420
Registriert: Fr 16. Aug 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von ferdimh »

Man kann das sogar am Anfang vom "Codefile" (das ja bei Arduino nicht auf .c endet, obwohl es das tun sollte) machen:
#undef F_CPU
#define F_CPU 1E6

und DANACH erst diversen Kram einbinden.

Das ist aber ultimativ hässlich, weil es dann verschiedenen konkurrierende Definitionen hat. Da hasst man sich in der Regel nachträglich dafür.
Matt
Beiträge: 6091
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

sysconsol hat geschrieben: Fr 8. Jan 2021, 13:23
Matt hat geschrieben: Do 7. Jan 2021, 10:31 avr-gcc oder ähnlich -> makefile anpassen

Code: Alles auswählen

F_CPU = 16000000
= 16Mhz
Ich dachte, das kann man via Arduino-IDE im Code-Editor mitgeben?
Ich nutze avr-gcc und nicht diese Arduino-IDE (werde ich auch nie es nutzen)
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

hier mal der Anfang einer terminal eingabe verarbeitung.

Code: Alles auswählen

void comUsb() {

	unsigned char prefix = inputString[0];
	unsigned char kommand = inputString[1];
	unsigned char kommand2 = inputString[2];


	if (prefix == 'v') {

		DigiUSB.print("adc-");
		DigiUSB.println(avgVal, 10);

	} else if (prefix == 'm') {//1==2){       //
		DigiUSB.print("high ");
		DigiUSB.println(vmin_ee11, 10);
		DigiUSB.print("max ");
		DigiUSB.println(vmax_ee10, 10);

	}
Die Eingabe sei stets 'v'. zurückkommen soll also "adc- bla"
Das fliegt mir um die Ohren, bzw. ich erhalte keine Rückgabe.
wenn ich den Inhalt des zweiten else if blocks komplett auskommentiere, gehts.
wenn ich nur eine einzige zeile wieder einkommentiere knallts.
wenn ich die Bedingung austausche (1==2) gehts.
:shock:
was ist hier los?
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Wofür brauchst du an der Stelle das "else"? Was passiert ohne dieses?
Und lass doch mal den Compileroutput sehen (Flash/Ram-Nutzung), irgendwelche Warnings?
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

grad nochmal probiert, mit/ohne else macht keinen Unterschied.

eclipse:

Code: Alles auswählen

'Building target: VoltLED'
'Printing size:'
"E:\Tools\Eclipse_Sloeb_433\arduinoPlugin\packages\arduino\tools\avr-gcc\4.8.1-arduino5/bin/avr-size" -A "D:\Eclipse_Workspaces\sloeber4.3.1\VoltLED\Release/VoltLED.elf"
D:\Eclipse_Workspaces\sloeber4.3.1\VoltLED\Release/VoltLED.elf  :
section           size      addr
.text             4498         0
.data              116   8388704
.bss               352   8388820
.comment            17         0
.debug_aranges    1264         0
.debug_info      32126         0
.debug_abbrev     6845         0
.debug_line       8240         0
.debug_frame      3548         0
.debug_str        9662         0
.debug_loc       22669         0
.debug_ranges     1368         0
Total            90705


'Finished building target: VoltLED'
' '

15:02:40 Build Finished. 0 errors, 0 warnings. (took 13s.181ms)
mit arduino hab ichs auch gebaut, genau der gleiche fehler.

Code: Alles auswählen

Couldn't deeply cache core build: Rel:
Running normal build of the core...
Der Sketch verwendet 4614 Bytes (76%) des Programmspeicherplatzes. Das Maximum sind 6012 Bytes.
Globale Variablen verwenden 468 Bytes des dynamischen Speichers.
eclipse behauptet zwei errors zu finden:

Code: Alles auswählen

Description	Resource	Path	Location	Type
The type 'DigiUSBDevice' must implement the inherited pure virtual method 'Print::write' 	DigiUSB.cpp	/VoltLED/libraries/DigisparkUSB	line 214	Code Analysis Problem
The type 'DigiUSBDevice' must implement the inherited pure virtual method 'Print::write' 	DigiUSB.cpp	/VoltLED/libraries/DigisparkUSB	line 214	Code Analysis Problem
ich glaub aber das ist ein sporadisch quer hängender Pup.
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Ich hänge an dem hier:
Globale Variablen verwenden 468 Bytes des dynamischen Speichers.
Wieviel RAM hat die Kiste?
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

tiny85. glaub 500?
ich denke du hast recht, das könnte einfach nur zu viel gewesen sein. :?:

verdammt!
hab noch mal bisschen aufgeräumt, nu gehts. :oops:
und jetzt bin ich bei 458 mit dem zweiten if.
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Das der Linker da kein Warning generiert ist schon doof. Aber zuwenig RAM sorgt gerne für die absonderlichsten Laufzeitprobleme....
Benutzeravatar
Fritzler
Beiträge: 12600
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Der Linker beim gcc generiert dir nurn Warning wenn du sowas im Linkerscript einbaust.
Woher soll der Linker denn wissen wie groß der RAM ist?
Wenn man bei brauchbaren IDEs den Prozessor angibt, dann wird im Linkerscript nen Makro ausgefüllt.

Hier mal wie ich das bei ARM mache:
linker.txt
(2.18 KiB) 35-mal heruntergeladen
Wenn der RAM aber schon voll ist mit .data, dann fliegt dir trotzdem noch der Stack um die Ohren.
Das ist eine hohe Kunst den maximalan Stackverbrauch eines Programms herauszufinden :mrgreen:

PS:
Könntet ihr mal .lds freischalten im Upload?
So enden meistens Linkerscripte.
nero
Beiträge: 729
Registriert: Mo 12. Aug 2013, 11:58
Wohnort: Oberbayern

Re: Der AVR-/ARDUINO-Faden

Beitrag von nero »

Fritzler hat geschrieben: Mo 11. Jan 2021, 18:07
Das ist eine hohe Kunst den maximalan Stackverbrauch eines Programms herauszufinden :mrgreen:
Unbenannt.PNG
Kratlclipse macht das mit Hilfe von ST recht gut. An Rekursionen scheiterts dann.

Sonst issses immer noch recht hilfreich den RAM anfangs mit 5A zu füllen und nach einmal richtig laufen lassen den RAM wieder auslesen. Da wo die 5A aufhöhren geht der Stack an
RTOS (nach Wahl) haben sowas idR eingebaut.
Benutzeravatar
Fritzler
Beiträge: 12600
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

nero hat geschrieben: Mo 11. Jan 2021, 18:24 Kratlclipse macht das mit Hilfe von ST recht gut. An Rekursionen scheiterts dann.
Das ist jetzt aber nur ein Call Graph für eine grade aufgerufene Funktion beim debuggen?
Oder seh ich das falsch?
Selbst wenn man das rausgefunden hat, dann könne (bei Cortex-M) dir immernoch mehrere nested IRQs den Tag versauen.
nero hat geschrieben: Mo 11. Jan 2021, 18:24 Sonst issses immer noch recht hilfreich den RAM anfangs mit 5A zu füllen und nach einmal richtig laufen lassen den RAM wieder auslesen. Da wo die 5A aufhöhren geht der Stack an
RTOS (nach Wahl) haben sowas idR eingebaut.
Das ist dann aber auch erst post mortem und nur für den grade durchgelaufenen Input.
Wenn dann mal ein anderer (unvorhergesehener) Input kommt, kanns immernoch krachen.
Große Kunst eben.

FreeRTOS kann Magic Patterns am start/ende vom Stack anlegen und ruft einen Callback auf wenn das verletzt/überschrieben wurde.

Der GCC hat da ja schon was eingebaut, aber leider nicht als wunschlos glücklich Version, man muss rumfrickeln:
www.adacore.com/uploads/technical-paper ... alysis.pdf
Aber auch das kann mal gut daneben liegen!
Mit LTO ging das Ganze dann sogar komplett kaputt (oder is das inzwischen gefixt?)
nero
Beiträge: 729
Registriert: Mo 12. Aug 2013, 11:58
Wohnort: Oberbayern

Re: Der AVR-/ARDUINO-Faden

Beitrag von nero »

Static Stack Analyzer. Also kein Ausführen nötig. Das fällt "irgendwie" ausm gcc mit raus
bei Rekursion etc scheiterts natürlich.
Aber ein printf, welches ganz tief unten zum Überlauf führt, findet man damit recht zuverlässig.

Der Trick ist eben den gesamten (Stack) RAM eindeutig zu füllen. Dann sieht man bis wohin er wächst. Zumindest typischerweise bei geplanter Anwendung oder im Test (der ja gerne auch quälen darf).
Das geht alles ohne Crash.

Wenns bis zum Crash kommt oder man einen Overflow im Verdacht hat (und man zur Laufzeit debuggen kann) hilft im gdb "rwatch". Das löst einen break beim Speicherzugriff aus. Den auf das Stackende setzen.
Benutzeravatar
Fritzler
Beiträge: 12600
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

nero hat geschrieben: Mo 11. Jan 2021, 18:59 Static Stack Analyzer. Also kein Ausführen nötig. Das fällt "irgendwie" ausm gcc mit raus
Dann funzt das wohl so wie im verlinkten Paper.
Der GCC kann pro Objektdatei und darin enthaltener Funktion die Stackgröße ausgeben.
Dann kann der GCC auch eine Callgraph anylse anfertigen.
Jetzt beides verbinden (macht der GCC leider nicht von sich aus), also ALLE Pfade durchgehen und STackgrößen aufaddieren.
Irgendeiner der Pfade hat dann den größten Stackverbrauch.
Das muss nicht der tiefste Pfad sein, irgendwer packt immer (ausversehen) Arrays auf den Stack :lol:
nero hat geschrieben: Mo 11. Jan 2021, 18:59 Der Trick ist eben den gesamten (Stack) RAM eindeutig zu füllen.
Da bin ich jetzt auch von nichts Anderem ausgegangen.
nero hat geschrieben: Mo 11. Jan 2021, 18:59 Zumindest typischerweise bei geplanter Anwendung oder im Test (der ja gerne auch quälen darf).
Ja eben typisch und für die sich ausgedachten Quälorgien im Test.
Dann kommt Murphy!
Auf 10 Byte genau sollt mans daher nicht treibern, auch wenn der RAM knapp wird.
Daher ja "große Kunst", einen guten Anhaltspunkt liefert das aber allemal.
nero hat geschrieben: Mo 11. Jan 2021, 18:59 Wenns bis zum Crash kommt oder man einen Overflow im Verdacht hat (und man zur Laufzeit debuggen kann) hilft im gdb "rwatch". Das löst einen break beim Speicherzugriff aus. Den auf das Stackende setzen.
Das geht auch ohne (du hattest ja nen Cortex-M ST Bild reingesetzt), setz den Stack an RAM Anfang.
Wenn der rauswandert gibts nen hardfault.
(oder busfault wenn du schöne faulthandler nutzt)
Das ist ncht nur zum debuggen super, sondern auch später im Produktiveinsatz.
Dann macht das Programm nicht erst irgendeinen Murks weils zB eine Sprungadresse überschrieben hat.
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

ich hab, ehrlich gesagt, keine Ahnung wovon ihr redet.
auch dachte ich, meine ich hab's mal gelesen, dynamisch speicher allokieren wäre nicht möglich auf dem avr.

hab mal minimal code zum eeprom<>v-usb probiert, der braucht schon 370b Ram.
die rxtx buffer von DigiUSB haben je 128b, vielleicht könnte man da noch was drehen.

edit. hab mal auf 64 geändert, scheint keine Probleme zu machen.
mit 32 wiederum geht's nicht, obwohl meine längste zeichenkette 18 zeichen ist.
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Finger »

Aber du hast dein Problem gelöst :mrgreen:
ch_ris
Beiträge: 3042
Registriert: Mo 30. Nov 2015, 10:08

Re: Der AVR-/ARDUINO-Faden

Beitrag von ch_ris »

Dank eurer Hilfe!
glaube ich muss hier bei dem kleinen Ding meinen Ansatz überdenken:
lustig los gehackt, String's sind toll weil bequem, huch- 7Kb sind zu viel.
von da aus hab ich's verkleinert und hab vermutlich immer um diese Ram problematik drum herum programmiert.
in der Annahme die Probleme wären andere.
Es war holprig. :lol:
Benutzeravatar
Cubicany
Beiträge: 3543
Registriert: Sa 15. Feb 2020, 17:48
Wohnort: Soest

Re: Der AVR-/ARDUINO-Faden

Beitrag von Cubicany »

Gibt es eine Möglichkeit, wie ich an einem Nano stumpf nacheinander die Ausgänge durchschalten kann?

Habe hier eine Anordnung von Leuchtmeldern, die so LED Einsätze für bis
24V drin haben, die schon bei 5V schön diffus leuchten. So hell sollen die nicht.
Und die sollen nacheinander durch laufen.

Es müsste ja irgendeine Alternative zu

/digitalWrite Pin x High
/delay 500

usw. geben, die einen schlankeren Fuß macht.

Gibt es da irgendeine Art Schieberegiser, Schleife oä.?
Benutzeravatar
Hightech
Beiträge: 11473
Registriert: So 11. Aug 2013, 18:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Hightech »

For ( int a, a=<16, a++){
digitalWrite(a, HIGH);
Delay(1000);
digitalWrite(a,LOW);
Delay(1000);
}
So oder ähnlich
gtfn-e
Beiträge: 7
Registriert: Do 27. Aug 2020, 10:48

Re: Der AVR-/ARDUINO-Faden

Beitrag von gtfn-e »

for (int a = 0; a <= 16; a++) {
...
Benutzeravatar
Cubicany
Beiträge: 3543
Registriert: Sa 15. Feb 2020, 17:48
Wohnort: Soest

Re: Der AVR-/ARDUINO-Faden

Beitrag von Cubicany »

Habe jetzt erst mal weil nur 6 LEDs verbaut sind, den Code "händisch" so aufgebaut, dass ich erst
mal alle LEDs schön den Ports 7 bis 12 zugeteilt habe und dann im eigentlichen Loop dann mal das
Alphabet für Sehbehinderte durchlaufen lasse. Das ganze klemmt derzeit am Fenster mit Blick
nach draußen. Einfach nur, um sich den Gag zu erlauben, wann die Leute anfangen zu fragen, was
das denn für "griechische Symbole" sind, die ich da ins All sende. ;) :lol:

Ne Schleife ist dafür etwas ungeeignet.
Benutzeravatar
Sven
Beiträge: 4421
Registriert: Fr 28. Jun 2013, 12:52
Wohnort: Sechsundzwanzigdreisechzehn

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sven »

Du könntest auch direkt aufs Port Register schreiben und in einer Schleife mit den Shift Operatoren ein Bit durchschieben.
Funktioniert natürlich nur, wenn alles an einem Port hängt und der Port nur die LEDs ansteuert.
Benutzeravatar
phettsack
Beiträge: 1203
Registriert: Mo 12. Aug 2013, 18:17

Re: Der AVR-/ARDUINO-Faden

Beitrag von phettsack »

Ich werfe mal die Library Ticker in den Hut.
Damit kann man sich verschiedene Ticker/Timer definieren und ist nicht mehr drauf angewiesen selber mit Delay zu stochern.

Den Tickerzähler kann man dann mit einem Modulo auswerten und dadurch die Ausgänge hochzählen:

Code: Alles auswählen

switch (timer1.counter() % 16) {
case 0:
 PIN1 = HIGH;
 break;
case 1:
 PIN2 = HIGH;
 break;
... usw
}
Das ist jetzt nur ein grober Entwurf, so aus dem Kopf runtergekurbelt.
MSG
Beiträge: 2196
Registriert: Fr 9. Nov 2018, 23:24
Wohnort: Nähe Dieburg

Re: Der AVR-/ARDUINO-Faden

Beitrag von MSG »

phettsack hat geschrieben: Fr 22. Jan 2021, 12:07Delay
delay ist eine Krankheit. Das bremst die komplette loop() Schleife aus. Und damit hat man dann wunderschöne Effekte bei Multiplexanzeigen,... :)

Ich mach das immer so:

Code: Alles auswählen

// global Data
unsigned long gNow; // current time

void loop() {
  gNow = millis(); // used in many other functions
  doSomething();
  ....
}

void doSomething(){
  static unsigned long sLastUpdateTime;  // time of last execution
  const int cRefresh = 100;   // execute every 100 ms

  if ( sLastUpdateTime < ( gNow - cRefresh ) ) {
    sLastUpdateTime = gNow;
    .....  // 
    }
}

j.o.e
Beiträge: 550
Registriert: Fr 29. Nov 2019, 01:15

Re: Der AVR-/ARDUINO-Faden

Beitrag von j.o.e »

gtfn-e hat geschrieben: Do 21. Jan 2021, 11:42 for (int a = 0; a <= 16; a++) {
...
So die Pins nicht aufsteigend sind, kann man mit a ein Array indizieren.

const int ledo[] = { LED2, LED7, LED1, ...};

und dann statt
digitalWrite(a, ...)
eben
digitalWrite(ledo[a], ...)

Oder so ...
IPv6
Beiträge: 2210
Registriert: Fr 17. Mär 2017, 22:05

Re: Der AVR-/ARDUINO-Faden

Beitrag von IPv6 »

MSG hat geschrieben: Fr 22. Jan 2021, 12:35 Ich mach das immer so:

Code: Alles auswählen

...
  if ( sLastUpdateTime < ( gNow - cRefresh ) ) {
 ...
Das ist genau der "falsche" Weg, der nach den 56 Tagen und einem Überlauf Probleme machen kann.
Mit fiktiven Werten als Beispiel:
Variable läuft nach 999 über, wird also nicht 1000, sondern nach 999 wieder zu 0.

Wird jetzt deine Funktion bei Timerstand = 999 aufgerufen (zufälligerweise) kann deine Abfrage nie mehr wahr werden, denn es kann keinen Wert größer 999 geben der die Abfrage wahr werden lassen würde.

Die Abfrage muss andersrum gestaltet werden:

Code: Alles auswählen

if (currentMillis - previousMillis >= interval)
Damit läuft das auch mit Überläufen in jedem Fall sauber.
Benutzeravatar
sukram
Beiträge: 3114
Registriert: Sa 10. Mär 2018, 18:27
Wohnort: Leibzsch

Re: Der AVR-/ARDUINO-Faden

Beitrag von sukram »

Wenn es ein 32 Bit Integer ist, sind es 49 Tage 17 Stunden 2 Minuten und ein paar Bröckchen. Das gleiche Problem lief mir erst vor kurzem auf meiner SPS über den Weg (dort in ST, aber gleiches Grundproblem).
MSG
Beiträge: 2196
Registriert: Fr 9. Nov 2018, 23:24
Wohnort: Nähe Dieburg

Re: Der AVR-/ARDUINO-Faden

Beitrag von MSG »

IPv6 hat geschrieben: Fr 22. Jan 2021, 13:05 Das ist genau der "falsche" Weg, der nach den 56 Tagen und einem Überlauf Probleme machen kann.

Die Abfrage muss andersrum gestaltet werden:

Code: Alles auswählen

if (currentMillis - previousMillis >= interval)
Damit läuft das auch mit Überläufen in jedem Fall sauber.
Ich sehe das Problem (tauchte bei mir noch nicht auf, da das Programm immer nur ein paar Stunden lief ;) ) und versuch grad deine Lösung nachzuvollziehen.

Annahme: Die Variablen haben einen Bereich von 0 bis 1000, damit es leichter nachzuvollziehen ist:

currentMillis wäre 2 (weil gerade übergelaufen)
previousMillis wäre 900 (Ausführung vor dem Überlauf)
interval wäre 100, damit der Programmteil alle 100ms ausgeführt wird:

if (currentMillis - previousMillis >= interval) <=>
if ( 2 - 900 >= 100 )
Da ist jetzt die Frage was 2 - 900 beim Datentyp unsigned int long als Ergebnis hat *grübel*
IPv6
Beiträge: 2210
Registriert: Fr 17. Mär 2017, 22:05

Re: Der AVR-/ARDUINO-Faden

Beitrag von IPv6 »

Wenn alle Variabeln vom Typ unsigned long sind, was sie sein müssen, damit sie auch gleichartig überlaufen, dann sind unter den genannten Voraussetzung 2 - 900 = 999 - 897 = 102.

Man kann die überlaufenden Variabeln wie eine Uhr betrachten, nach der 12 kommt die 1, so auch umgekehrt. Zwei Stunden vor 1 Uhr war es eben 11 Uhr.
j.o.e
Beiträge: 550
Registriert: Fr 29. Nov 2019, 01:15

Re: Der AVR-/ARDUINO-Faden

Beitrag von j.o.e »

MSG hat geschrieben: Fr 22. Jan 2021, 13:54
IPv6 hat geschrieben: Fr 22. Jan 2021, 13:05 Das ist genau der "falsche" Weg, der nach den 56 Tagen und einem Überlauf Probleme machen kann.

Die Abfrage muss andersrum gestaltet werden:

Code: Alles auswählen

if (currentMillis - previousMillis >= interval)
Damit läuft das auch mit Überläufen in jedem Fall sauber.
Ich sehe das Problem (tauchte bei mir noch nicht auf, da das Programm immer nur ein paar Stunden lief ;) ) und versuch grad deine Lösung nachzuvollziehen.

Annahme: Die Variablen haben einen Bereich von 0 bis 1000, damit es leichter nachzuvollziehen ist:

currentMillis wäre 2 (weil gerade übergelaufen)
previousMillis wäre 900 (Ausführung vor dem Überlauf)
interval wäre 100, damit der Programmteil alle 100ms ausgeführt wird:

if (currentMillis - previousMillis >= interval) <=>
if ( 2 - 900 >= 100 )
Da ist jetzt die Frage was 2 - 900 beim Datentyp unsigned int long als Ergebnis hat *grübel*
Der von Dir am Beispiel "damit es leichter nachzuvollziehen ist" gewähle Datentyp ist nicht "unsigned int long" - darum führt deine Überlegung zum Widerspruch. Anschaulicher ist das Schriftliche Subtrahieren:

002
- 900
1 <-- geliehen
--------
102

Bei der 100-er Stelle (also 0 - 9) musstest Du dir eine 1 (also 1000) leihen, damit ergibt sich 10 - 9 = 1. Ergo lautet das Ergebnis 102.

Die geliehene 1 (=1000) geht unter, da im Überlauf - denn dein Datentyp kann ja nicht unterscheiden zwischen 0 und 1000.
Antworten