(Fout)melding compiler

Arduino specifieke Software
Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

(Fout)melding compiler

Berichtdoor zuid » 04 Mei 2018, 09:27

Bij het compileren voor een ESP8266 met een schets gemaakt voor een MEGA krijg ik de volgende melding:
---------------------------------------------------------------------------------------
C:\Users\Nico\Documents\Documents\arduino-1.8.5\hardware\esp8266com\esp8266\libraries\Wire/Wire.h: In function 'int OV7670Read(int, byte*, int)':

C:\Users\Nico\Documents\Documents\arduino-1.8.5\hardware\esp8266com\esp8266\libraries\Wire/Wire.h:70:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int, int)

uint8_t requestFrom(int, int, int);

C:\Users\Nico\Documents\Documents\arduino-1.8.5\hardware\esp8266com\esp8266\libraries\Wire/Wire.h:64:12: note: candidate 2: size_t TwoWire::requestFrom(uint8_t, size_t, bool)

size_t requestFrom(uint8_t address, size_t size, bool sendStop);
----------------------------------------------------------------------------------
Kennelijk kan de compiler in de ESP8266 Wire.h geen eenduidige keuze maken.
Compileren voor MEGA geeft geen problemen,
Is dit een compiler probleem of is de Wire library voor de ESP8266 niet correct geprogrammeerd?

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: (Fout)melding compiler

Berichtdoor Koepel » 04 Mei 2018, 16:10

De definitie van de parameters van Wire.requestFrom() in de Arduino Wire library zijn blijkbaar net iets anders dan de Wire library van de EPS8266. En daar loopt de functie OV7670Read() tegen aan.

Hier zie je de 5 mogelijkheden die de Arduino Mega 2560 heeft: https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/libraries/Wire/src/Wire.h#L61.

Als je weet welke Wire library je gebruikt dan kun je opzoeken wat het verschil is. Als je weet welke OV7670 library je gebruikt, dan kun je opzoeken hoe de Wire.requestFrom() wordt aangeroepen in de functie OV7670Read().

Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

Re: (Fout)melding compiler

Berichtdoor zuid » 04 Mei 2018, 21:48

Het opzoeken is geen probleem. De oplossing daarna wel. Als de library volgens de compiler twee varianten heeft waar de compiler niet uit kan kiezen hoe zou ik de compiler dan moeten vertellen welke keuze hij zou moeten maken. Of denk je dank ik als een "waarschuwing" moet zien en dat de uiteindelijk gecompileerde code geen probleem zal geven?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: (Fout)melding compiler

Berichtdoor Koepel » 04 Mei 2018, 22:46

Meestal vertelt de compiler welke hij gekozen heeft.
Als de compiler echt geen keuze kan maken, dan zul je misschien de aanroep van Wire.requestFrom() in de functie OV7670Read() moeten aanpassen. Een cast naar (int) of (uint8_t) van een van de parameters is dan waarschijnlijk voldoende.

Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

Re: (Fout)melding compiler

Berichtdoor zuid » 05 Mei 2018, 06:33

Dank voor je antwoord. Ik ga het verder uitzoeken.

Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

Re: (Fout)melding compiler

Berichtdoor zuid » 08 Mei 2018, 07:08

Ook nadat ik e.e.a. verder heb uitgezocht denk ik toch dat er een probleem in de Wire library van de esp8622 zit.
Ik heb de volgende gegevens verzameld:
Standaard arduino wire (https://www.arduino.cc/en/Reference/WireRequestFrom)
Syntax
Wire.requestFrom(address, quantity)
Wire.requestFrom(address, quantity, stop)
Parameters
address: the 7-bit address of the device to request bytes from
quantity: the number of bytes to request
stop : boolean. true will send a stop message after the request, releasing the bus. false will continually send a restart after the request, keeping the connection active.
Returns
byte : the number of bytes returned from the slave device

Toevoeging/afwijking in beschrijving esp8266 (geen afwijking m.b.t. requestFrom)
I2C (Wire library) (http://arduino-esp8266.readthedocs.io/e ... re-library)
Wire library currently supports master mode up to approximately 450KHz.
Before using I2C, pins for SDA and SCL need to be set by calling Wire.begin(int sda, int scl), i.e. Wire.begin(0, 2) on ESP-01, else they default to pins 4(SDA) and 5(SCL).

De wire library (versie 2.4.1) geeft in de wire.h:
Code: Alles selecteren
    size_t requestFrom(uint8_t address, size_t size, bool sendStop);
    uint8_t requestFrom(uint8_t, uint8_t);
    uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
    uint8_t requestFrom(int, int);
    uint8_t requestFrom(int, int, int);

en in wire.cpp:
Code: Alles selecteren
  size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop){
  if(size > BUFFER_LENGTH){
    size = BUFFER_LENGTH;
  }
  size_t read = (twi_readFrom(address, rxBuffer, size, sendStop) == 0)?size:0;
  rxBufferIndex = 0;
  rxBufferLength = read;
  return read;
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop){
  return requestFrom(address, static_cast<size_t>(quantity), static_cast<bool>(sendStop));
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity){
  return requestFrom(address, static_cast<size_t>(quantity), true);
}

uint8_t TwoWire::requestFrom(int address, int quantity){
  return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity), true);
}

uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop){
  return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity), static_cast<bool>(sendStop));
}


Om de werking te testen ben ik uitgegaan van het voorbeeld in standaard Wire beschrijving. Alleen heb ik ook de derde parameter toegevoegd.
Test code:
Code: Alles selecteren
#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
 
  //Wire.requestFrom(2, 6);                // request 6 bytes from slave device #2            // v1 OK
  //Wire.requestFrom(2, 6, true);          // request 6 bytes from slave device #2            // v2
  //Wire.requestFrom(2, 6, (bool) 1 );      // request 6 bytes from slave device #2           // v3
  Wire.requestFrom(2, 6, (int) 1 );     // request 6 bytes from slave device #2             // v4 OK
 //Wire.requestFrom(2, 6, 1);          // request 6 bytes from slave device #2               // v5


  while(Wire.available())    // slave may send less than requested
  {
    char c = Wire.read();    // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}


In de code staan 5 varianten van de requestFrom. De 1e en de 4e geven geen fouten in de compiler,
De andere drie dus wel.
Als ik in wire.cpp kijk zou dat betekenen dat onderstaande optie nooit gebruikt kan worden.

size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop){
if(size > BUFFER_LENGTH){
size = BUFFER_LENGTH;
}
size_t read = (twi_readFrom(address, rxBuffer, size, sendStop) == 0)?size:0;
rxBufferIndex = 0;
rxBufferLength = read;
return read;
}

Of zie ik iets over het hoofd?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: (Fout)melding compiler

Berichtdoor Koepel » 08 Mei 2018, 13:17

De bedoeling is dat de derde parameter een bool is, dus 'true' of 'false'.
+1 punt voor de ESP8266 Wire library, 0 punten voor de officiële Arduino Wire library.

De tweede parameter beperken tot een byte met maximaal 255 is niet logisch. Een "size_t" is wel logisch.
+1 punt voor de ESP8266 Wire library, 0 punten voor de officiële Arduino Wire library.

Voor het I2C address hebben ze allebei een uint8_t, dus de 10-bit I2C address kan niet ondersteund worden. Dat is -1 punt voor beide.

Resultaat: De ESP8266 Wire library krijgt 1 punt van mij, en de officiële Arduino Wire library staat op -1 punten :o

Je kunt de aanroep van Wire.requestFrom() compatible maken door alles 'int' of alles 'uint8_t' te doen.

Een cijfer in de code is automatisch een 'int'. Een variabele kun je aanpassen.
Code: Alles selecteren
Wire.requestFrom(2, 6, 1);   // three times a 'int'
Wire.requestFrom( (int) 2, (int) 6, (int) 1);   // three times a 'int'
Wire.requestFrom( (int) address, (int) lengte, (int) true);


De officiële Arduino Wire library is nu eenmaal de standaard. De ESP8266 had zich daaraan aan moeten passen, ook al zit het niet logisch in elkaar.

Is het voldoende duidelijk ? Kun je nu de aanroep in OV7670Read() aanpassen ?

Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

Re: (Fout)melding compiler

Berichtdoor zuid » 08 Mei 2018, 18:05

Is het voldoende duidelijk ?
Bijna :)

Als ik het goed begrijp zou het volgende ook goed zijn:
Code: Alles selecteren
Wire.requestFrom((uint8_t)2, (size_t) 6, (bool) 1 );


De Compiler heeft er in ieder geval geen probleem mee.

Het resultaat is denk ik wel een andere functie, nl:
Code: Alles selecteren
size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop){
  if(size > BUFFER_LENGTH){
    size = BUFFER_LENGTH;
  }
  size_t read = (twi_readFrom(address, rxBuffer, size, sendStop) == 0)?size:0;
  rxBufferIndex = 0;
  rxBufferLength = read;
  return read;
}


Bij 3x (int)
Code: Alles selecteren
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop){
  return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity), static_cast<bool>(sendStop));
}


Ik mis dus tenminste een volledige beschrijving van de esp Wire library.

Kun je nu de aanroep in OV7670Read() aanpassen ?


De oplossing hier is uitgaande van de 3x (int) eigenlijk nog eenvoudiger.
De waarde 1 (true) is de default waarde, de derde parameter zou dus gewoon weggelaten kunnen worden.
Code: Alles selecteren
uint8_t TwoWire::requestFrom(int address, int quantity){
  return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity), true);
}


m.v.g.
Nico

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: abibitehoaqic en 19 gasten