Electrokit Buggfix Plus
Aktuellt datum och tid: 03.35 2019-06-27

Alla tidsangivelser är UTC + 1 timme




Svara på tråd  [ 25 inlägg ]  Gå till sida Föregående  1, 2
Författare Meddelande
InläggPostat: 15.56 2019-04-15 
EF Sponsor
Användarvisningsbild

Blev medlem: 15.29 2005-05-10
Inlägg: 37519
Ort: Söderköping
Jag tolkar "position" som den plats i eeprom där du vill lagra dina värden. Eller är "position" något annat? Det kanske är just "position" som är dina värden?


Upp
 Profil  
 
InläggPostat: 15.58 2019-04-15 
Användarvisningsbild

Blev medlem: 14.52 2005-01-10
Inlägg: 23829
Ort: Aabenraa, Danmark
Och då får jag upprepa vad hur jag alltid gör:
Spara först en struct, jag kallar den oftast Config då jag använder den för att spara en massa inställningar i.
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
struct
  {
  float Position[2]; // Sådär, plats för 2 positioner
  } Config;
#define CONFIG_START 0


Nu ska detta sparas:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void Config_Save(void)
  {
  u_int16_t Ctr;
  for(Ctr = 0; Ctr < sizeof(Config); Ctr++)
    {
    EEPROM.put(Ctr + CONFIG_START, (u_int8_t)*((u_int8_t*)&Config + Ctr);
    }
  }

Och vad gör den då? Jo, den läser alla bytes som ingår i Config och sparar dom i EEPROM, byte för byte. Ändrar Config storlek är det lugnt, rutinen kör konsekvent med storleken som referens.

Men det ska ju hämtas också:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void Config_Load(void)
  {
  u_int16_t Ctr;
  for(Ctr = 0; Ctr < sizeof(Config); Ctr++)
    {
    EEPROM.get(Ctr + CONFIG_START, (u_int8_t)*((u_int8_t*)&Config + Ctr);
    }
  }

Samma sak men med get istället.
Omedelbart anser jag att raden egentligen sk vara:
(u_int8_t)*((u_int8_t*)&Config + Ctr) = EEPROM.get(Ctr + CONFIG_START, u_int8_t);
eller något liknande. En get-funktion svarar ju med värdet.

Men nåväl, när båda Config_Save() och Config_Load() fungerar är det bara att lägga in rät värde i Config.Position[0] och Config.Position[1] och anropa Config_Save().

Vid uppstart laddas Config in som första steg via Config_Load().


Upp
 Profil  
 
InläggPostat: 17.34 2019-04-15 

Blev medlem: 21.06 2011-01-29
Inlägg: 836
sodjan skrev:
Jag tror att han menar att, om du ska spara en 32-bit integer (4 bytes) så
sparar men just värdet 4 först, sedan integern i de följande fyra positionerna.
D.v.s. totalt fem positioner i EEPROM. Storlek och värde. Då kan man läsa
tillbaka den första positionen och veta hur mycket mer som ska läsas.

Men get/put i Arduino sköter ju det automatiskt eftersom dessa vet hur stor
plats de olika data typerna tar och skriver/läser rätt antal bytes.

Nej jag menar antal värden/positioner, inte antal bytes.
Som jag tolkar problembeskrivningen så kan det antingen vara 1 eller flera motorpositioner. Då måste man ju veta om man ska läsa en, två eller n ints.


Upp
 Profil  
 
InläggPostat: 11.50 2019-04-16 
Användarvisningsbild

Blev medlem: 05.43 2013-02-13
Inlägg: 379
Problemet löst!

Jag la till ett nytt namn för minne nr 2 och dessa rader kod:

Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)

long UserStopPulseCount2;

EEPROM.get(8, UserStopPulseCount2);



Då kunde jag använda mig av en ny positionssparning på precis samma sätt som första positionen vid namn UserStopPulseCount.
Har testat nu fram och tillbaka och det fungerar strålande.

:o


Upp
 Profil  
 
InläggPostat: 14.10 2019-04-16 
Användarvisningsbild

Blev medlem: 05.43 2013-02-13
Inlägg: 379
sodjan skrev:
Jag tolkar "position" som den plats i eeprom där du vill lagra dina värden. Eller är "position" något annat? Det kanske är just "position" som är dina värden?


Precis, just nu ligger det en position som är döpt till UserStopPulseCount och en annan döpt till UserStopPulseCount2


Upp
 Profil  
 
InläggPostat: 14.22 2019-04-16 
Användarvisningsbild

Blev medlem: 05.43 2013-02-13
Inlägg: 379
Icecap skrev:
Och då får jag upprepa vad hur jag alltid gör:
Spara först en struct, jag kallar den oftast Config då jag använder den för att spara en massa inställningar i.
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
struct
  {
  float Position[2]; // Sådär, plats för 2 positioner
  } Config;
#define CONFIG_START 0


Nu ska detta sparas:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void Config_Save(void)
  {
  u_int16_t Ctr;
  for(Ctr = 0; Ctr < sizeof(Config); Ctr++)
    {
    EEPROM.put(Ctr + CONFIG_START, (u_int8_t)*((u_int8_t*)&Config + Ctr);
    }
  }

Och vad gör den då? Jo, den läser alla bytes som ingår i Config och sparar dom i EEPROM, byte för byte. Ändrar Config storlek är det lugnt, rutinen kör konsekvent med storleken som referens.

Men det ska ju hämtas också:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void Config_Load(void)
  {
  u_int16_t Ctr;
  for(Ctr = 0; Ctr < sizeof(Config); Ctr++)
    {
    EEPROM.get(Ctr + CONFIG_START, (u_int8_t)*((u_int8_t*)&Config + Ctr);
    }
  }

Samma sak men med get istället.
Omedelbart anser jag att raden egentligen sk vara:
(u_int8_t)*((u_int8_t*)&Config + Ctr) = EEPROM.get(Ctr + CONFIG_START, u_int8_t);
eller något liknande. En get-funktion svarar ju med värdet.

Men nåväl, när båda Config_Save() och Config_Load() fungerar är det bara att lägga in rät värde i Config.Position[0] och Config.Position[1] och anropa Config_Save().

Vid uppstart laddas Config in som första steg via Config_Load().



Tjusigt! Tackar. Nu löste det sig endå med jättelite kod.
Men vad finns det för fördelar att lägga det i en "struct"?
Och lagrar denna kod positionerna permanent i minnet så att de är kvar även när man stängt av och satt på maskinen?


Upp
 Profil  
 
InläggPostat: 15.54 2019-04-16 
Användarvisningsbild

Blev medlem: 14.52 2005-01-10
Inlägg: 23829
Ort: Aabenraa, Danmark
Fördelen är dels att man i programmet kan se vilka data som hör till en viss block/funktion.
Dels att man - i det exempel jag angav - kan lägga till saker i struct'en/ändra befintliga i variabeltyp och/eller antal osv. och funktionerna jag ritade upp fungera lika bra för det utan manuell justering. Vill du ha 3 stopp på vägen är det bara att ändra antalet - och Config-blocket sparas likaväl utan vidare trim i den delen.

Med sizeof() får man antal bytes en datastorlek använder och vid att kapsla in en given datamängd i en struct{} ger sizeof() hela blockets storlek. Och gäller det om att spara inställningsdata är det bara att uppdatera data i blocket och spara blocket i sin helhet.

Funktionen kan även vara att stycka ihop en kommunikationsblock och skicka den. Blir det ändringar i definitionen av kommunikationsblocket ändras alla viktiga saker automatisk vid kompileringen - och du har ingen aning om hur många trubbel det har räddad mig ifrån under årens lopp.

Gör jag t.ex. en typedef av ett kommunikationsblock och inkluderar samma fil i t.ex. ett µC-program samt ett PC-program (båda C) är definitionen alltid identisk. Ändrar jag blocket är det bara att kompilera om och saken är biff.


Upp
 Profil  
 
InläggPostat: 16.23 2019-04-16 
Användarvisningsbild

Blev medlem: 09.27 2011-08-14
Inlägg: 1370
Bara påminner om att det är begränsad livslängd på eeprommet. Men om du slitit ut plats 0 och 1 finns ju resten kvar.
Nåt 100000-tal skrivningar är vad det inbyggda eepromet klarar.


Upp
 Profil  
 
InläggPostat: 08.30 2019-04-17 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9157
Ort: Alingsås
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
    val = digitalRead(PositionSavePin);    // Knapp som sparar position
    if (val == HIGH) {                     // Kollar om knappen är tryckt

Den delen av koden känns inte bra, tycker jag. DigitalRead är en funktion som läser in värdet från en ingång rakt av. Det betyder att om denna kod ligger i en loop som kör snabbt (=ofta) så kommer koden att utföras tusentals gånger - så länge du håller ner knappen.

Så istället för att kolla om en ingång är HIGH så bör du leta efter förändringar istället - från låg till hög. Då kommer inte koden att köras igen förrän du släppt upp knappen och sedan trycker ner den igen (om debouncingen fungerar).
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
val = digitalRead(PositionSavePin);
if  (oldval == LOW && val == HIGH) { ... do something ... }
oldval = val;


Men nu kanske inte val och oldval är särskilt smarta namn på variabler i ett program där det finns fler funktioner... val betyder ju bara "värde"... kanske button1 passar bättre?
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
button1val = digitalRead(BUTTON1);
if  (oldButton1val == LOW && button1val == HIGH) { ... do something ... }
oldButton1val = button1val ;


Upp
 Profil  
 
InläggPostat: 08.48 2019-04-17 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9157
Ort: Alingsås
Den här operationen kan göras bitvis också. Så om du har många knappar som ska läsas av och varje knapp är en bit på en port kan koden se ut så här:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
uint8_t buttons, old_buttons, buttons_pressed;

buttons = PINB; //läs in värden från åtta knappar från port B
buttons_pressed = !old_buttons & buttons; // bitvis kontroll om knapp blivit nedtryckt
old_buttons = buttons;

for (uint8_t i = 0; i<8; i++)
{
       if (buttons_pressed & (1<<i))  { ... do something ... } // button i is pressed?
}


Upp
 Profil  
 
Visa inlägg nyare än:  Sortera efter  
Svara på tråd  [ 25 inlägg ]  Gå till sida Föregående  1, 2

Alla tidsangivelser är UTC + 1 timme


Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 2 gäster


Du kan inte skapa nya trådar i denna kategori
Du kan inte svara på trådar i denna kategori
Du kan inte redigera dina inlägg i denna kategori
Du kan inte ta bort dina inlägg i denna kategori
Du kan inte bifoga filer i denna kategori

Sök efter:
Hoppa till:  
   
Drivs av phpBB® Forum Software © phpBB Group
Swedish translation by Peetra & phpBB Sweden © 2006-2010