ben nu al een hele week aan het sukkelen hiermeer, uren in code zitten kijken en ik kijk er volgens mij over.
de code is werkende op een arduino, maar op een ESP wil het niet werken.
het betreffende deel is
uint32_t t1Hour[] = {0x8FC3, 0x800061, 0xD009000, 0xD0};
IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1650, 550, 550, &t1Hour[0], 104, PROTOCOL_IS_LSB_FIRST, 0, 0);foutmelding
D:\esp8266\PROGS\libraries\Arduino-IRremote-master\src/IRSend.hpp:520:6: note: candidate expects 7 arguments, 12 provided
D:\esp8266\PROGS\ArgoAircoControlV5ESP\ArgoAircoControlV5ESP.ino: In function 'void Time1H()':
ArgoAircoControlV5ESP:62:125: error: no matching function for call to 'IRsend::sendPulseDistanceWidthFromArray(int, int, int, int, int, int, int, uint32_t*, int, int, int, int)'
62 | IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1650, 550, 550, &t1Hour[0], 104, PROTOCOL_IS_LSB_FIRST, 0, 0);
| ^
als ik echter de in de source ga kijken (https://github.com/Arduino-IRremote/Arduino-IRremote) dan is die laatste constructor toch diegene die ik gebruik (tussen de 2 rijen met sterretjes), met 12 variabelen. (eerste is 13, 2de is 7, 3de is 12).
de code met deze librarie doet het wel op arduino, dus ergens is de compiler voor ESP anders waardoor die het niet aanvaard
void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros,
uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit,
uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) {
uint8_t tFlags = 0;
if (aMSBFirst) {
tFlags = PROTOCOL_IS_MSB_FIRST;
}
(void) aSendStopBit;
sendPulseDistanceWidthFromArray(aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros,
aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, tFlags, aRepeatPeriodMillis, aNumberOfRepeats);
}
void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo,
IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis,
int_fast8_t aNumberOfRepeats) {
sendPulseDistanceWidthFromArray(aFrequencyKHz, aDistanceWidthTimingInfo->HeaderMarkMicros,
aDistanceWidthTimingInfo->HeaderSpaceMicros, aDistanceWidthTimingInfo->OneMarkMicros,
aDistanceWidthTimingInfo->OneSpaceMicros, aDistanceWidthTimingInfo->ZeroMarkMicros,
aDistanceWidthTimingInfo->ZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, aFlags, aRepeatPeriodMillis,
aNumberOfRepeats);
}
******************************************
void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros,
uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis,
int_fast8_t aNumberOfRepeats) {
******************************************
// Set IR carrier frequency
enableIROut(aFrequencyKHz);
uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
uint_fast8_t tNumberOf32Or64BitChunks = ((aNumberOfBits - 1) / BITS_IN_RAW_DATA_TYPE) + 1;Er wordt nogal gegoogeld hiet met types. uint_fast8_t bijv, en uint16_t. En die uint32_t moet eigenlijk een 'IRRawDataType' zijn.
Terwijl de code alleen maar getallen geeft zoals 38, 8900, enz.
De compiler ziet die getallen als integers en moet dus gaat vertalen naar uint_fast8_t en uint16_t. Dat gaat soms wel goed, soms ook niet. Dat hangt af van de afstand tussen het echte type en het te converteren type, maar ook van compiler instellingen. Bovendien is een int op een Arduino 16 bits (op sommige Arduino's toch), en op een ESP 32 bits.
Persoonlijk zou ik het zo nooit implementeren. Als je 12 parameters nodig hebt voor een funktie-call dan kan niemand ze meer uit elkaar houden. Dus dan is toch minstens een struct op zijn plaats. Maar ja, dat zal wel zo in de library zitten.
Je kunt wel een type toekennen aan de getallen, bijv mbv casts, of met achtervoegsels (suffix) zoals bijv 'u' voor unsigned en 'l' voor long.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
3 schijnbaar identieke functies met 7, 12 en 13 parameters. Wat een bende!
In mijn beleving heb je 3 parameters nodig: een pointer naar de data, de lengte van de data, en een pointer naar een struct met instellingen.
ik heb op het werk ook al eens alles in parameters gezet
uint_fast8_t a = 38;
uint16_t b = 8900;
uint16_t c = 4450;
uint16_t d = 550;
uint16_t e = 1650;
uint16_t f = 550;
uint16_t g = 550;
uint32_t t1Hour[] = {0x8FC3, 0x800061, 0xD009000, 0xD0};
uint16_t h = 104;
bool i = PROTOCOL_IS_LSB_FIRST;
uint16_t j = 0;
int_fast8_t k = 0
IrSender.sendPulseDistanceWidthFromArray(a, b, c, d, e, f, g, t1HOUR, h, i, j, k);maar ook dat werkte niet. (die uint32 wist ik niet hoe te vertalen)
die 2 regels code komt gewoon uit een ander example van dezelfde code. (simplereceiver.ino denk ik).
die zet je in een arduino, sluit IR ontvanger aan, richt afstandsbediening en dan krijg je in serial monitor die code.
uint32_t t1Hour[] = {0x8FC3, 0x800061, 0xD009000, 0xD0};
IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1650, 550, 550, &t1Hour[0], 104, PROTOCOL_IS_LSB_FIRST, 0, 0);
dan is het gewoon een kwestie van een ander code te schrijven waar je bovenstaande dan als instructie in zet.
werkt PRIMA op een nano, ontvangen als zenden. maar eens naar ESP is het hopeloos.
ik wil mijn airco via webbrowsers kunnen sturen, en een nano heeft geen internet.
ik zou de ESP als webserver kunnen zetten, en een nano de IR kunnen uitzenden en dan de data tussen beide versturen, maar dat is ook te gek aangezien beide het ook afzonderlijk zouden moeten kunnen.
nu draait het op een nano met ethernet shield, maarja hier heb ik dus netwerkkabel voor nodig en niet zomaar wifi(in bureau lukt het nog net).
de volgende versie zal mijn pelletkachel kunnen in en uitschakelen, en in de woonkamer is er geen netwerkbekabeling en moet het naar wifi.
Op vrijdag 21 maart 2025 21:52:21 schreef SparkyGSX:
3 schijnbaar identieke functies met 7, 12 en 13 parameters. Wat een bende!
word wel veel gedaan hoor, doe ik ook vaak. is dat niet gewon 'overloading'. heb dat veel moeten doen in java destijds.
je kan dan 1 programma gebruiken om iets met 3 variabelen te verwerken, maar evengoed met 10. die van 3 negeert dan 7 andere waardes of gebruikt default.
stel dat ik een programma hebt die html code genereert van een aantal sensoren.
void create_html(int temp1){
output = "<br>temperatuur1= " . temp1;
output = "<br>temperatuur2= N/A";
output = "<br>temperatuur3= N/A";
}
void create_html(int temp1, int temp2){
output = "<br>temperatuur1= " . temp1;
output = "<br>temperatuur2= " . temp2;
output = "<br>temperatuur3= N/A";
}
void create_html(int temp1, int temp2, int temp3){
output = "<br>temperatuur1= " . temp1;
output = "<br>temperatuur2= " . temp2;
output = "<br>temperatuur3= " . temp3;
}of je dan 1, 2 of 3 waardes hebt, je roept dezelfde functie op
create_html(30);
create_html(30, 35);
create_html(30, 35, 40);werken dus alle3
Ja, die create_html() is dan weer een voorbeeld waar het wel nuttig is inderdaad.
Even spitten in de sources gaf deze definitie: (IRremoteInt.h)
#if (__INT_WIDTH__ < 32)
typedef uint32_t IRRawDataType;
#define BITS_IN_RAW_DATA_TYPE 32
#else
typedef uint64_t IRRawDataType;
#define BITS_IN_RAW_DATA_TYPE 64
#endif
Dus het lijkt erop dat je inderdaad een uint32_t kunt gebruiken op een Atmel, maar op een ESP een uint64_t moet gebruiken. Nu krijg je een type mismatch en dus wordt die funktie geweigerd.
In het algemeen kun je best zorgen dat je de types gebruikt die in de funkties gevraagd worden. Hier dus 'IRRawDataType'
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Moet die "< 32" niet "<= 32" zijn?
@fcapri: ik weet wat overloading is, maar niemand gaat de volgorde van 12 verschillende parameters onthouden. Daarbij is een pointer naar een struct ook nog efficiënter dan alles steeds op de stack zetten, zeker als de inhoud van die struct toch nooit verandert.
Op vrijdag 21 maart 2025 23:46:40 schreef deKees:
Ja, die create_html() is dan weer een voorbeeld waar het wel nuttig is inderdaad.Even spitten in de sources gaf deze definitie: (IRremoteInt.h)
Dus het lijkt erop dat je inderdaad een uint32_t kunt gebruiken op een Atmel, maar op een ESP een uint64_t moet gebruiken. Nu krijg je een type mismatch en dus wordt die funktie geweigerd.
In het algemeen kun je best zorgen dat je de types gebruikt die in de funkties gevraagd worden. Hier dus 'IRRawDataType'
dat was het idd
gewoon die 32 naar 64 veranderd en compileert. zoek ik me de hele tijd suf achter mijn esp, vermoed ik dat ik hem vergeten ben op het werk. zal wachten worden tot maandag om te testen
ik zie in die code eigenlijk dat je een uint32 moet hebben als de data minder dan 32bits is, en een uint64 als het meer is. maar waarom is dat gelinkt aan de processor???
mijn data is toch nog altijd hetzelfde aantal bits? of spreekt die INT_WIDTH over het processor soort (32bit/64bit?).
want die uint32 heb ik als enige gewoon nooit veranderd, omdat de data daar zeker hetzelfde was
EricP
mét CE
Het zal wel een stukje uit het verleden zijn.
C ligt vrij dicht tegen assembly aan. De ene controller kan alleen 8-bit bewerkingen (en voor een 16-bit moet je zelf 2x 8 bits optellen met een carry), de volgende kan ondanks dat het een 8-bitter is wel een 16-bit add in 1x. En uiteraard kwamen daar iets later de controllers bij die ook 32 of 64 bits in 1x konden doen (waarbij '1x' vanuit het standpunt van de code klopper is). De 'int' werd (wordt) waarschijnlijk 'pas' gemaakt voor de controller.
Als je het specifiek wilt hebben, dan gebruik je dus bijvoorbeeld de uint_8, uint_16 of uint_32 (en er zal ook wel een 64-bit variant van bestaan). Voordeel is dat je op hogere niveau's in de code daar niet over na hoeft te denken, nadeel is dat wanneer je 'alles' als 64 bit zet je op een controller die max. 16 bit 'dingen' kan (let wel: dan kan ook prima een 8-bitter zijn), je nodeloos code aan het uitvoeren bent. Omgekeerd kan ik me voorstellen dat een compiler met een 16-bit op een controller die 32 bit operaties kan daar nog wat met masking kan uitvoeren (om naar die 16 bits te komen) - al hoewel ik daar ff geen concreet voorbeeld bij kan vinden.
Dus ja, veel code is portable. Maar dan moet je het ook wel zo schrijven en niet met 'een int is altijd 32 bits' ofzo...
[Bericht gewijzigd door EricP op (10%)]
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Op vrijdag 21 maart 2025 20:03:21 schreef deKees:
Persoonlijk zou ik het zo nooit implementeren. Als je 12 parameters nodig hebt voor een funktie-call dan kan niemand ze meer uit elkaar houden.
Inderdaad die lib is een bende als je zoiets doet. Als ik zoiets zie gaat het meteen de prullenbak in, troep, heeft het niet begrepen, deugt per definitie niet en nog meer gevloek wat je niet wilt weten.
Verdere posts hier terug geven hetzelfde commentaar.
Kortom, wegkieperen en zelf op nieuw maken van scratch op een fatsoenlijke manier.