Forum: Mikrocontroller und Digitale Elektronik IRMP auf einen PIC18F4520 portieren


von Andreas G. (andy1024)


Lesenswert?

Hallo,


ich versuche schon eine ganze Zeit IRMP auf einem PIC18F4520 zum laufen 
zu bekommen. Ich bin eher ein Hardwerker als ein Softwerker von daher 
hab ich nicht die große Ahnung. Als Enticklungsumgebung benutzte ich 
MPLAB X 2.10 mit dem XC 8 (V1.31) Kompiler.

Hat jemand einen funktionierenden Version?

Bitte nicht auf den thraed im Forum verweisen, den kenne ich schon.


Gruß
Andy

von Konrad S. (maybee)


Lesenswert?

Und kennst du auch den Artikel IRMP mit den Hinweisen zu PIC?

von Andreas G. (andy1024)


Lesenswert?

Hallo Konrad,


ja den kenn ich, ich komm trozdem nicht klar...


Gruß
Andy

von Andreas G. (andy1024)


Lesenswert?

Hallo,

ich denke ich sollte meine Probleme etwas konkretisieren.


Wenn ich den Kompiler starte erhalte ich folgende Fehlermeldung:

"irmp.h:167:Error: syntax error"

gemeint ist folgende Zeile

"extern uint8_t                          irmp_get_data (IRMP_DATA *);"

und IRMP_DATA ist rot unterstichen und wenn ich mit der Maus über 
IRMP_DATA fahre sehe ich folgenden Komentar: "Unable to resolve 
identifier IRMP_DATA"

Für mich sieht es so aus als wäre IRMP_DATA unbekannt.

Die originale main.c hab ich 1:1 kopiert und als neues Projekt angelegt.
Die einzige Änderung die ich gemacht hab sind die zwei #defines:

#define PIC_C18
#define WIN32

Die stehen im Hauptprogramm gleich am Anfang.


Andy

von Chris B. (dekatz)


Lesenswert?

Andreas Geissler schrieb:
> Als Enticklungsumgebung benutzte ich
> MPLAB X 2.10 mit dem XC 8 (V1.31) Kompiler.

In "irmpsystem.h" ist der XC8 Compiler gar nicht vorgesehen weil nicht 
auf das vordefinierte Compilermacro '__XC8' geprüft wird (welches der 
Compiler selbst liefert). Daher fehlt auch der Teil wo die richtigen 
Headerfiles für den XC8 eingebunden werden.....und wahrscheinlich noch 
so manches andere (habe nicht alle Sourcen überprüft wo es noch haken 
könnte).

Am besten lädst du dir von MICROCHIP den alten C18 V3.45 runter (findest 
du im Archiv), damit kommst du am ehesten zum Ziel!

von Peter C. (peter_c49)


Lesenswert?

>> MPLAB X 2.10 mit dem XC 8 (V1.31) Kompiler.

hab ich auch (auch wenn Linux), IRMP code compiliert damit.
hab mir einen simplen Fernbedienungstester damit gemacht, auch mit einem 
18F4520.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter C. schrieb:
>>> MPLAB X 2.10 mit dem XC 8 (V1.31) Kompiler.
>
> hab ich auch (auch wenn Linux), IRMP code compiliert damit.
> hab mir einen simplen Fernbedienungstester damit gemacht, auch mit einem
> 18F4520.

Hast Du etwas vom IRMP-Code anpassen müssen?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Andreas Geissler schrieb:
> gemeint ist folgende Zeile
>
> "extern uint8_t                          irmp_get_data (IRMP_DATA *);"
>
> und IRMP_DATA ist rot unterstichen und wenn ich mit der Maus über
> IRMP_DATA fahre sehe ich folgenden Komentar: "Unable to resolve
> identifier IRMP_DATA"

Das ist sehr merkwürdig. In irmp.h wird nämlich vorher irmpsystem.h 
includiert. Dort wird IRMP_DATA ohne wenn und aber definiert.

Ist diese Fehlermeldung wirklich der allererste Fehler beim Compilieren?

Mir kommt es eher so vor, als ob der Compiler eher uint8_t und uint16_t 
nicht kennt. Diese beiden Typen werden nämlich in IRMP_DATA verwendet.

> Für mich sieht es so aus als wäre IRMP_DATA unbekannt.

Das kann ich mir nicht erklären, siehe oben. Für mich sieht das eher wie 
ein Folgefehler aus.

> #define PIC_C18

XC8 ist aber nicht unbedingt C18 ;-)

> #define WIN32

Wofür? Vielleicht wegen uint8_t, weil es kein stdint gibt? Dieses 
Problem mit define von WIN32 totzuschlagen ist eher der falsche Weg.

Versuche es bitte folgendermaßen in irmpsystem.h:

#if defined(__XC8)
#include <stdint.h>
#endif

Platziere diesen Block vor der Zeile:

#if defined(ATMEL_AVR)


Wenn Dein Compiler dann wegen stdint.h meckert, dann schreibe 
stattdessen:

#if defined(__XC8)
typedef unsigned char                   uint8_t;
typedef unsigned short                  uint16_t;
#endif

Und nimm dabei bitte das define von WIN32 raus. Das ist definitiv 
falsch.

Mehr kann ich Dir nicht helfen, da ich keine 
PIC-C-Entwicklungsumgebungen kenne. Wahrscheinlich musst Du aber noch 
mehr anpassen, zum Beispiel den Timer-Code.

von Chris B. (dekatz)


Lesenswert?

Frank M. schrieb:
>
> #if defined(__XC8)
> #include <stdint.h>
> #endif
>

Benötigt auf jeden Fall noch ein
#include <xc.h>
um das richtige Includefile für den verwendeten Controller nachzuladen.

von Peter C. (peter_c49)


Lesenswert?

Hallo,

hab mal kurz verglichen:

c-2po:~/MPLABXProjects/PIC18F4520/IRMPtest1.X$ for i in `ls | grep -e 
"^i.*[h|c]"`; do echo $i; diff $i irmp-svn/$i; done
irmp.c
437,438c437,438
< #  define ANALYZE_PRINTF(__VA_ARGS)
< #  define ANALYZE_ONLY_NORMAL_PRINTF(__VA_ARGS)
---
> #  define ANALYZE_PRINTF(...)
> #  define ANALYZE_ONLY_NORMAL_PRINTF(...)
irmpconfig.h
26,27d25
< #define PIC_C18
<
35c33
< #  define F_INTERRUPTS                          15151   // interrupts 
per second, min: 10000, max: 20000, typ: 15000
---
> #  define F_INTERRUPTS                          15000   // interrupts per 
second, min: 10000, max: 20000, typ: 15000
105,106c103,104
< #elif defined (PIC_C18) 
// use RE1 as IR input on PIC
< #  define IRMP_PIN                              PORTEbits.RE1
---
> #elif defined (PIC_C18)                                                 // use 
RB4 as IR input on PIC
> #  define IRMP_PIN                              PORTBbits.RB4
irmpextlog.c
irmpextlog.h
irmp.h
irmpprotocols.h
irmpsystem.h
22,23d21
< #define __18CXX
<
57c55
< #  define F_CPU 32000000L
---
> #  define F_CPU 8000000L
110,111c108,109
< //#  include <timers.h> 
// timer lib
< //#  include <pwm.h> 
// pwm lib
---
> #  include <timers.h> 
// timer lib
> #  include <pwm.h> 
// pwm lib
c-2po:~/MPLABXProjects/PIC18F4520/IRMPtest1.X$ svn info irmp-svn/
Path: irmp-svn
Working Copy Root Path: MPLABXProjects/PIC18F4520/IRMPtest1.X/irmp-svn
URL: svn://mikrocontroller.net/irmp
Relative URL: ^/
Repository Root: svn://mikrocontroller.net/irmp
Repository UUID: aeb2e35e-bfc4-4214-b83c-9e8de998ed28
Revision: 120
Node Kind: directory
Schedule: normal
Last Changed Author: ukw
Last Changed Rev: 120
Last Changed Date: 2013-04-09 16:17:52 +0200 (Di, 09 Apr 2013)

c-2po:~/MPLABXProjects/PIC18F4520/IRMPtest1.X$

also hab nicht alzu viel aendern muessen, achte auf die svn rev, war 
r120.

in meinem main.c:

keine frage, #include <xc.h> ganz oben!!!

#define _XTAL_FREQ 32000000UL // 32mhz -> befehlstakt -> 8mhz
#define FOSC _XTAL_FREQ
#define FCY  FOSC / 4UL // Cycle Frequenz

#define BAUDRATE 19200UL
#define BRG (( FCY  16  BAUDRATE ) -1UL)

#include <stdio.h>
#include <stdlib.h>

#include "irmp.h"

...
hier mein HW setup, ports, timer, uart etc...
...

int main(int argc, char** argv) {

    IRMP_DATA irmp_data;  <=== !!!

...

    irmp_init();

...
  // infinite loop, interrupts will blink PORTD pins and handle UART 
communications.
    while (1) {
        LATBbits.LATB0 = ~LATBbits.LATB0;

        if (irmp_get_data (&irmp_data))
        {
            // ir signal decoded, do something here...
            // irmp_data.protocol is the protocol, see irmp.h
            // irmp_data.address is the address/manufacturer code of ir 
sender
            // irmp_data.command is the command code
            // irmp_protocol_names[irmp_data.protocol] is the protocol 
name (if enabled, see irmpconfig.h)
            printf("proto %d addr %d cmd %d\n", irmp_data.protocol, 
irmp_data.address, irmp_data.command );
        }
    }

natürlich die ~15khz interrupt routine noch


void interrupt high_priority high_isr(void) {
    LATD0 = 1; // blink LED for interrupt time measure

    if (TMR2IF) {
        TMR2IF = 0; // clear Timer 0 interrupt flag

         irmp_ISR();

    }
    LATD0 = 0; // blink LED
}

grob wars das. laeuft prima und zeigt mir was ich sehen wollte bevor ich 
eine fernbedienung entsorge.
hab das nur gemacht um mir aus dem gesammeltem haufen die gängigen 
rauszusuchen.

ach, die warnungen zu dem ANALYSE_PRINTF hab ich mal ignoriert da ich es 
nicht benutze.

c-2po:~/MPLABXProjects/PIC18F4520/IRMPtest1.X$ make
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory `~/MPLABXProjects/PIC18F4520/IRMPtest1.X'
make  -f nbproject/Makefile-default.mk 
dist/default/production/IRMPtest1.X.production.hex
make[2]: Entering directory `~/MPLABXProjects/PIC18F4520/IRMPtest1.X'
"/opt/microchip/xc8/v1.31/bin/xc8" --pass1  --chip=18F4520 -Q -G 
--double=24 --float=24 --emi=wordwrite --rom=default,-7D00-7FFF 
--opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore 
--mode=free -P -N255 --warn=0 --asmlist 
--summary=default,-psect,-class,+mem,-hex,-file 
--output=default,-inhx032 
--runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib 
,+plib  --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto 
"--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) 
%s" "--msgformat=%f:%l: advisory: (%n) %s" 
-obuild/default/production/IRMPmain.p1  IRMPmain.c
"/opt/microchip/xc8/v1.31/bin/xc8" --pass1  --chip=18F4520 -Q -G 
--double=24 --float=24 --emi=wordwrite --rom=default,-7D00-7FFF 
--opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore 
--mode=free -P -N255 --warn=0 --asmlist 
--summary=default,-psect,-class,+mem,-hex,-file 
--output=default,-inhx032 
--runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib 
,+plib  --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto 
"--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) 
%s" "--msgformat=%f:%l: advisory: (%n) %s" 
-obuild/default/production/irmp.p1  irmp.c
irmp.c:2051: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (2 instead of 1)
irmp.c:2084: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:2101: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:2109: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2140: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2161: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2225: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2237: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2249: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2337: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (7 instead of 1)
irmp.c:2659: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2733: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:2919: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (3 instead of 1)
irmp.c:2937: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (5 instead of 1)
irmp.c:3206: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:3367: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:3406: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:3428: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:3439: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (4 instead of 1)
irmp.c:3457: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (3 instead of 1)
irmp.c:3476: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (2 instead of 1)
irmp.c:3483: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (2 instead of 1)
irmp.c:3515: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (2 instead of 1)
irmp.c:3525: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (3 instead of 1)
irmp.c:3542: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (3 instead of 1)
irmp.c:3550: warning: (171) wrong number of preprocessor macro arguments 
for "ANALYZE_PRINTF" (3 instead of 1)
"/opt/microchip/xc8/v1.31/bin/xc8"  --chip=18F4520 -G 
-mdist/default/production/IRMPtest1.X.production.map  --double=24 
--float=24 --emi=wordwrite --rom=default,-7D00-7FFF 
--opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore 
--mode=free -P -N255 --warn=0 --asmlist 
--summary=default,-psect,-class,+mem,-hex,-file 
--output=default,-inhx032 
--runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib 
,+plib  --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto 
"--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) 
%s" "--msgformat=%f:%l: advisory: (%n) %s" 
-odist/default/production/IRMPtest1.X.production.elf 
build/default/production/IRMPmain.p1 build/default/production/irmp.p1
Microchip MPLAB XC8 C Compiler (Free Mode) V1.31
Copyright (C) 2014 Microchip Technology Inc.
License type: Node Configuration

:: advisory: (1233) Employing 18F4520 errata work-arounds:
:: advisory: (1234)  * Corrupted fast interrupt shadow registers
:: warning: (1273) Omniscient Code Generation not available in Free mode

Memory Summary:
    Program space        used  1070h (  4208) of  8000h bytes   ( 12.8%)
    Data space           used    9Bh (   155) of   600h bytes   ( 10.1%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   54Ch bytes   (  0.0%)

Running this compiler in PRO mode, with Omniscient Code Generation 
enabled,
often produces code which is 60% smaller and at least 400% faster than 
in
Free mode. The MPLAB XC8 PRO compiler output for this code could be
5759 bytes smaller and run 4 times faster.
See http://www.microchip.com for more information.

make[2]: Leaving directory `~/MPLABXProjects/PIC18F4520/IRMPtest1.X'

rom=default,-7D00-7FFF  auch ignorieren, dass brauch ich da ich in 
7D00-7FFF einen bootloader drin hab und behalten will.

ps: wenn du es gar nicht hinbekommst, ev kann ich das am wochenende mal 
um meinen bootloader verkürzen, testen and posten, weiss aber nicht ob 
ich den pic brenner finden werde bis dahin, meine pic18-dev-boards haben 
meist einen serial bootloader, dass würde bei dir nicht gehen ohne 
diesen mit meinem code.

mfG
Peter ;-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter C. schrieb:

> hab mal kurz verglichen:

Danke, ich werde Deine Änderungen in IRMP einbauen. Wärest Du dann so 
nett und würdest das Ergebnis bei Dir nochmal testen?

> ach, die warnungen zu dem ANALYSE_PRINTF hab ich mal ignoriert da ich es
> nicht benutze.

Die sind auch nur für Windows und Linux, nicht für den µC. Muss mal 
schauen, wie ich die Aufrufe mit varargs elegant für die µCs eliminiere.

Vielen Dank und Gruß,

Frank

von Wolfgang S. (ws01)


Lesenswert?

Guten Abend. Da ich neu hier bin, es aber schon spät ist, nur eine ganz 
kurze Vorstellung: ich bin Informatiker, mit Microcontrollern und 
Elektronik spiele ich nur in meiner Freizeit ein wenig herum, mein C ist 
leider ziemlich eingerostet.  In Foren wie diesem hier lese ich zwar 
häufig mit, schreibe ansonsten aber fast nur im Usenet.  Irgend jemand 
muß da ja die Stellung halten. :-)

Mein Interesse an diesem Thread ergibt sich aus dem Umstand, daß ich 
Anfang des Jahres vor einem ähnlichen Problem stand, ich war von einem 
zig Jahre alten CCS C (mit älteren PIC) auf den XC8 umgestiegen (hrmpf), 
bastelte mich durch die Feinheiten von 10F320 und 12F1840, ärgerte mich 
über den XC8 und wollte herausfinden, ob sich mit letzterem ein frisch 
gekaufter WS2812B-Streifen ansteuern läßt.  Letztlich ist dann das hier:
http://www.mystrobl.de/Plone/basteleien/weitere-bulls-and-cows-mastermind-implementationen/mm-v1821/mastermind-solver-mit-led-streifen-und-ir-fernbedienung
herausgekommen, dabei ist auch eine Anpassung von IRMP an den 12f1840 
mit XC8 entstanden.  Ich bin noch dabei, den Artikel fertigzuschreiben 
und aus meinen div. Varianten das zusammenzusuchen, was ich an Code 
weitergeben möchte und in welcher Form. Jedenfalls kann ich aber gerne 
auch meine Variante der Anpassung von IRMP beisteuern.

An IRSND habe ich mir die Zähne ausgebissen, der XC8 in der kostenlosen 
Version ist einfach zu gecrippelt, als daß sich das Timing damit und dem 
besagten PIC machen ließe. IRMP funktioniert aber prächtig.

Diffs zur 2.4.0 ließen sich einfach produzieren, für einem Merge zur 
aktuellen Version benötigte ich aber ein Wochenende.  Vermutlich sollte 
ich dafür aber ggfs auf die diskutierten Ergänzungen (2.5.5?) warten ...

Bevor ich diesbezüglich etwas tue: besteht grundsätzlich Interesse?

Wolfgang

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:

> [...] Jedenfalls kann ich aber gerne
> auch meine Variante der Anpassung von IRMP beisteuern.

Danke für Dein Angebot, ich werde jetzt zunächst mal die Diffs von Peter 
C. (peter_c49) nehmen und diese in den IRMP einarbeiten. Sie sehen 
soweit ganz plausibel und passen auch soweit formal zu dem restlichen 
IRMP-Source.

Aber vielleicht kannst Du dann das Ergebnis, welches ich ins SVN 
einchecken werde, dann auch mal testen? 4 Augen (Peters und Deine) sehen 
gewiss mehr. :-)

> An IRSND habe ich mir die Zähne ausgebissen, der XC8 in der kostenlosen
> Version ist einfach zu gecrippelt, als daß sich das Timing damit und dem
> besagten PIC machen ließe.

Hm, das sollte eigentlich auch laufen. Okay, IRMP ist bei den Timings 
wesentlich toleranter als die Empfänger der meisten Hersteller....

> IRMP funktioniert aber prächtig.

Freut mich.

> Diffs zur 2.4.0 ließen sich einfach produzieren, für einem Merge zur
> aktuellen Version benötigte ich aber ein Wochenende.  Vermutlich sollte
> ich dafür aber ggfs auf die diskutierten Ergänzungen (2.5.5?) warten ...

Ja, ich checke heute dann eine neue Test-Version ein.

> Bevor ich diesbezüglich etwas tue: besteht grundsätzlich Interesse?

Latürnich! :-)

Viele Grüße,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

So, ich habe Peters Änderungen in den IRMP-Source eingebaut und das 
Ganze als Version 2.5.5 ins SVN eingecheckt. Wäre nett, wenn das einige 
hier testen könnten. Sicherlich sind noch kleine Korrekturen notwendig, 
um das Ganze rund zu machen :-)

Wo ich noch keine Lösung habe, sind die variadic Macros, die vom 
XC8-Compiler offenbar nicht unterstützt werden. Wenn da noch jemand eine 
pfiffige Idee hat, würde ich mich darüber freuen. Ziel ist es, dass sie 
nach NICHTS aufgelöst werden. Jetzt wird es jede Menge Warnungen hageln, 
die erstmal zu ignorieren sind.

Das Include von <xc.h> ist nach irmpsystem.h gewandert, Peters konkrete 
Portpin-Definitionen habe ich nicht eingebaut, aber dafür gesorgt, dass 
XC8 mit C18 eine gemeinsame Sektion in irmpconfig.h erhalten.

Peters Änderungen in main.c habe ich ans Ende von main.c geschoben - 
gekapselt durch #if defined(__XC8) .... #endif. Das Togglen der LEDs 
habe ich dabei rausgenommen. Das wäre eher ein schönes Beispiel der 
Callback-Funktion von IRMP.

P.S.
Dieses diff:


110,111c108,109
< //#  include <timers.h>
// timer lib
< //#  include <pwm.h>
// pwm lib
---
> #  include <timers.h>
// timer lib
> #  include <pwm.h>
// pwm lib


habe ich nicht verstanden. Für mich sieht das identisch aus.

@Peter: wäre prima, wenn Du weitere diffs mit Option -b machst. 
Vermutlich ist das hier ein Whitespace-Problem. Wenn Du den Output noch 
in
1
[code]
2
   ....
[/code]

packst, dann werden die Zeilen hier auch nicht umbrochen.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ich habe gerade noch irmp.c geändert und jeden Aufruf der Variadic 
Macros (ANALYZE_XXX(...)) geklammert. Nun sollten auch keine Warnungen 
mehr beim XC8-Compiler erscheinen.

Unschön: Durch diese Klammerung mit #ifdef ANALYZE ... #endif sieht der 
Source jetzt noch zerfranselter aus :-(

Ist eingecheckt.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Habe gerade noch 2 Fehler, die durch die Änderung reinkamen, entdeckt 
und behoben. Jetzt sollte der Source im SVN auch wieder durch den 
avr-gcc gehen ;-)

von Peter C. (peter_c49)


Angehängte Dateien:

Lesenswert?

Hallo Frank,

irmp trunk eben ausgecheckt, änderungen eingepflegt, svn diff.
1
@c-1po:~/irmp-trunk$ svn diff
2
Index: irmpconfig.h
3
===================================================================
4
--- irmpconfig.h        (revision 135)
5
+++ irmpconfig.h        (working copy)
6
@@ -30,7 +30,7 @@
7
  *---------------------------------------------------------------------------------------------------------------------------------------------------
8
  */
9
 #ifndef F_INTERRUPTS
10
-#  define F_INTERRUPTS                          15000   // interrupts per second, min: 10000, max: 20000, typ: 15000
11
+#  define F_INTERRUPTS                          15151 //15000   // interrupts per second, min: 10000, max: 20000, typ: 15000
12
 #endif
13
 
14
 /*---------------------------------------------------------------------------------------------------------------------------------------------------
15
@@ -104,7 +104,7 @@
16
  *---------------------------------------------------------------------------------------------------------------------------------------------------
17
  */
18
 #elif defined (PIC_C18)                                                 // use RB4 as IR input on PIC (C18 or XC8 compiler)
19
-#  define IRMP_PIN                              PORTBbits.RB4
20
+#  define IRMP_PIN                              PORTEbits.RE1 //PORTBbits.RB4
21
 
22
 /*---------------------------------------------------------------------------------------------------------------------------------------------------
23
  * Change hardware pin here for PIC CCS compiler
24
Index: irmpsystem.h
25
===================================================================
26
--- irmpsystem.h        (revision 135)
27
+++ irmpsystem.h        (working copy)
28
@@ -107,8 +107,8 @@
29
 
30
 #if defined (PIC_C18)                                                               // PIC C18 or XC8 compiler
31
 #  include <p18cxxx.h>                                                              // main PIC18 h file
32
-#  include <timers.h>                                                               // timer lib
33
-#  include <pwm.h>                                                                  // pwm lib
34
+//#  include <timers.h>                                                               // timer lib
35
+//#  include <pwm.h>                                                                  // pwm lib
36
 #  define IRSND_PIC_CCP1                1                                           // PIC C18 RC2 = PWM1 module
37
 #  define IRSND_PIC_CCP2                2                                           // PIC C18 RC1 = PWM2 module
38
 #endif

so sehen meine aenderungen aus wenn ich sie mit trunk (svn diff) mache.
compiliert ohne warnungen.
Test erst am wochenende, hab den brenner nicht hier.

ich kann das ganze mplapx project aber hier anhängen , ohne meine 
bootloader linker option. und ohne es getestet zu haben.
ist nur ~50k, hänge es an, ev hat Andreas es vor mir getestet ;-)

die 15151 interruptfrequenz muss jeder selbst drübersehen, mein timer 
ist so configuriert, siehe IRMPmain.c.

mfG
Peter

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Peter,

danke für den Test. Deine Änderungen habe ich eingecheckt. Die includes 
von timers.h und pwm.h habe ich per #ifndef __XC8 ausgeschlossen. Deine 
Änderungen in irmpconfig.h habe ich bzgl. F_INTERRUPTS lediglich im 
Kommentar vermerkt. Schließlich ist es ja eine Konfigurationsdatei, die 
ohnehin angepasst werden muss.

Damit sind wir der Sache ein gutes Stück näher gekommen :-)

Gruß,

Frank

von Wolfgang S. (ws01)


Lesenswert?

Hallo Frank,
>Frank M. schrieb:
> Wolfgang S. schrieb:
>> [...] Jedenfalls kann ich aber gerne
>> auch meine Variante der Anpassung von IRMP beisteuern.
>
> Danke für Dein Angebot, ich werde jetzt zunächst mal die Diffs von Peter
> C. (peter_c49) nehmen und diese in den IRMP einarbeiten. Sie sehen
> soweit ganz plausibel und passen auch soweit formal zu dem restlichen
> IRMP-Source.

Ich habe es gesehen und etwa das schwebte mir vor, als ich "auf die 
diskutierten Ergänzungen warten" schrieb.

>
> Aber vielleicht kannst Du dann das Ergebnis, welches ich ins SVN
> einchecken werde, dann auch mal testen? 4 Augen (Peters und Deine) sehen
> gewiss mehr. :-)

Mach' ich, wird aber ein paar Tage dauern, da Freizeitprojekt.

>
>> An IRSND habe ich mir die Zähne ausgebissen, der XC8 in der kostenlosen
>> Version ist einfach zu gecrippelt, als daß sich das Timing damit und dem
>> besagten PIC machen ließe.
>
> Hm, das sollte eigentlich auch laufen. Okay, IRMP ist bei den Timings
> wesentlich toleranter als die Empfänger der meisten Hersteller....

Das Codeaufblähen der freien Version des XC8 kostet auch viel Zeit, es 
gehen Interrupts verloren, weil die Interruptroutine innerhalb ihres 
Zeitslots nicht fertig wird. Versuchsweises Ablegen in einem Puffer und 
dann in einer Trivialschleife versenden funktioniert zwar im Prinzip, 
ist aber nicht wirklich brauchbar, deshalb habe ich das nicht 
weiterverfolgt.

Wolfgang

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:
> Mach' ich, wird aber ein paar Tage dauern, da Freizeitprojekt.

Ist klar. Prima!

> Das Codeaufblähen der freien Version des XC8 kostet auch viel Zeit, es
> gehen Interrupts verloren, weil die Interruptroutine innerhalb ihres
> Zeitslots nicht fertig wird.

Echt? Die irmp_ISR wird fertig, die irsnd_ISR jedoch nicht? Das hätte 
ich tatsächlich nicht gedacht. Wo Du von "Codeaufblähen" sprichst: 
Arbeitet die freie Version des XC8 bewusst ineffektiv?

Meinst Du, ich sollte nochmal in den Code der irsnd_ISR schauen, um nach 
Stellen, die man optimieren könnte, zu suchen? Oder lohnt sich das beim 
XC8 nicht?

von Peter C. (peter_c49)


Angehängte Dateien:

Lesenswert?

Hallo Frank, Andreas,

habe vor dem Wochenende zeit gefunden.
Es tut wie es auch mit meiner alten version tat.
Nur diesmal gibt es keinerlei warnungen oder sonstiges gejammere.
Habe auch nicht an dem debug ANALYSE_PRINTF drehen müssen.

ich haenge das testproject an, gemacht mit der "package" option in 
MPLABX.
also ein zip file.
Benutzt habe ich xc8-1.3.1 und mplabx 2.10. nur die free version, 
keinerlei optimierung.

Auch habe ich noch mal die Interruptzeit gemessen:
ca 3.5 us bei ruhe, springt bis auf ca 7us wenn IR tasten gedrückt 
werden.
das letztere könnte aber wohl an meinem UART interrupts liegen, da ich 
das ergebniss unmittelbar mit printf sende.
Die 7us werde ich nicht weiter verfolgen, ist mir fix genug.

Im anhang auch ein bildle mit dem alten frickelboard (rechts) und dem 
neuen Test auf dem steckbrett.

ps: irmp war vom svn revision 135. PIC18F4520 mit internem FRC+PLL 
(32Mhz), was 8Mhz cycle frequenz ergibt.

mfg
Peter ;-)

: Bearbeitet durch User
von Wolfgang S. (ws01)


Lesenswert?

Frank M. schrieb:
> Hallo Wolfgang,

Hallo Frank.

>
> Wolfgang S. schrieb:

>> Das Codeaufblähen der freien Version des XC8 kostet auch viel Zeit, es
>> gehen Interrupts verloren, weil die Interruptroutine innerhalb ihres
>> Zeitslots nicht fertig wird.
>
> Echt? Die irmp_ISR wird fertig, die irsnd_ISR jedoch nicht?

Ja.


> Das hätte
> ich tatsächlich nicht gedacht. Wo Du von "Codeaufblähen" sprichst:
> Arbeitet die freie Version des XC8 bewusst ineffektiv?

Ja. Zweifel bestehen bezüglich der Frage, ob lediglich einige 
Optimierungen stillgelegt wurden oder ob bewußt "junk" injiziert wird. 
Je nach Konstruktion eines Codegenerators kann man das m.E. gar nicht so 
einfach unterscheiden.

Bezüglich des Platzbedarfs würde ich es hinnehmen. Wenn Microchip an 
Bastler Prozessoren mit mehr Flash als nötig verkauft und so etwas mehr 
verdient, tut das niemandem wirklich weh. Wenn man aber mitten in einem 
Projekt gegen die Wand läuft, weil Realtime-Anforderungen völlig 
unerwartet ohne größeren Umbau und Verunstaltung des Code beim besten 
Willen nicht mehr einzuhalten sind, dann ist das eine andere Sache.

Hier ist ein langer Rant, allerdings ohne Details zu
<http://gerrysweeney.com/tag/xc8/>;

>
> Meinst Du, ich sollte nochmal in den Code der irsnd_ISR schauen, um nach
> Stellen, die man optimieren könnte, zu suchen? Oder lohnt sich das beim
> XC8 nicht?

Schwer zu sagen. Es hängt u.a. an Ausdrücken wie 
(irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0
die ziemlich merkwürdig übersetzt werden und unerwartet viel Zeit 
kosten. Aber selbst wenn man das testweise durch eine Konstante ersetzt, 
reicht es nicht.  Wenn ich meine drei Monate alten Notizen richtig 
entziffere, braucht bei RC5 eine vollständige Abwicklung mehr als zwei 
mal so lange wie rechnerisch der versendete Code in Realtime brauchen 
sollte. Gemessen mit irsnd_ISR-Aufruf in einer Schleife in main statt 
aus dem Timerinterrupt.  Da ich den ganzen Aufbau zwischenzeitlich 
wieder zerlegt habe, habe ich adhoc keine weiteren Details, wo genau die 
Zeit sonst noch verloren geht.

Wenn ich mit der Empfangsseite durch bin, die für mich im Moment die 
interessantere ist, mache ich mit irsnd weiter.

von Andreas G. (andy1024)


Lesenswert?

Hallo an alle,

Danke für die Postings...

Ich war die ganze Woche unterwegs, so das ich nicht antworten konnte, 
geschweige probieren konnte.

ich werde jetzt mal alles studieren und ausprobieren.


Danke nochmals
Andy

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

So, ich habe jetzt etwas Zeit gefunden, meine noch auf 2.4.0 basierende 
Anpassung von IRMP an den PIC 12F1840 in die derzeit aktuelle 
SVN-Version zu übertragen und dabei auf fast nichts abzuspecken.

Die wesentlichen Teile befinden sich in der main_pic.c, übersetzbar z.B. 
mit "compile_irmp.cmd" (ich benutze hier kein MPLAB-X, sondern simple 
Batchprozeduren).

Verschaltet wie folgt
1
                              PIC12F1840
2
       ___                     __
3
 10k -|___|-+           Vdd -o| o|o- Vss
4
       ___  +-RS232in / GP5 -o|  |o- GP0 / ICSPDAT
5
  1k -|___|-- RS232out/ GP4 -o|  |o- GP1 / ICSPCLK 
6
                  Vpp / GP3 -o|__|o- GP2 / TS TSOP1736

liefert das mit einem Bündel von Beispiel-Fernbedienungen folgende 
Output über die serielle Schnittstelle.
1
IRMP PIC 12F1840 1.1 ws
2
P 7 a=0x0011 c=0x000c f=0x00 (RC5)
3
P 6 a=0x0001 c=0x0018 f=0x00 (RECS80)
4
P 2 a=0xbf00 c=0x0019 f=0x00 (NEC)
5
P 2 a=0xeb14 c=0x0001 f=0x00 (NEC)
6
P 7 a=0x001c c=0x0005 f=0x00 (RC5)
7
P 7 a=0x000a c=0x0057 f=0x00 (RC5)
8
P 7 a=0x000a c=0x0057 f=0x01 (RC5)
9
P 2 a=0xfb04 c=0x0008 f=0x00 (NEC)

Folgende Änderungen waren nötig:

** Ein zusätzliches const in irmp.c bzw. irmp.h, um warnings bei 
Verwendung von IRMP_PROTOCOL_NAMES zu vermeiden.

** Eine Ergänzung in irmpconfig.h
1
+#if defined(__12F1840)
2
+#  define IRMP_PIN                              RA2
3
+# warning  "IRMP input via RA2 auf 12F1840"
4
+#endif

PORTBbits.RB4 gibt es beim 12F1840 nicht.

Die obige Warning sollte natürlich wieder raus.

Soweit für den Moment. Ich habe nicht umfänglich getestet und eine 
Fehlermeldung
1
 2318: (double) (time_counter * 1000) / 15000);
2
                 ^ (192) undefined identifier "time_counter"
3
                          (312) ";" expected ^

wenn man DENON enabled, ignoriert, ansonsten aber die im beliegenden 
Archiv angeknipsten Protokolle bzw. zugehörigen Codeschnipsel jedenfalls 
mit übersetzen können.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Peter,

Peter C. schrieb:

> Auch habe ich noch mal die Interruptzeit gemessen:
> ca 3.5 us bei ruhe, springt bis auf ca 7us wenn IR tasten gedrückt
> werden.

Gut. Aus Deiner Sicht sind also keine Änderungen notwendig?
Danke fürs Testen :)

Gruß,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:
> Hier ist ein langer Rant, allerdings ohne Details zu
> <http://gerrysweeney.com/tag/xc8/>;

Danke für die Info.

> Schwer zu sagen. Es hängt u.a. an Ausdrücken wie
> (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0
> die ziemlich merkwürdig übersetzt werden und unerwartet viel Zeit
> kosten.

Ja, denke ich mir. Das kann man aber noch optimieren. Werde mir mal 
darüber Gedanken machen....

> Wenn ich mit der Empfangsseite durch bin, die für mich im Moment die
> interessantere ist, mache ich mit irsnd weiter.

Prima!

Viele Grüße,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wolfgang S. schrieb:
> Die wesentlichen Teile befinden sich in der main_pic.c, übersetzbar z.B.
> mit "compile_irmp.cmd" (ich benutze hier kein MPLAB-X, sondern simple
> Batchprozeduren).

Meinst Du, es wäre eine gute Idee, main_pic.c mit ins IRMP-Paket zu 
packen?

> Verschaltet wie folgt
>
1
>                               PIC12F1840
2
>        ___                     __
3
>  10k -|___|-+           Vdd -o| o|o- Vss
4
>        ___  +-RS232in / GP5 -o|  |o- GP0 / ICSPDAT
5
>   1k -|___|-- RS232out/ GP4 -o|  |o- GP1 / ICSPCLK
6
>                   Vpp / GP3 -o|__|o- GP2 / TS TSOP1736
7
>


Das "Bild" könnte man ja noch dazupacken. Zum Beispiel auch im Artikel.

> liefert das mit einem Bündel von Beispiel-Fernbedienungen folgende
> Output über die serielle Schnittstelle.

Schön. Auch das wäre ein Kandidat für den Artikel.

> Folgende Änderungen waren nötig:
>
> ** Ein zusätzliches const in irmp.c bzw. irmp.h, um warnings bei
> Verwendung von IRMP_PROTOCOL_NAMES zu vermeiden.

Okay. Werde ich anpassen.

> ** Eine Ergänzung in irmpconfig.h
>
>
1
> +#if defined(__12F1840)
2
> +#  define IRMP_PIN                              RA2
3
> +# warning  "IRMP input via RA2 auf 12F1840"
4
> +#endif
5
>
>
> PORTBbits.RB4 gibt es beim 12F1840 nicht.

irmpconfig.h ist sowieso immer vom "Anwender" anzupassen.

> Soweit für den Moment. Ich habe nicht umfänglich getestet und eine
> Fehlermeldung
>
1
>  2318: (double) (time_counter * 1000) / 15000);
2
>                  ^ (192) undefined identifier "time_counter"
3
>                           (312) ";" expected ^
4
>
>
> wenn man DENON enabled, ignoriert, [...]

Das verstehe ich nicht. Der Teil steckt in einer Funktion, die nur mit 
übersetzt wird, wenn man ein Windows- oder Linux-Executable erzeugen 
will. Doubles meide ich auch auf µCs wie die Pest. Hier sollte die 
Funktion vom Preprocessor "weggefressen" werden.

Dank und Gruß,

Frank

: Bearbeitet durch Moderator
von Wolfgang S. (ws01)


Lesenswert?

Hallo Frank, Du schriebst im Beitrag #3717503
zu meiner Bemerkung

>> Schwer zu sagen. Es hängt u.a. an Ausdrücken wie
>> (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0
>> die ziemlich merkwürdig übersetzt werden und unerwartet viel Zeit
>> kosten.
>
> Ja, denke ich mir. Das kann man aber noch optimieren. Werde mir mal
> darüber Gedanken machen....

Konkret ist es so, daß current_bit / 8 als 16-Bit-Division (library 
call) implementiert wird,
1
127                           ;testcodeirsnd.c: 8: if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))
2
128                           
3
129                           ;incstack = 0
4
130                           ; Regs used in _main: [wreg+fsr1l+fsr1h+status,2+status,0+pclath+cstack]
5
131  077A  3008                      movlw   8
6
132  077B  00F0                      movwf   ___awdiv@divisor
7
133  077C  3000                      movlw   0
8
134  077D  00F1                      movwf   ___awdiv@divisor+1
9
135  077E  087C                      movf    _current_bit,w
10
136  077F  00F9                      movwf   ??_main
11
137  0780  01FA                      clrf    ??_main+1
12
138  0781  0879                      movf    ??_main,w
13
139  0782  00F2                      movwf   ___awdiv@dividend
14
140  0783  087A                      movf    ??_main+1,w
15
141  0784  00F3                      movwf   ___awdiv@dividend+1
16
142  0785  3187  27A2  3187          fcall   ___awdiv
17
143  0788  0870                      movf    ?___awdiv,w
18
144  0789  3E20                      addlw   _irsnd_buffer& (0+255)
19
145  078A  0086                      movwf   6
20
146  078B  0187                      clrf    7
21
147  078C  3001                      movlw   1
22
148  078D  00FB                      movwf   ??_main+2
23
149  078E  087C                      movf    _current_bit,w
24
150  078F  3907                      andlw   7
25
151  0790  3AFF                      xorlw   255
26
152  0791  3E01                      addlw   1
27
153  0792  3E07                      addlw   7
28
154  0793  0A89                      incf    9,f
29
155  0794  2F96                      goto    u234
30
156  0795                     u235:  
31
157  0795  35FB                      lslf    ??_main+2,f
32
158  0796                     u234:  
33
159  0796  0B89                      decfsz  9,f
34
160  0797  2F95                      goto    u235
35
161  0798  087B                      movf    ??_main+2,w
36
162  0799  0501                      andwf   1,w
37
163  079A  1903                      btfsc   3,2
38
164  079B  2FA0                      goto    l8
39
165                           
40
[/code}
41
42
43
Ersetzt man das durch einen Shift, wird, wie auch im zweiten Teil des Ausdrucks, in einer Schleife geshiftet.
44
45
[code]
46
;testcodeirsnd.c: 10: if (irsnd_buffer[current_bit >>3] & (1<<(7-(current_bit % 8))))
47
48                           
48
49                           ;incstack = 0
49
50                           ; Regs used in _main: [wreg+fsr1l+fsr1h+status,2+status,0]
50
51  07D5  0876                      movf    _current_bit,w
51
52  07D6  00F7                      movwf   ??_main
52
53  07D7  3003                      movlw   3
53
54  07D8                     u15:   
54
55  07D8  36F7                      lsrf    ??_main,f
55
56  07D9  0B89                      decfsz  9,f
56
57  07DA  2FD8                      goto    u15
57
58  07DB  0877                      movf    ??_main,w
58
59  07DC  3E70                      addlw   _irsnd_buffer& (0+255)
59
60  07DD  0086                      movwf   6
60
61  07DE  0187                      clrf    7
61
62  07DF  3001                      movlw   1
62
63  07E0  00F8                      movwf   ??_main+1
63
64  07E1  0876                      movf    _current_bit,w
64
65  07E2  3907                      andlw   7
65
66  07E3  3AFF                      xorlw   255
66
67  07E4  3E01                      addlw   1
67
68  07E5  3E07                      addlw   7
68
69  07E6  0A89                      incf    9,f
69
70  07E7  2FE9                      goto    u24
70
71  07E8                     u25:   
71
72  07E8  35F8                      lslf    ??_main+1,f
72
73  07E9                     u24:   
73
74  07E9  0B89                      decfsz  9,f
74
75  07EA  2FE8                      goto    u25
75
76  07EB  0878                      movf    ??_main+1,w
76
77  07EC  0501                      andwf   1,w
77
78  07ED  1903                      btfsc   3,2
78
79  07EE  2FF3                      goto    l8
79
80                           
80
81                           ;testcodeirsnd.c: 11: current_bit++;
81
82  07EF  3001                      movlw   1
82
83  07F0  00F7                      movwf   ??_main
83
84  07F1  0877                      movf    ??_main,w
84
85  07F2  07F6                      addwf   _current_bit,f
85
86  07F3                     l8:

Das ist immer noch ziemlich idiotisch, weil bei einer Konstante 3 drei 
Shiftinstruktionen hintereinander kürzer und schneller wären, aber immer 
noch viel besser.

Ich bin versucht, das durch einen Inline-Assembler-Makro zu ersetzten, 
der diese Bitadressierung in einen Bytearray realisiert, weiß aber 
nicht, ob das der Compiler hergibt. Eine portable Lösung wäre mir aber 
lieber. Mal schauen. Morgen habe ich vielleicht etwas mehr Zeit.

Viele Grüße, Wolfgang

von Wolfgang S. (ws01)


Lesenswert?

Frank M. schrieb:
> Wolfgang S. schrieb:
>> Die wesentlichen Teile befinden sich in der main_pic.c, übersetzbar z.B.
>> mit "compile_irmp.cmd" (ich benutze hier kein MPLAB-X, sondern simple
>> Batchprozeduren).
>
> Meinst Du, es wäre eine gute Idee, main_pic.c mit ins IRMP-Paket zu
> packen?

Ich habe nichts dagegen. Vielleicht sollte man es aber in 
main_pic12f1840.c umbenennen, denn es ist spezifisch für diesen. Wer 
sich mit den PICs auskennt, dürfte abschätzen können, ob das als Vorlage
für andere aus der selben Subfamilie taugt.

>
>> Verschaltet wie folgt
>>
1
>>                               PIC12F1840
2
>>        ___                     __
3
>>  10k -|___|-+           Vdd -o| o|o- Vss
4
>>        ___  +-RS232in / GP5 -o|  |o- GP0 / ICSPDAT
5
>>   1k -|___|-- RS232out/ GP4 -o|  |o- GP1 / ICSPCLK
6
>>                   Vpp / GP3 -o|__|o- GP2 / TS TSOP1736
7
>>
>
>
> Das "Bild" könnte man ja noch dazupacken.

In der oa main_pic.c ist es ja schon drin.

>Zum Beispiel auch im Artikel.

Du kannst es gerne übernehmen, wenn Du möchtest.

>
>> liefert das mit einem Bündel von Beispiel-Fernbedienungen folgende
>> Output über die serielle Schnittstelle.
>
> Schön. Auch das wäre ein Kandidat für den Artikel.

Ok.

>
>> Folgende Änderungen waren nötig:
>>
>> ** Ein zusätzliches const in irmp.c bzw. irmp.h, um warnings bei
>> Verwendung von IRMP_PROTOCOL_NAMES zu vermeiden.
>
> Okay. Werde ich anpassen.
>
>> ** Eine Ergänzung in irmpconfig.h
>>
>>
1
>> +#if defined(__12F1840)
2
>> +#  define IRMP_PIN                              RA2
3
>> +# warning  "IRMP input via RA2 auf 12F1840"
4
>> +#endif
5
>>
>>
>> PORTBbits.RB4 gibt es beim 12F1840 nicht.
>
> irmpconfig.h ist sowieso immer vom "Anwender" anzupassen.

Schon, es stehen aber bereits prozessorspezifische Beispielwerte drin. 
Es wäre halt praktisch, wenn es "out of the box" liefe.

>
>> Soweit für den Moment. Ich habe nicht umfänglich getestet und eine
>> Fehlermeldung
>>
1
>>  2318: (double) (time_counter * 1000) / 15000);
2
>>                  ^ (192) undefined identifier "time_counter"
3
>>                           (312) ";" expected ^
4
>>
>>
>> wenn man DENON enabled, ignoriert, [...]
>
> Das verstehe ich nicht. Der Teil steckt in einer Funktion, die nur mit
> übersetzt wird, wenn man ein Windows- oder Linux-Executable erzeugen
> will. Doubles meide ich auch auf µCs wie die Pest. Hier sollte die
> Funktion vom Preprocessor "weggefressen" werden.

IN 
https://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?revision=136&view=markup 
steht die obige Zweile 2318 hinter (!) einem "#endif // ANALYZE" und 
geklammert in ein
#if IRMP_SUPPORT_DENON_PROTOCOL == 1

"time_counter" wird als static int in Zeile 475 allerdings nur in einer 
"#ifdef ANALYZE"-Klammer definiert und ANALYZE wird, wenn ich mich 
richtig erinnere, tatsächlich nur bei der Desktop-Version definiert.

Die Funktion, in der das steckt, ist irmp_ISR, die ist ganz sicher nicht 
wegdefiniert.

Soviel für heute bzw. gestern, morgen ist auch noch ein Tag. :-)
Gute Nacht, Wolfgang

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wolfgang S. schrieb:
>>> PORTBbits.RB4 gibt es beim 12F1840 nicht.
>>
>> irmpconfig.h ist sowieso immer vom "Anwender" anzupassen.
>
> Schon, es stehen aber bereits prozessorspezifische Beispielwerte drin.
> Es wäre halt praktisch, wenn es "out of the box" liefe.

Hm, ich wollte nicht zuviel Fallunterscheidungen in irmpconfig.h machen, 
um den Anwender nicht abzuschrecken. Dieses PORTBbits.RB4 gibt es wohl 
nur bei anderen PIC-Compilern/µCs? Der PIC-Part ist nicht von mir, denn 
ich verwende keine PICs.

> "time_counter" wird als static int in Zeile 475 allerdings nur in einer
> "#ifdef ANALYZE"-Klammer definiert und ANALYZE wird, wenn ich mich
> richtig erinnere, tatsächlich nur bei der Desktop-Version definiert.

Ach, jetzt habe ich die richtige Stelle gefunden, nämlich diese:
1
#ifdef ANALYZE
2
              ANALYZE_PRINTF ("%8.3fms warning: did not receive inverted command repetition\n",
3
#endif // ANALYZE
4
                              (double) (time_counter * 1000) / F_INTERRUPTS);

Weil der XC8-Compiler keine Variadic Macros kennt, hatte ich vor ein 
paar Tagen per Editor-Macro sämtliche ANALYZE_PRINTF mit #ifdef ... 
#endif geklammert. Bei den mehrzeiligen Vorkommnissen musste ich dann 
nochmal nachbessern und habe offenbar diese Stelle übersehen. Der 
double-Ausdruck ist Argument des ANALYZE_PRINTF-Macros und gehört 
deshalb natürlich mit in den #ifdef ... #endif Block:
1
#ifdef ANALYZE
2
              ANALYZE_PRINTF ("%8.3fms warning: did not receive inverted command repetition\n",
3
                              (double) (time_counter * 1000) / F_INTERRUPTS);
4
#endif // ANALYZE

Ich werde die Änderung gleich einchecken.

Gruß und Dank,

Frank

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:
>>> Schwer zu sagen. Es hängt u.a. an Ausdrücken wie
>>> (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0
>>> die ziemlich merkwürdig übersetzt werden und unerwartet viel Zeit
>>> kosten.
>>
> Konkret ist es so, daß current_bit / 8 als 16-Bit-Division (library
> call) implementiert wird,

Igitt. Hätte ich gewusst, dass es immer noch derart dumme Compiler gibt, 
hätte ich das anders geschrieben. Eigentlich werden Divisionen mit 
Zweierpotenzen als Shift und Modulo-Operationen als Maskierung 
übersetzt.

Schreibe das bitte mal so:

(irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 0x07)))) ? 1 : 0

(Ich weiß, das erste hattest Du ja schon probiert. Vielleicht muss man 
dem Compiler beim Modulo-Operator auch noch auf die Sprünge helfen).

Viele Grüße,

Frank

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Frank M. schrieb:
> Hallo Wolfgang,
Hallo Frank.
>
> Wolfgang S. schrieb:
>>>> Schwer zu sagen. Es hängt u.a. an Ausdrücken wie
>>>> (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0
>>>> die ziemlich merkwürdig übersetzt werden und unerwartet viel Zeit
>>>> kosten.
>>>
>> Konkret ist es so, daß current_bit / 8 als 16-Bit-Division (library
>> call) implementiert wird,
>
> Igitt. Hätte ich gewusst, dass es immer noch derart dumme Compiler gibt,
> hätte ich das anders geschrieben.

Je nun. Der Compiler ist nicht dumm, er ist nur mutwillig gecrippelt. 
Ich habe zwischenzeitlich einen anderen Artikel (wieder-)gefunden, der 
das etwas umfänglicher beleuchtet: 
<http://www.t4f.org/articles/optimization-of-microchip-pic-xc8-compiler-in-free-and-pro-mode/>;

> Eigentlich werden Divisionen mit
> Zweierpotenzen als Shift und Modulo-Operationen als Maskierung
> übersetzt.

Klar.

>
> Schreibe das bitte mal so:
>
> (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 0x07)))) ? 1 : 0
>
> (Ich weiß, das erste hattest Du ja schon probiert.

Yep, in Beitrag 3718647. (Btw, gibt es eine elegante Möglichkeit, eine 
Beitragsid bzw. einen einzelnen Betrag herauszufischen?)

Dort sieht man aber auch, daß der Compiler aus modulo 8 bereits ein & 7 
macht:
1
149  078E  087C                      movf    _current_bit,w
2
150  078F  3907                      andlw   7

> Vielleicht muss man
> dem Compiler beim Modulo-Operator auch noch auf die Sprünge helfen).

Sieht nicht so aus.

Ich bin inzwischen aber ein paar Schritte weiter.  Zunächst war das 
Problem (auch) ein dummer Anfängerfehler auf meiner Seite, ich habe in 
der ISR den Timer nicht vor, sondern nach dem Aufruf von irsnd_ISR() 
reinitialisiert, so daß sich deren Zeitbedarf zu 1/F_INTERRUPTS 
addierte. Zusammen gab das einen Faktor vor etwas über zwei.  Nachdem 
ich die Division durch den Rechtsshift ersetzt UND diesen Fehler 
korrigiert hatte, war dieses Problem behoben.  Nun stellt sich aber ein 
weiteres Problem: zwei aufeinanderfolgende Aufrufe von RC5(...) 
produzieren unterschiedliche Ergebnisse, siehe die beiden 
DSO-Screenshots. Die "geraden" Outputs sind m.E. richtig, die ungeraden 
nicht.
1
void RC5(int addr,int cmd)
2
{
3
    // Dauern dürfte das für 14 Bit 14*889*2 µs == 0.0249 s
4
    // Gedauert hat es 1041 Ticks, also 0.0694 , also 2.78 mal so lang.
5
    irmp_data.protocol = IRMP_RC5_PROTOCOL;                       
6
    irmp_data.address  = addr;
7
    irmp_data.command  = cmd;
8
    irmp_data.flags    = 0;
9
    irsnd_send_data (&irmp_data, FALSE);     
10
}
11
    ....
12
13
    RC5(0x1c,0x11);
14
    while (irsnd_is_busy ()) putch('.');
15
    printf("\r\n");
16
    RC5(0x1c,0x11);
17
    while (irsnd_is_busy ()) putch('_');
18
    printf("\r\n");
19
    __delay_ms(25);

Wenn ich das mit einer gerade frisch abgezogenen SVN-Version probiere,
passiert das auch, zusätzlich kann irmp allerdings den irsnd-Output 
überhaupt nicht verstehen.
1
wolfgang@c7:~/irmp.svn/irmp> ./irsnd-15kHz 7 1a 11 0 > rc5
2
3
wolfgang@c7:~/irmp.svn/irmp> ./irmp-15kHz   <rc5
4
5
(kein Output)
6
7
wolfgang@c7:~/irmp.svn/irmp> ./irmp-15kHz   -l <rc5
8
pulse: 0 pause: 13
9
pulse: 13 pause: 13
10
pulse: 13 pause: 13
11
pulse: 13 pause: 13
12
pulse: 13 pause: 13
13
pulse: 26 pause: 26
14
pulse: 26 pause: 13
15
pulse: 13 pause: 26
16
pulse: 26 pause: 13
17
pulse: 13 pause: 13
18
pulse: 13 pause: 26
19
pulse: 13 pause: 676
20
pulse: 0 pause: 13
21
pulse: 13 pause: 13
22
pulse: 26 pause: 26
23
pulse: 13 pause: 13
24
pulse: 26 pause: 26
25
pulse: 26 pause: 13
26
pulse: 13 pause: 26
27
pulse: 26 pause: 13
28
pulse: 13 pause: 13
29
pulse: 13 pause: 26
30
pulse: 13 pause: 676

Sowohl in der PIC- als auch in der Linuxversion ist nur
1
define IRSND_SUPPORT_RC5_PROTOCOL              1       // RC5
aktiviert.

Soweit für den Moment, gute Nacht allerseits.
Wolfgang

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:
> Nun stellt sich aber ein
> weiteres Problem: zwei aufeinanderfolgende Aufrufe von RC5(...)
> produzieren unterschiedliche Ergebnisse, siehe die beiden
> DSO-Screenshots. Die "geraden" Outputs sind m.E. richtig, die ungeraden
> nicht.

Bei RC5 gibt es ein Toggle-Bit, welches sich bei einem langen 
Tastendruck nicht ändert, bei mehreren Tastendrücken schon. IRSND stellt 
dieses Verhalten nach:

  - Gibst Du einen Repeat-Wert in flags an, ändert sich das Toggle-Bit
    nicht.

  - Rufst Du irsnd_send_data() mehrfach auf, wird dieses Bit jedes
    Mal geändert.

Durch dieses Verhalten ist es normal, dass die Frames "verschieden" 
aussehen.

> Wenn ich das mit einer gerade frisch abgezogenen SVN-Version probiere,
> passiert das auch, zusätzlich kann irmp allerdings den irsnd-Output
> überhaupt nicht verstehen.
>
1
> wolfgang@c7:~/irmp.svn/irmp> ./irsnd-15kHz 7 1a 11 0 > rc5
2
> 
3
> wolfgang@c7:~/irmp.svn/irmp> ./irmp-15kHz   <rc5
4
> 
5
> (kein Output)
6
> 
7
8
Das kann ich nicht nachvollziehen.
9
10
[code]
11
chroot-eis-iv# grep 'PROTOCOL * 1 ' i*config.h
12
irmpconfig.h:#define IRMP_SUPPORT_RC5_PROTOCOL               1       // ...
13
irsndconfig.h:#define IRSND_SUPPORT_RC5_PROTOCOL              1       // ...
14
chroot-eis-iv# make -f makefile.lnx
15
...
16
chroot-eis-iv# ./irsnd-15kHz 7 1a 11 0 | ./irmp-15kHz
17
1111010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00
18
1011010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00

IRMP kann also den Output von IRSND durchaus verstehen. Da bei diesem 
Test irsnd_send_data() immer automatisch zweimal aufgerufen wird, kann 
man hier sehr schön die Änderung des Toggle-Bits sehen: das zweite 
angezeigte Bit ist verschieden (1. Zeile: 1, 2. Zeile: 0), die Codes 
sind trotzdem identisch.

Viele Grüße,

Frank

von Wolfgang S. (ws01)


Lesenswert?

Frank M. schrieb:
[...]
> Durch dieses Verhalten ist es normal, dass die Frames "verschieden"
> aussehen.

s.w.u.

>
>> Wenn ich das mit einer gerade frisch abgezogenen SVN-Version probiere,
>> passiert das auch, zusätzlich kann irmp allerdings den irsnd-Output
>> überhaupt nicht verstehen.
>>
>> wolfgang@c7:~/irmp.svn/irmp> ./irsnd-15kHz 7 1a 11 0 > rc5
>>
>> wolfgang@c7:~/irmp.svn/irmp> ./irmp-15kHz   <rc5
>>
>> (kein Output)
>>
>
> Das kann ich nicht nachvollziehen.

Ich zunächst auch nicht, dann ist mir aufgefallen, daß ich genau das 
getan hatte, was ich schrieb: ich habe IRSND_SUPPORT_RC5_PROTOCOL in 
irsndconfig.h auf den Wert 1 gesetzt. Und übersehen, daß auch 
irmpconfig.h angefasst werden muss. :-/ Manchmal hat man einfach Tomaten 
auf den Augen.

Nach der Korrektur und Neuübersetzen geht's natürlich auch bei mir.
1
wolfgang@c7:~/irmp> ./irmp-15kHz   <rc5
2
1111010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00
3
1011010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00

>
>
> chroot-eis-iv# grep 'PROTOCOL * 1 ' i*config.h
> irmpconfig.h:#define IRMP_SUPPORT_RC5_PROTOCOL               1       //
> ...
> irsndconfig.h:#define IRSND_SUPPORT_RC5_PROTOCOL              1       //
> ...
> chroot-eis-iv# make -f makefile.lnx
> ...
> chroot-eis-iv# ./irsnd-15kHz 7 1a 11 0 | ./irmp-15kHz
> 1111010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00
> 1011010010001 p= 7 (RC5), a=0x001a, c=0x0011, f=0x00
>
>
> IRMP kann also den Output von IRSND durchaus verstehen. Da bei diesem
> Test irsnd_send_data() immer automatisch zweimal aufgerufen wird, kann
> man hier sehr schön die Änderung des Toggle-Bits sehen: das zweite
> angezeigte Bit ist verschieden (1. Zeile: 1, 2. Zeile: 0), die Codes
> sind trotzdem identisch.

Verstehe. Diese Eigenschaft von RC5 war mir bisher nicht bekannt. Wieder 
was gelernt. Danke!    Ich mach dann mal weiter ...

Wolfgang

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Kurze Erfolgsmeldung (IRSND via XC8 auf einem 12F1840 lauffähig machen): 
Es sieht nicht nur gut aus (siehe dazu die beiden Screenshots),
mit einer provisorisch drangeklemmten IR-Diode (Vss -> Diode -> RA2) und
1
   RC5(0x12,0x0c)
läßt sich die alte Philips MC 115, die hier mein Arbeitszimmer bedröhnt, 
auch zuverlässig ausschalten, wenn man nah genug rangeht.

Ganz ohne Serienwiderstand funktioniert es meinen Erwartungen 
entsprechend auch auf größere Distanz, davon wird man selbstverständlich 
aber aus grundsätzlichen Erwägungen schärfstens abraten. :-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wolfgang S. schrieb:
> Kurze Erfolgsmeldung (IRSND via XC8 auf einem 12F1840 lauffähig machen):

Super! Gratuliere!

Was ist dafür im IRMP zu ändern?

> Ganz ohne Serienwiderstand funktioniert es meinen Erwartungen
> entsprechend auch auf größere Distanz, davon wird man selbstverständlich
> aber aus grundsätzlichen Erwägungen schärfstens abraten. :-)

Besser ist natürlich ein Transistor zwischen Portpin und LED - wie im 
Artikel angegeben. Die meisten IR-LEDs lassen sich schon mit wesentlich 
mehr als nur 20mA gepulst betreiben. 100mA sind immer drin. Dann kommt 
man auch entsprechend weit.

von Wolfgang S. (ws01)


Lesenswert?

Frank M. schrieb:
> Wolfgang S. schrieb:
>> Kurze Erfolgsmeldung (IRSND via XC8 auf einem 12F1840 lauffähig machen):
>
> Super! Gratuliere!

Danke.

>
> Was ist dafür im IRMP zu ändern?

Ich habe die meisten relevanten Änderungen, i.W. die Initialisierung der 
Peripherie in meine eigenen irsndmain_pic.c vorgenommen. Die könnte man 
einfach dazupacken. In irsnd.h habe ich in ein
1
# if defined(__12F1840)
geklammert PWMon und PWMoff passend dazu definiert.

In irsnd.c habe ich irsnd_set_freq erst mal stillgelegt, die Frequenz 
wird bei der Initialisierung festgelegt. Darüberhinaus ist überall 
"current_bit / 8" durch "current_bit >> 3" ersetzt (das bringt's) sowie 
% 8 acht durch & 7 (das macht keinen Unterschied, wie bereits erwähnt).

Die Frage ist, wie Du compiler- bzw. prozessorspezische Varianten 
einbebaut haben möchtest. Derzeit stehen durch PIC_C18 geklammerte 
Festlegungen in irsnd.c, die (auch) für den XC8 gedacht sind, 
darüberhinaus aber auch spezifisch für eine einzelne Prozessorfamilie. 
Die Libraryfunktion SetDCPWM gibt es AFAIK nur für die PIC18-Serie und 
mir fehlt ein wenig der Antrieb, das nachzuimplementieren. Vorschlag: 
ich lasse das so wie jetzt, also wie oben geklammert und schicke Dir 
diffs, wenn ich die Sachen etwas glattgezogen habe.


>
>> Ganz ohne Serienwiderstand funktioniert es meinen Erwartungen
>> entsprechend auch auf größere Distanz, davon wird man selbstverständlich
>> aber aus grundsätzlichen Erwägungen schärfstens abraten. :-)
>
> Besser ist natürlich ein Transistor zwischen Portpin und LED - wie im
> Artikel angegeben. Die meisten IR-LEDs lassen sich schon mit wesentlich
> mehr als nur 20mA gepulst betreiben. 100mA sind immer drin. Dann kommt
> man auch entsprechend weit.

Die PIC-Ports sind robuster, als viele Leute offenbar glauben. Mir ist 
noch nie ein PIC-Port durch eine ohne Serienwiderstand angeschlossene 
Diode kaputtgegangen, darüberhinaus baue ich hier keine kommerziellen 
Produkte, sondern nur Spielzeug für den Eigenbedarf, wobei ein Teil des 
Spaß darin besteht, mit möglichst kleinen PIC und möglichst wenig 
Bauteilen auszukommen. Da kommt dann z.B. so etwas bei heraus.

http://www.mystrobl.de/Plone/basteleien/10f320/stridulator

Und analog die Idee, was man mit einer CR2032, einem 12F1840, einer 
kleinen IR-LED und sonst nichts für Späße treiben kann. :-)

Wenn es um Robustheit, Leistung und Reichweite geht, wird man sicherlich 
ganz anders vorgehen und z.B. drei IR333 in Serie über einen FET 
schalten.  Für dergleichen suche noch nach einer Leistungs-LED mit 
passenden Eigenschaften (940nm, 1-3W, enger Sichtwinkel, in 
Einzelstückzahlen hier erhältlich).

von Andreas G. (andy1024)


Lesenswert?

Hallo Frank, Peter,


heute morgen hab ich versucht IRMP bei mir zum laufen zu bekommen.

Ich habe eure Hauprprogramme (main.c) in neue angelegte Projekt 
Dateien kopiert und F_CPU auf 12MHz abgeändert (12000000ul). Ansonsten 
hab ich nichts geändert.

Wenn ich jetzt den Kompiler starte erhalte ich folgende Fehlermeldung:

:0: error: undefined symbols:
_irmp_get_data(dist/default/production\FB_Tester_v0_6.X.production.obj) 
_irmp_init(dist/default/production\FB_Tester_v0_6.X.production.obj) 
_irmp_ISR(dist/default/production\FB_Tester_v0_6.X.production.obj)

Wie ich jetzt sehe sind das 3 Funktionen aus der main.c.

Hab ich was wichtiges Übersehen, nicht beachtet?


Gruß
Andreas

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Andreas,

Du musst auch irmp.c mit ins Projekt nehmen, also dazulinken. Dort sind 
die Funktionen definiert. In main.c werden sie nur aufgerufen.

Viele Grüße,

Frank

: Bearbeitet durch Moderator
von Andreas G. (andy1024)


Lesenswert?

Hallo Frank,


danke für die scnelle Hilfe jetzt läuft der Kompiler durch....


Gruß
Andreas

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Wolfgang S. schrieb:
> Frank M. schrieb:
>> Wolfgang S. schrieb:
>>> Kurze Erfolgsmeldung (IRSND via XC8 auf einem 12F1840 lauffähig machen):
>>
>> Was ist dafür im IRMP zu ändern?

...

> Die Libraryfunktion SetDCPWM gibt es AFAIK nur für die PIC18-Serie und
> mir fehlt ein wenig der Antrieb, das nachzuimplementieren. Vorschlag:
> ich lasse das so wie jetzt, also wie oben geklammert und schicke Dir
> diffs, wenn ich die Sachen etwas glattgezogen habe.

Hi Frank,

ich habe das eher schlechte Wetter heute abend dazu genutzt, etwas 
weiter herumzubasteln. Anbei ein Zwischenstand, so wie das jetzt ist, 
reicht es für meine Zwecke. TODO: Aufgrund des festen Prescalers wird 
irsnd_set_freq nur für Frequenzen oberhalb von 3120 kHz unterstützt.

Anbei ein Archiv, das alle Quellen enthält. Diffs stellt Du besser 
selber her. Basis ist IRMP:  2.5.7 01.07.2014 aus SVN.

In main_pic12f1840.c habe ich im Programmkopf der Testaufbau
und das Ergebnis ziemlich ausführlich kommentiert.

Das Programm kombiniert irmp, irsnd, zeigt empfangene Kommandos über 
RS232 und nimmt zwei triviale Sendebefehle über RS232 entgegen, eines 
für RC5 (meine Ausschaltsequenz), eines für NEC (ein fiktives 55 
aa-Kommando).

Schönes Restwochenende, Wolfgang

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Wolfgang,

Wolfgang S. schrieb:
> ich habe das eher schlechte Wetter heute abend dazu genutzt, etwas
> weiter herumzubasteln. Anbei ein Zwischenstand, so wie das jetzt ist,
> reicht es für meine Zwecke.

Erstmal danke für den Zwischenstand.

> TODO: Aufgrund des festen Prescalers wird
> irsnd_set_freq nur für Frequenzen oberhalb von 3120 kHz unterstützt.

3120 kHz?, ich nehme mal 31,2 kHz an :-) Das reicht.

> Anbei ein Archiv, das alle Quellen enthält. Diffs stellt Du besser
> selber her. Basis ist IRMP:  2.5.7 01.07.2014 aus SVN.

Vielen Dank. Ich habe Deine Änderungen soweit übernommen mit folgenden 
Anpassungen:

Variable irsnd_busy bleibt static. Muss ein Versehen Deinerseits gewesen 
sein, das "static" zu entfernen.

main_pic*.c und softuart.h habe ich in einem neuen Unterverzeichnis 
namens "pic" abgelegt. So bleibt das Hauptverzeichnis etwas 
übersichtlicher. Ich plane auch, irgendwann die main-Module für 
AVR/STM32 usw. in weitere Unterverzeichnisse abzulegen.

Diese ganzen Fallunterscheidungen für die jeweiligen µCs stören mich 
zunehmend im Source. Ich überlege, den ganzen µC-spezifischen Kram aus 
IRMP und IRSND rauszuwerfen und das Ganze anders zu lösen, nämlich zum 
Beispiel folgendermaßen für irmp:

 - Die ISR aus main.c liest den PIN aus.
 - Die Funktion irmp_ISR() bekommt den Zustand des Pins als Argument.

Damit wäre irmp.c komplett hardware-unabhängig. Die Pin-Definitionen 
könnten aus irmpconfig.h dann komplett raus. Für die jeweiligen 
µC-Familien müsste jeweils ein spezifischens irmp-main-xxx.c erstellt 
werden.

Bei IRSND wird das etwas schwieriger, hier müssten Callback-Funktionen 
definiert werden:

  - Initialisierung der PWM mit der gewünschten Frequenz
  - Einschalten der PWM
  - Abschalten der PWM

Der ganze hardware-technische Kram käme dann ins irsnd-main-xxx.c.

> In main_pic12f1840.c habe ich im Programmkopf der Testaufbau
> und das Ergebnis ziemlich ausführlich kommentiert.

Danke gefällt mir!

Viele Grüße,

Frank

P.S.
Deine Änderungen sind bereits im SVN. Ich hoffe, ich habe nichts 
übersehen.

: Bearbeitet durch Moderator
von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Frank M. schrieb:
> Hallo Wolfgang,

Hallo Frank.

>
> Wolfgang S. schrieb:
>> ich habe das eher schlechte Wetter heute abend dazu genutzt, etwas
>> weiter herumzubasteln. Anbei ein Zwischenstand, so wie das jetzt ist,
>> reicht es für meine Zwecke.
>
> Erstmal danke für den Zwischenstand.

Ist mir ein Vergnügen. :-)

>
>> TODO: Aufgrund des festen Prescalers wird
>> irsnd_set_freq nur für Frequenzen oberhalb von 3120 kHz unterstützt.
>
> 3120 kHz?, ich nehme mal 31,2 kHz an :-) Das reicht.

Tippfehler, ja, die fünf fehlte, passiert mir manchmal mit der linken 
Hand.
Konkret 32000000/((255+1)*4) == 31250.
Ich war zu faul, für die entsprechenden defines eine Fallunterscheidung 
in irsnd.c einzubauen.  So ergibt sich ein Unsinnswert bei 
IRSND_FREQ_30_KHZ.


>
>> Anbei ein Archiv, das alle Quellen enthält. Diffs stellt Du besser
>> selber her. Basis ist IRMP:  2.5.7 01.07.2014 aus SVN.
>
> Vielen Dank. Ich habe Deine Änderungen soweit übernommen mit folgenden
> Anpassungen:
>
> Variable irsnd_busy bleibt static. Muss ein Versehen Deinerseits gewesen
> sein, das "static" zu entfernen.

Flüchtigkeitsfehler. Ich hatte das zwecks Debugging aus der main heraus 
bei einigen Variablen gemacht und dann diese übersehen.

>
> main_pic*.c und softuart.h habe ich in einem neuen Unterverzeichnis
> namens "pic" abgelegt. So bleibt das Hauptverzeichnis etwas
> übersichtlicher.

Da der Aufbau so nicht funktioniert, habe ich für den Testfall passende 
Konfigurationsdateien dazugepackt, siehe Archiv. Mit den 
Defaulteinstellungen ist nicht nur das verwendete RC5 nicht enabled, es 
läßt sich auch gar nicht erst erfolgreich übersetzen bzw linken, weil - 
jedenfalls mit dem kostenlosen XC8 - der program space des 12F1840 nicht 
reicht.

Eine kleine Korrektur noch in irmpconfig.h:
In der Sequenz (etwas komprimiert)
1
/*-----------------------------
2
 * Change hardware pin here for PIC C18 or XC8 compiler
3
 *------------------------------
4
 */
5
#elif defined (PIC_C18)         // use RB4 as IR input on PIC (C18 or XC8 compiler)
6
#if defined(__12F1840)
7
#  define IRMP_PIN       RA5    // on 12F1840 with XC8 compiler
8
#endif
9
#  define IRMP_PIN       PORTBbits.RB4  // PIC C18
sollte der letzte define in einen else-Part verschoben werden, so ergibt 
das keinen Sinn, da IRMP_PIN zwei mal definiert wird, wenn __12F1840 
definiert ist und da PORTBbits.RB4 auf dem Prozessor gar nicht vorhanden 
ist.

Insgesamt ist das etwas unschön, in zwei Fälle PIC12F1840 einerseits und 
"alle anderen" zu trennen, mir fällt da aber auch nichts Besseres ein.


> Ich plane auch, irgendwann die main-Module für
> AVR/STM32 usw. in weitere Unterverzeichnisse abzulegen.

Ja, eine gute Idee. Vielleicht sogar Unterverzeichnisse für mehr oder 
weniger vollständige "Projekte", die dann spezifisch für einen konkreten 
Prozessor und Testaufbau sind. Es würde die Pflege erleichtern.

>
> Diese ganzen Fallunterscheidungen für die jeweiligen µCs stören mich
> zunehmend im Source. Ich überlege, den ganzen µC-spezifischen Kram aus
> IRMP und IRSND rauszuwerfen und das Ganze anders zu lösen, nämlich zum
> Beispiel folgendermaßen für irmp:
>
>  - Die ISR aus main.c liest den PIN aus.
>  - Die Funktion irmp_ISR() bekommt den Zustand des Pins als Argument.
>
> Damit wäre irmp.c komplett hardware-unabhängig. Die Pin-Definitionen
> könnten aus irmpconfig.h dann komplett raus.

Ja, dann könnte man auch irmpconfig.h bei einem Upgrade blind 
austauschen. Andererseits muß man berücksichtigen, daß ein call evtl. 
teurer ist als eine Pinabfrage per Makro.


> Für die jeweiligen
> µC-Familien müsste jeweils ein spezifischens irmp-main-xxx.c erstellt
> werden.

Wenn man damit auskommt. Vielleicht sollte man dann auch das, was in
irmpextlog enthalten ist, in die main zu verschieben versuchen. Denn 
auch das ist ziemlich hardwareabhängig.

>
> Bei IRSND wird das etwas schwieriger, hier müssten Callback-Funktionen
> definiert werden:
>
>   - Initialisierung der PWM mit der gewünschten Frequenz
>   - Einschalten der PWM
>   - Abschalten der PWM
>
> Der ganze hardware-technische Kram käme dann ins irsnd-main-xxx.c.

Unter dem Aspekt, daß diese Callbacks nicht wirklich häufig aufgerufen 
werden, sollte das kein Problem sein.

>
>> In main_pic12f1840.c habe ich im Programmkopf der Testaufbau
>> und das Ergebnis ziemlich ausführlich kommentiert.
>
> Danke gefällt mir!

Fein. Anbei wie gesagt, der neue Inhalt von "pic". In "softuart_pic.h" 
habe ich den Kommentar verbessert, anders als dort in der Vorversion 
stand, funktioniert das auch mit 19200 baud.

>
> Viele Grüße,
>
> Frank
>
> P.S.
> Deine Änderungen sind bereits im SVN. Ich hoffe, ich habe nichts
> übersehen.

Bis auf die notwendige Korrektur in irmpconfig.h ist mir nichts 
aufgefallen. Die solltest Du aber auf jeden Fall auch in die 
anzupassende Vorlage übernehmen. Für diejenigen, die den Testaufbau mit 
dem 12F1840 nachstellen wollen, wären aber die passenden ????config.h im 
pic-Verzeichnis schon nützlich.

Jedenfalls läßt sich mit den Änderungen/Ergänzungen die aktuelle 
SVN-Version übersetzen und das Ergebnis läuft:
1
IRMP PIC 12F1840 1.9 ws
2
P 7 a=0x0015 c=0x000c f=0x00 (RC5)
3
P 7 a=0x0015 c=0x000c f=0x01 (RC5)
4
P 7 a=0x0015 c=0x000c f=0x00 (RC5)
5
P 7 a=0x0015 c=0x000c f=0x01 (RC5)
6
P 2 a=0xbf00 c=0x0014 f=0x00 (NEC)
7
P 2 a=0xbf00 c=0x0014 f=0x01 (NEC)
8
P 2 a=0xbf00 c=0x0014 f=0x00 (NEC)
9
. MX115OFF PR2 221


Soweit für den Moment.
Wolfgang

von Andreas G. (andy1024)


Lesenswert?

Hallo Ihr,


eine Frage hätte ich noch bezüglich IRMP.

Es funktioniert jetzt so wie es soll. Ich hab die Interrupt Frequenz auf 
15,17 KHz eingestellt, und wenn ich eine Taste auf meiner RC5 
Ferbedienung drücke wird auch in IRMP gesprungen. Ich hab das Protokoll 
aktiviert und ändere den Pegel an einem freien Portpin (RB1) während der 
IR Decoder an RB0 angeschlossen ist.

Meine Frage nun wie bekomme ich das Command word bzw das Adress word in 
unsigned char zerlegt so das ich mir anzeigen lassen kann. Die Anzeige 
Elektronik läuft.

if (irmp_get_data (&irmp_data))
        {
            LATB1 = 0;
            // ir signal decoded, do something here...
            // irmp_data.protocol is the protocol, see irmp.h
            // irmp_data.address is the address/manufacturer code of ir 
sender
            // irmp_data.command is the command code
            // irmp_protocol_names[irmp_data.protocol] is the protocol 
name (if enabled, see irmpconfig.h)
            printf("proto %d addr %d cmd %d\n", irmp_data.protocol, 
irmp_data.address, irmp_data.command );
            irmp_data.address = i_rc5_adr;
            irmp_data.command = i_rc5_comm;
            h_rc5_adr = i_rc5_adr & 0xFF;
            l_rc5_adr = ((i_rc5_adr<<8)&0xFE) | l_rc5_adr;
            CS0 = 0;
            spi_write_word(0x23,0x30+l_rc5_adr);
            CS0 = 1;
            CS1 = 0;
            spi_write_word(0x23,0x30+h_rc5_adr);
            CS1 = 1;
            LATB1 = 1;
        }

So funktioniert es leider nicht.

Gruß
Andreas

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Andreas Geissler schrieb:
> Meine Frage nun wie bekomme ich das Command word bzw das Adress word in
> unsigned char zerlegt so das ich mir anzeigen lassen kann. Die Anzeige
> Elektronik läuft.

Ich weiß leider nicht, was Du für eine Anzeige verwendest. Den printf- 
bzw. sprintf-Befehl kannst Du dafür nicht verwenden? Wenn nicht, warum 
steht er dann da?

Wird die Anzeige über SPI angesprochen?

Ich habe mir mal Deinen Code dazu angeschaut:
1
>             irmp_data.address = i_rc5_adr;
2
>             irmp_data.command = i_rc5_comm;

Das verstehe ich nicht. Addrese und Kommando stehen in irmp_data.address 
und irmp_data.command nach dem irmp_get_data() und nun überschreibst Du 
sie wieder?

Das müsste eher umgekehrt lauten:
1
            i_rc5_adr = irmp_data.address;
2
            i_rc5_comm = irmp_data.command;

>             h_rc5_adr = i_rc5_adr & 0xFF;
>             l_rc5_adr = ((i_rc5_adr<<8)&0xFE) | l_rc5_adr;

Das verstehe ich ebenso nicht nicht. Wenn Du die adr in zwei Bytes 
splitten willst, dann bitte so:
1
              h_rc5_adr = i_rc5_adr >> 8;          // high word
2
              l_rc5_adr = i_rc5_adr & 0xFF;        // low word

Dassselbe gilt für das Kommando.

Ich nehme mal an, dass das Display Characters und keine "rohen" 
Binärdaten möchte. Deshalb musst Du nun die Bytes konvertieren, z.B. 
nach Hex:

Eine Möglichkeite wäre:
1
// Konvertierung eine Nibbles
2
uint8_t
3
itox (uint8_t val)
4
{
5
    uint8_t rtc;
6
7
    val &= 0x0F;
8
9
    if (val <= 9)
10
    {
11
        rtc = val + '0';
12
    }
13
    else
14
    {
15
        rtc = val - 10 + 'A';
16
    }
17
    return (rtc);
18
}
19
20
// Konvertierung eines Bytes
21
void
22
itoxx (unsigned char * xx, unsigned char i)
23
{
24
    *xx++ = itox (i >> 4);
25
    *xx++ = itox (i & 0x0F);
26
}

Dann:
1
  unsigned char adr_buf[5];
2
3
  itoxx (buf, h_rc5_adr);         // high byte
4
  itoxx (buf + 2, l_rc5_adr);     // low byte
5
  buf[4] = '\0';                  // terminieren

Nun Hast Du die Adresse in einen C-String umgewandelt. Wie Du Strings 
auf Deiner Anzeige ausgibst, weißt Du ja bestimmt. Dasselbe kannst Du 
mit dem Kommando-Word machen.

Wenn Du sprintf() zur Verfügung hast, geht das alles viel kürzer:

  unsigned char adr_buf[5];

  sprintf (adr_buf, "%04x", i_rc5_adr);

Die meisten (s)printf()-Implementationen (falls überhaupt vorhhanden) 
verbrauchen jedoch für µCs ziemlich viel Flash. Daher kann der Umweg 
über die Funktion itoxx() wesentlich speicherschonender sein.

Leider kann ich dazu nicht mehr sagen, weil ich mich mit PICs so gut wie 
gar nicht auskenne.

Viele Grüße,

Frank

: Bearbeitet durch Moderator
von Andreas G. (andy1024)


Lesenswert?

Hallo Frank,


danke für die Antwort. Eigentlich sollte ich doch wissen wierum die 
Zuweisung in C geschrieben wir.


Ich hab hier ein selbst gebautes Anzeigemodul mit 8 5x7 Punkten die über 
2 Maxim Bausteine über SPI angesprochen werden. Am Anfang wollte ich nur 
kurz mir die Adresse und Kommando von RC5 anzeigen lassen...


Danke nochmals für alles.

Andreas

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.