Go Down

Topic: i2c grote variable (Read 230 times) previous topic - next topic

superpeter

hallo allemaal
ik ben met een nog al complex bauw project bezig.
waarin onder meer gebruik ge maakt word van i2c communicatie en grotere getallen.
nu loop ik egter beetje vast.
laat ik eerst maar even het programa nu neer knallen voor zover ik het nu heb
Code: [Select]

#include <Wire.h>
 
#define SLAVE_ADDRESS 0x04
int number = 0;
int numberb = 0;
int nummer = 0;
int state = 0;
int amperea = 0;
double ampere;
 
void setup() {
 pinMode(13, OUTPUT);
 
 // initialize i2c as slave
 Wire.begin(SLAVE_ADDRESS);
 
 // define callbacks for i2c communication
 Wire.onReceive(receiveData);
 Wire.onRequest(sendData);
 // serial data snelhijd
 Serial.begin(9600);
}
 
void loop() {
 // serial print
 Serial.println(number);
 Serial.print("     ");
 Serial.print(numberb);
  Serial.print("     ");
 Serial.print(state);
  Serial.print("     "); 
 Serial.print(amperea);
  Serial.print("     ");
 Serial.print(ampere);
  Serial.print("     ");
  Serial.print(amperea);

// delay(100);
 ampere = Getampere();
}
 
// callback for received data
void receiveData(int byteCount){
 
 while(Wire.available()) {
  number = Wire.read();
 
  if (number == 10000){
   if (state == 0){
    digitalWrite(13, HIGH); // set the LED on
    numberb = 1;
    state = 1;
   } else{
    digitalWrite(13, LOW); // set the LED off
    state = 0;
    numberb = 0;
   }
  }
  else if (number == 20000){
    numberb = ampere;
  }
 }
}
 
// callback for sending data
void sendData(){
 Wire.write(numberb);
}
 
// Get the internal ampereerature of the arduino
double Getampere(void)
{
 unsigned int wADC;
 double t;
 ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
 ADCSRA |= _BV(ADEN); // enable the ADC
 //delay(20); // wait for voltages to become stable.
 ADCSRA |= _BV(ADSC); // Start the ADC
 while (bit_is_set(ADCSRA,ADSC));
 wADC = ADCW;
 t = (wADC - 324.31 ) / 1.22;
 return (t);
}


nu wil ik voor reseave en send hogere nummers kunnen gebruiken dan 1024 en dit zelfde geld ook voor zenden.
men vraag is nu wat moet ik aan passen om ook getallen boven de 1024 te kunnen gebruiken in de variable nuber en numberb?
hopelijk kan / wil iemand me hier mee helpen
groeten: peter

MAS3

Hoi superpeter.

Ik heb eerst 10 minuten zitten zoeken naar wat je vraag nou eigenlijk is.
Want op het eerste gezicht is er niets wat die waardes beperkt tot het getal 1024.
Totdat ik de code eens een paar keer overgekeken had, en zag dat het ding op een bepaalde manier het stroomverbruik van de Arduino zelf moet meten, en daarbij de interne ADC gebruikt.
En daar ligt je probleem.
Want de ADC is 10 bits, en daarmee beperkt tot 1024 mogelijke waardes, inclusief de waarde nul en daarmee is de maximale waarde 1023.
Dan is het standaard antwoord, dat je hiervoor een externe ADC gebruikt, die meer dan 10 bits is.
Maar dat is voor deze meting niet mogelijk.

In het laatste stukje van je code word deze meting gedaan.
Dat is de functie Getampere().
In het commentaar dat er vlak voor staat, word dit "ampereerature" genoemd.
Ik dacht eerst dat dat een foutje was, maar dat is het toch niet.
Want in die functie zit een berekening (t = (wADC - 324.31 ) / 1.22), die mij doet denken aan een conversie van een bepaald systeem naar een ander systeem (bijvoorbeeld Fahrenheit naar Celsius, maar dat is het in ieder geval niet).
Ik vermoed dat de stroom word gemeten aan de hand van een bepaalde temperatuur in de controller, maar die truc kende ik nog niet.
Dat het resultaat vervolgens 't' word genoemd versterkt dit vermoeden alleen maar.
Maar het verklaart de vreemde beschrijving wel.
Omdat je dus iets gaat meten in de chip zelf, kun je dat niet met een externe ADC uitvoeren.

Dus helaas ziet het er naar uit dat wat jij wil, niet mogelijk is.

De trucs die met de ADC worden uitgehaald, zijn mij onbekend.
Wellicht kun je de bandbreedte wisselen door iets met de referentie te doen, ik zie wat van REFS1 en REFS0 voorbij komen.
Maar om daar een enigszins betrouwbare waarde uit te krijgen, moet je meerdere waardes ook meerdere malen meten, en vervolgens bewerken om het gemiddelde er uit te krijgen.
Das dus het gemiddelde per waarde die je gemeten had.
Bewerken is dan vaak de hoogste en de laagste meetresultaten weggooien, de overige meetresultaten bij elkaar op te tellen en te delen door het aantal meetresultaten min 2 (omdat je er 2 had weggegooid).
Maar geen idee of je dat kunt doen, en of het werkelijk een betere meting met meer dan 10 bits resolutie zal opleveren.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

superpeter

als eerste heel erg bedankt voor de uitleg.
verder moet ik eerlijk zijn het is/was een kantenkraal script die eigenlijk de temperatuur zou moeten meten alleen ik heb de sensor vervangen door een ampere meter en de variable temp overal hernoemd naar ampere.
nu kan ik natuurlijk gewoon dat stukje er lomp uit slopen en eventuele verwijzingen naar dat laatste stukje ook weg halen.
kijken of hij dan wel wat meer met hoge getallen wil werken.
zodra dat dan werkt kan ik natuurlijk stukje toe gaan voegen die dood leuk op a0 kijkt in plaats van dat  stukje wat er nu staat.
en de waarde van a0 kan ik natuurlijk via een variabele late omrekenen naar het aantal ampere en dat gebruiken.
je zit dan niet meer met een meting die inter gebruikt word en je bent dan ook gelijk dat stukje code kwijt die ik zelf al nooit heb kunnen door gronde.


MAS3

Dat lost je probleem niet op.
Want daarmee heb je nog steeds de 10 bits ADC van de Arduino zelf.

Maar je kunt dit dus wel met een externe ADC doen; 12 bits zijn beschikbaar en dan heb je ineens 4096 mogelijke waarden.

Hoe is jouw Engels ?
Want Adafruit heeft daar wat van in hun arsenaal, en die zijn ook erg goed in uitleggen hoe je hun spullen kunt gebruiken.
Maar das dan wel in het Engels.
Erg kostbaar is dat spul niet, ongeveer een tientje dus dat is nog wel te overzien.
En het ding dat ik gezien heb is ook nog instelbaar voor verschillend sterke en soorten signalen.
Maar het werkt wel heel anders dan analogRead() dus.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

superpeter

helaas is men Engels redelijk.
verstaan gaat me redelijk af lezen kom ik ook vaak wel uit (eventueel met gebruik van google translate)

verder even wat extra technische achtergrond omtrent het projectje.
de master is namelijk ene raspbery pi 3.
de arduino die ik als slave gebruik is een arduino mega.
eventueel is communicatie via de serial/usb poort ook een bespreekbare optie.
verder de rede dat ik met grotere getallen wil werken is omdat ik geen optie gedacht kreeg om te zorgen dat ik de waarde ampere en tempratuur uit elkaar kan halen.
de oplossing die ik hiervoor bedacht had is dus de waarde van ampere te pakken en daarbij 2000 op te tellen.
dit zelfde wauw ik bij de tempratuur doen maar dan gene 2000 er bui op tellen maar 4000 en vervolgend aan de ontvangende kant kijken welk getal hij heeft en met een if regel het dan weer terug te gaan rekennen.
ik weet dat dit ene zeer amateuristische methode is.
ik ben echter een hobieist en weet dus niet alles.
daarom mag iedereen met goede oplossingen zich natuurlijk late horen.
eventueel meerdere verschillende variable verzenden is dus ook bespreek baar.
echter heb ik nog niet kunnen vinden hoe je via i2c meerdere variable kunt verzenden en hoe je dan aan de ontvangende kant ook zorgt dat hij weet of hij de tempratuur of het aantal ampere juist binnen krijgt.

overigens zit ik al typend nu te bedenken dat als ik 2 variable meteen naar elkaar kan verzenden en ontvangen dan kan je natuurlijk zeggen dat variable 1 een getal is bv1 voor temp en 2 voor ampere.
variable 2 is vervolgens de waarde van de betreffende sensor.
en dan zou je volgens mij 1024 sensors moeten kunnen hebben met elk een meet berijk van 1 tm 1024
ik weet niet of dit kan en of dit een goede optie is maar dat hoorgr ik van zelf denk ik wel

groeten: peter


MAS3

Hoi.

Je moet je helemaal niet verontschuldigen voor hoe je je probleem wil aanpakken.
Hoe je dat wil doen, is helemaal aan jou.
En ik heb wel vaker gezien dat op een dergelijke manier meerdere gegevens in 1 signaal worden gestopt.

Wanneer je meerdere waarden na elkaar wil verzenden, dan moet je er nog wel iets anders bij doen.
Want hoe weet je dat je aan de ontvangende kant de 1e gegevens binnen krijgt ?
Er zijn allerlei redenen te bedenken waardoor je niet in de pas loopt met zenden en ontvanger.
Je moet dan dus zorgen dat je op 1 of andere manier een seintje geeft dat je gaat beginnen met het verzenden van de data.
Dat kan door iets te verzenden dat je anders nooit over die lijn zou sturen.
Bijvoorbeeld 3 keer een nul achter elkaar, ik noem maar iets.

Eigenlijk zou je eens moeten kijken hoe arrays werken, want dat is een prima manier om gegevens op te halen en te verwerken.
Maar het is niet een ding dat je even onder de knie zal gaan krijgen, daar gaat wat tijd overheen.

Dit is de manier waarop ik hele zinnen binnenhaal bij een heel ander projectje.
De zinnen komen binnen als gewoon leesbare tekens, en ik kan geen andere / betere manier bedenken om dat te doen, dan dit.

Nick Gammon is voor mij een grote hulp geweest.
Die zit in Australië, en communiceert daarom in het Engels.
Maar als je hier op klikt, kom je op een pagina van hem uit waar hij uitlegt hoe er via I2C gecommuniceerd kan worden.
Daar staat niets in over een beperking van waardes tot 1023, want dat is er in werkelijkheid helemaal niet.
De beperking gaat een gigantisch veel groter getal geven, en is dan nog heel eenvoudig groter te krijgen.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

superpeter

weer heel erg bedankt voor de reactie.

ik ben in middels al wat aan het puzzelen ge weest.
en heel toevallig had ik al rekening ge houden met een unieke variable verzenden.
ik had namelijk bedacht om met 4 variable te werken
variable 1 is wie: ofwel wie verzend er waarbij de raspbary pi altijd de 1 verzend en de arduino altijd een 2.
en mochten er meer dingen bij komen krijgen die 3 4 5 enz.
variable 2 is waar.
dit is ook weer een uniek getal maar dan die van de ontvanger in dit geval ook weer raspbary 1 arduino 2 enz enz.
variable 3 is dan weer wat ofwel ook weer een getal waarbij bv: 1 temperatuur is 2 ampère om te zorgen dat je dus weet welke sensor.
en de laatste variable is dan de waarde van de betreffende sensor.
voor arduino lijkt het programma op het eerste gezicht ook te werken.
wel heb ik er nu een flinke puzzel bij ge kregen namelijk hoe zorg ik aan de raspbaby kant dat ik met meerdere variable kan werken.
maar goed daar moet ik gewoon nu op gaan puzelen.
want als de arduino wel 4 variable kent maar de raspbary niet dan weet je natuurlijk nooit 100% zeker dat het ook egt werkt.
dus daar ga ik de komende dagen op puzzelen.

en oja mocht iemand mee willen puzzelen voor de raspbary pi dan kan ik altijd ook dat programmaatje even posten echter heb ik dit nu nog niet gedaan omdat het uit eindelijk een arduino en geen raspbary pi forum is

Go Up