Tutorial Arduino programmieren,

Antworten
Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

Tönt echt kompliziert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Tönt echt kompliziert.

Ich habe hier mal ein Beispiel, für mein Leopaden, der Leuchtet und den kann ich per IR Steuern.
Ca all 2 Sekunden werden Änderungen auf dem EEProm gespeichert(wenn es welche gegeben hat.
Außerdem gibt es noch Animationen, wenn sie eingestellt sind, werden sie abgespielt.
Und der atTiny prüft noch im "hintergrund" ob neue IR Signale da sind oder nicht.

Das ist dann "quasi" alles Gleichzeitig.
Klar ist das nicht mit einem PC zu vergleichen, aber ich finde es schon interessant.
Den gleichen Code habe ich noch mal ohne IR aber dafür mit 6 Buttons die ich Analog einlese.

Ist sowas wie eine Statmaschin, denke ich.

Code: Alles auswählen

 
void loop() {
  unsigned long irCode=0;
  int d;
 
  unsigned long currentMillis = millis();   
  if (currentMillis - previousMillis1 >= 2000) {  // Änderungen erst nach zwei Sekunden Speichern
    previousMillis1=currentMillis;
    ChangeSE();
  }   
 
 
  while(listenForIR()!=NUMPULSES) {
  }
 
  for (int i = 2; i < 34; i++) {
    irCode=irCode<<1;
    if((pulses[i][0] )>0&&(pulses[i][0])<(600/RESOLUTION)) {
      irCode|=0;
    }
    else {
     irCode|=1;
    }
    pulses[i][0]=0;
  }
  command(irCode);
}
 
MFG
Michael Springwald

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

Wen ich es richtig verstehe, dann läuft dann läuft die Loop ohne mitten drin unterbrochen zu werden ?

Aber dein while könnte die Schleife aber trotzdem unterbrechen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Wen ich es richtig verstehe, dann läuft dann läuft die Loop ohne mitten drin unterbrochen zu werden ?

Genau.

Aber dein while könnte die Schleife aber trotzdem unterbrechen ?

Hier ist ein kleiner Trick.... ist nicht ganz sauber..... die while schleife wird nur unterbrochen, wenn es IR Signale gibt.

Code: Alles auswählen

 
t listenForIR() {
/*
  pulse sample ||||||||||   |||||   || ||||  ||  || |||||
                 >5ms        3.5ms   bit pulses <400ms = 0 else 1
*/
 
  currentpulse = 0;
  while (currentpulse<NUMPULSES) {
   unsigned int highpulse, lowpulse; // temporary storage timing
   highpulse = lowpulse = 0; // start out with no pulse length
 
   while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
      highpulse++;
      delayMicroseconds(RESOLUTION);     
      if (currentpulse == 1 && highpulse>4000/RESOLUTION) return currentpulse;
      if (currentpulse>1&&highpulse >1500/RESOLUTION) return currentpulse;
      if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse;
      }     
     if (AnimationIndex > 0 && currentpulse == 0) UseAnimation(); 
   }
 
   pulses[currentpulse][0] = highpulse;
 
   while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
      lowpulse++;
      delayMicroseconds(RESOLUTION);     
      //if (currentpulse>1&&lowpulse >1+500/RESOLUTION) return currentpulse;
      if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse;
      }
   }
   pulses[currentpulse][1] = lowpulse;
   currentpulse++;   
 
  }
  return currentpulse;
}
 

Dieser Code stammt nicht von mir, ich habe ihn angepasst. So das es geht...
Es gibt noch ein anderen Code ohne IR:
Hier kann man es besser sehen...

Code: Alles auswählen

 
void loop() {   
  CheckButtons(); 
  if (AnimationIndex == 0) {
    if (ChangeColorIndex || ChangeBrightness)
      AllLED(ColorChangeByIndex());
  }
  else {
    UseAnimation();
  } 
 
  unsigned long currentMillis = millis();   
  if (currentMillis - previousMillis3 >= 2000) {  // Änderungen erst nach zwei Sekunden Speichern
    previousMillis3=currentMillis;
    ChangeSE();
  } 
}
 


PS: Irgendwie habe ich den Eindruck das der C Syntax Highlighter nicht so recht geht, mal geht er mal nicht....
MFG
Michael Springwald

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

PS: Irgendwie habe ich den Eindruck das der C Syntax Highlighter nicht so recht geht, mal geht er mal nicht....
das war schon immer so, das einzige was geht, ist der Pascal-syntax.

So was ähnliche habe ich auch schon gemacht, die Loop ohne Unterbrechung laufen lassen und für jedes Ereignis eine Zähl variable eingebaut. Oder bei einem Tastendruck ein Status setzten.
Aber einen Muliplex für eine Anzeige würde ich trotzdem in einem Timer nehmen, weil dort sich die kleinste Unterbrechnung sichtbar macht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

Mathias hat geschrieben:Schon mal ein Anfang. :wink:


Ich bin schon ein bisschen weiter gekommen, wen man "AVR-Application wählt", bekomme ich schon mal eine Unit.

Sowas könnte den Arduino-Freunden gefallen.

Code: Alles auswählen

unit Unit1;
 
interface
 
implementation
 
procedure Setup;
begin
 
end;
 
procedure Loop;
begin
 
end;
 
end
Dateianhänge
Bildschirmfoto vom 2018-08-26 22-49-41.png
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Nicht schlecht.... Ein guter Anfang.... wenn man jetzt noch den USB Port auswählen könnte und den AVR-Typ?
MFG
Michael Springwald

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Tutorial Arduino programmieren,

Beitrag von Timm Thaler »

Mathias hat geschrieben:Sowas könnte den Arduino-Freunden gefallen.


Ach nee, lass mal.

Mir ist bei anderen aktuellen Beiträgen schon aufgefallen, dass da offenbar versucht wird, Arduino-Style auf Pascal zu übertragen. Keine gute Idee, weil man die Nachteile von Arduino hier mit einschleppt.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Mir ist bei anderen aktuellen Beiträgen schon aufgefallen, dass da offenbar versucht wird, Arduino-Style auf Pascal zu übertragen. Keine gute Idee, weil man die Nachteile von Arduino hier mit einschleppt.

Es geht darum, die Nutzung zu vereinfachen. Keiner möchte sich durch 1000 verschiedene Datenblätter "Wühlen" und erst mal zwei Jahre lang rumprobieren bist die erste LED leuchtet oder so ähnlich.

Wir müssen ja nicht ALLES übernehmen, aber ein paar "Vereinfachungen" sollten wir schon übernehmen oder?
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Noch was: Es heißt immer Pascal wäre dazu nicht geeignet und es wäre nicht Effizient.... beweisen wir doch das Gegenteil?
Das könnte Vielleicht sogar Lazarus weiter verbreiten... z.b. an schulen und der gleichen.
MFG
Michael Springwald

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

Das mit dem Setup und Loop war nur ein Versuch Quellcode zu erzeugen.
Besser wäre der Styl wie in den Tutorials.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Tutorial Arduino programmieren,

Beitrag von kupferstecher »

Mathias, du kennst den LazWizardAVR, oder? Es fehlt noch die Integration als Package/Plugin in Lazarus.

http://forum.lazarus.freepascal.org/ind ... ,35486.msg

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Tutorial Arduino programmieren,

Beitrag von Mathias »

Auch schon gesehen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Tutorial Arduino programmieren,

Beitrag von Timm Thaler »

pluto hat geschrieben:Noch was: Es heißt immer Pascal wäre dazu nicht geeignet und es wäre nicht Effizient.... beweisen wir doch das Gegenteil...


Aber nicht durch ineffiziente Programmierung.

Diese Prozedur dürfte Dir bekannt vorkommen:

Code: Alles auswählen

procedure WritePortB(Pin: byte; Value: Boolean);
begin
  if Value then begin
    PORTB := PORTB or (1 shl Pin);
  end else begin
    PORTB := PORTB and not (1 shl Pin);
  end;
end;
 


Daraus macht der Compiler in Optimierungsstufe -O3 das hier:

Code: Alles auswählen

PsTEST_ss_WRITEPORTBsBYTEsBOOLEAN:
   mov   r18,r24
# Var Pin located in register r18
# Var Value located in register r22
# [18] if Value then begin
   cp   r22,r1
   breq   .Lj6
# [19] PORTB := PORTB or (1 shl Pin);
   ldi   r19,1
   mov   r20,r18
   tst   r20
   breq   .Lj8
.Lj7:
   lsl   r19
   dec   r20
   brne   .Lj7
.Lj8:
   in   r20,24
   or   r20,r19
   out   24,r20
   rjmp   .Lj9
.Lj6:
# [21] PORTB := PORTB and not (1 shl Pin);
   ldi   r19,1
   tst   r18
   breq   .Lj11
.Lj10:
   lsl   r19
   dec   r18
   brne   .Lj10
.Lj11:
   com   r19
   in   r18,24
   and   r18,r19
   out   24,r18
.Lj9:
# [23] end;
   ret


Das Problem ist hier die Variable. Für das Shift wird eine Schleife gebaut, die je nach Pin mehr oder weniger oft schiebt. Damit ist der Befehl auch noch unterschiedlich lang.

Da man aber meistens weiss, welchen Pin man setzen will, kann man den auch als Konstante angeben:

Code: Alles auswählen

    PORTB := PORTB or (1 shl 7);
 


Das sieht kompiliert so aus:

Code: Alles auswählen

# [41] PORTB := PORTB or (1 shl 7);
   sbi   24,7


Ein deutlicher Unterschied in Codegröße und Ausführungszeit. Das entscheidet darüber, ob Deine LED mit Soft-PWM oder Dein Display mit Multiplexing flimmert oder sauber leuchtet.

Aber, das geht mit Deiner Prozedur auch:

Code: Alles auswählen

procedure WritePortB(Pin: byte; Value: Boolean); inline;
begin
  if Value then begin
    PORTB := PORTB or (1 shl Pin);
  end else begin
    PORTB := PORTB and not (1 shl Pin);
  end;
end;


Das Entscheidende ist das kleine "inline". Damit wird aus Deinem Code bei Aufruf mit:

Code: Alles auswählen

WritePortB(7, true);


Code: Alles auswählen

# [33] WritePortB(7, true);
   sbi   24,7
 


Faszinierend, oder?

Das geht aber nur, wenn der Pin als Konstante angegeben wird. Ist er eine Variable, fliegt es Dir um die Ohren:

Code: Alles auswählen

# [35] for led := 0 to 7 do begin
   ldi   r18,-1
.Lj19:
   inc   r18
# [36] WritePortB(led, true);
   mov   r19,r18
   ldi   r20,1
   tst   r19
   breq   .Lj23
.Lj22:
   lsl   r20
   dec   r19
   brne   .Lj22
.Lj23:
   in   r19,24
   or   r19,r20
   out   24,r19
   cpi   r18,7
   brlo   .Lj19


Das ist zwar schon optimaler als ganz oben, aber bedingt durch das "inline" wird jetzt der Abschnitt jedesmal beim Aufruf von WritePortB mit einer Variablen eingebaut, was den Code sehr aufbläht.

Der Freepascal-Compiler optimiert an vielen Stellen auch für die kleinen AVRs erstaunlich gut, teilweise besser als der GCC. Aber man muss ihn zum einen auch lassen und sollte zum anderen immer im Hinterkopf haben, was da passiert und was der Controller kann. Ein oder zwei Blicke ins Datenblatt werden Dir nicht erspart bleiben.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Tutorial Arduino programmieren,

Beitrag von pluto »

Faszinierend, oder?

ja, was für ein Größen Unterschied.
Ich dachte immer ein DigitalWrite z.b. bräuchte immer gleich lang....

Ein oder zwei Blicke ins Datenblatt werden Dir nicht erspart bleiben.

Das ist durchaus richtig. Beim STM32F3 musste ich ins Datenblatt schauen, wegen der Pin Belegen des SWD....
Es sind aber zwei paar schuhe:
1. Das Datenblatt lesen.
2. Das Datenblatt verstehen, welches viel wichtiger ist.

Ich denke viele Angaben sind klar... Spannung, Strom, sowas in der Richtung.
Aber es gibt auch vieles, da braucht man einfach Hintergrund Wissen. Z.B. was verschiedene Register angeht.
Was heißt das eigentlich genau? Beim STM32 z.b. muss man alles erst einschalten beim AVR nicht(soweit weit ich weiß).
Das sind alles Detail Informationen. Die Irgendwo im Datenblatt stehen.

Klar, wenn man sich damit Jahre Lang befasst, kennt man es irgendwann. Jedoch ist ein "Anfänger" auf dieser Ebene überfordert. Darum habe ich mich auch erst mit Arduino und AVR befasst. Klar, habe ich davor auch Lazarus "gemacht", aber nicht mit AVR.

Ich denke, es geht einfach um die vielen Details. Z.B. einer im Verein(KTT-Oldenburg) hat ein Datenblatt zu einem LCD gelesen und Verstanden: Das man statt ca 8 Datenleitung eigentlich nur 2 bräuchte. Keine Standard Lib nutzt diese Funktion. Es war ein 128X64 LCD. Dabei wäre sie Praktisch.

Darum wäre es Sinnvoll, wenn man es "Anfängern" so leicht wie möglich machen würde, aus meiner Sicht. Am Anfang ist es egal wie groß das Programm ist.
Z.B. habe ich schon sehr früh am Anfang gelesen, dass man in AVR besser keine Strings nutzen sollte. Erst als ich mich mit den ESP befasst habe, habe ich sie genutzt.

Es geht immer nur um Details und die in Zusammenhang zu bringen...
MFG
Michael Springwald

Antworten