Blandade C++ frågor, nybörjarnivå

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1353
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av baron3d »

eller

Kod: Markera allt

for( i = 1; i>0; i<<1) {
  
   if(tmpBuffer & i) {
      ...
   }
}
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Oj, ja gnid salt i såret bara :wink:

Vad tror ni om nedan? Jag har gjort ett litet program som ska blinka en LED enligt det bifogade schemat. DIP-switchen styr antal 1s-blink den ska göra innan det "rullar runt" med en 3s paus.
Observera, det bifogade programmet kompilerar men fungerar inte. Ska jobba mer med det ikväll men det jag frågar efter är om det verkligen inte finns något smidigare sätt att göra för att få önskad effekt?
Det känns som otroligt mycket kod för en sån här "enkel" uppgift.

Tyvärr ska fler saker byggas på men jag måste börja så här för att ha en grund att jobba på.

Tack på förhand!
DSC_3050.jpg

Kod: Markera allt

void setup() {

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(10, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);

  digitalWrite(10, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);
  digitalWrite(A5, HIGH);
  
}



uint8_t doTimingMachines(uint32_t tmpOnTime, uint32_t tmpOffTime, uint32_t tmpRollOver, uint8_t tmpmachineCounter) {

  uint8_t machineStops = digitalRead(19 + 18 + 17 + 16);

  static uint8_t displayOn;
  uint32_t currentMillis = millis();
  static uint32_t previousMillis;
  
  if((displayOn == 0) && (machineStops - tmpmachineCounter) >= 1 ) {

    
    if (currentMillis - previousMillis < tmpOffTime) {
      
      previousMillis = currentMillis;
      
    } else {
      displayOn = 1;
      PORTD |= (1 << PD3);      
      tmpmachineCounter++;
    }
  }
  
  if((displayOn == 0) && (machineStops - tmpmachineCounter) <= 0 ) {
    
    if (currentMillis - previousMillis < tmpRollOver) {
      
      previousMillis = currentMillis;
      
      } else {
      displayOn = 1;
      PORTD |= (1 << PD3);
      tmpmachineCounter = 0;
    }
  }
  
  if(displayOn == 1) {
    
    if (currentMillis - previousMillis < tmpOnTime) {
      
      previousMillis = currentMillis;
      } else {
      displayOn = 0;
      PORTD &= ~(1 << PD3);
    }   
  }
  return (machineStops - tmpmachineCounter); 
}
int i;

void loop() {

  while(1) {
    
    i = (doTimingMachines(1000, 1000, 3000, i));
  }

}
DSC_3048.jpg
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Icecap »

Har du aktiverat någon pull-up för DIP-switch-ingångarna?

Eller räknar du med att när switchen inte kortslutar till GND lyfter den på något magisk sätt till en '1'? ;-)
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Hehe. Det ska vara i sin ordning. Genom att skriva HIGH till en ingång så aktiverar pull-up:en.

Programmet i sig kan jag nog få igång men det måste gå att göra smidigare.
Jag vill skicka tiderna mellan loopen och funktionen men sen sättet att räkna och tända/släcka känns onödigt överarbetat.

Ville bara höra mig för innan jag viger kvällen åt att få igång det här.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av sodjan »

"Få igång" !? Det är väl bara att kompilera och ladda koden...
Tar väl inte många minuter... :-)
Trevlig helg!
Användarvisningsbild
adent
Inlägg: 4245
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av adent »

Jag tycker det ser lite konstigt ut. Hade jag haft bättre koll på Arduinomiljön kunde du nog få bättre hjälp :/

Vad gör den här raden? uint8_t machineStops = digitalRead(19 + 18 + 17 + 16);

Utan att ha ägnat allt för mycket tanke så tycker jag din i-variabel inte behöver lämna funktionen, används
den bara där så låt den bo där. Behöver du komma ihåg den mellan funktionsanrop så gör den static som nämnts tidigare.

MVH: Mikael
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Jooo, den var nog lite konstig också; för det fungerade inte som jag ville där :wink:
Min tanke var att jag skulle läsa av ingångarna 19, 18, 17 och 16 och samtidigt slå ihop resultatet.

Har spenderat en bra del av kvällen till att göra om en del, och nu ser funktionen ut som nedan. Den kompilerar och fungerar som tänkt.
Tyvärr är jag just nu är jag i en transaktionsfas mellan mitt "testprogram" och det skarpa programmet så "DIP-switchen" är borttagen m.m. men just timing-delen verkar bete sig klockrent.
Bestämde mig också för att deklarera alla tider som konstanter istället för parametrar som skickas till funktionen.

Ledsen om det är lite rörigt men jag skulle nog aldrig gjort inlägget ovan. Det blir så översiktligt och lättläst för mig, men jag kan inte förvänta mig att någon annan ska förstå vad jag håller på med.
Vi kan ignorera ovan fråga och så ska jag försöka återkomma med något mer konkret istället. :tumupp:

Kod: Markera allt

const uint32_t MACHINE_ON_TIME = 1000;
const uint32_t MACHINE_OFF_TIME = 1000;
const uint32_t MACHINE_R_O_TIME = 3000;

uint8_t doTimingMachines() {
	
	machineStops = 3;                          // ta in ethernetbuffern här
	uint32_t currentMillis = millis();
	static uint32_t previousMillis;
	
	
	if(displayOn && (currentMillis - previousMillis > MACHINE_ON_TIME)) {

		previousMillis = currentMillis;
		PORTD &= ~(1 << PD3);
		displayOn = 0;
		Counter++;
	}

	
	else if(!displayOn && (currentMillis - previousMillis > MACHINE_OFF_TIME) && ((machineStops - Counter) >= 1)) {

		previousMillis = currentMillis;
		PORTD |= (1 << PD3);
		displayOn = 1;
	}

	else if(!displayOn && (currentMillis - previousMillis > MACHINE_R_O_TIME) && ((machineStops - Counter) == 0)) {

		previousMillis = currentMillis;
		PORTD |= (1 << PD3);
		displayOn = 1;
		Counter = 0;
	}

	
	return 0;
}
Användarvisningsbild
adent
Inlägg: 4245
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av adent »

Ah!

Men då var det nog lite fel. Beräkningar görs innan funktionsanropet så:

foobar(45);

och

foobar(12+12+1+24-4);

Gör samma sak (om jag räknade rätt på den sista). Men det kansk

Men om du inte bryr dig om vilken knapp som är intryckt (eller bara antalet valda knappar)
så kan man kanske göra typ foo = digitalread(1) + digitalread(2) + digitalread(7);

Förutsatt att de returnerar 1 eller 0.



MVH: Mikael
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Ahaa, så skulle jag ha gjort. Fasen vad självklart det blir när någon berättar för en.
Försökte flera olika varianter men trodde till slut att jag gjorde något fel med ingångsläsningen och gav upp och gav variabeln ett direkt värde för att kunna gå vidare.

Tack för hjälpen adent!
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av sodjan »

> och samtidigt slå ihop resultatet.

Vad menar du med att "slå ihop"? Du har 4 digitala ingångar
som kan vara "hög" eller "låg". Med "slå ihop" skulle man lika
gärna kunna avse t.ex. "1110" som 3.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

För detta test så skulle antal "aktiva" ingångar adderas.
Så om två dip-brytare var dragna till jord så var resultatet tänkt att bli 0b00000010, med en invertering.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Ny fråga:

Vet en funktion vad som har anropat den?

I funktionen nedan så tänkte jag att jag skickar över en parameter så att funktionen sen kan utföra olika saker beroende på vem anroparen är.
Finns det något annat sätt?

Kod: Markera allt

void doSomething(uint8_t tmpcaller) {
	
	if(tmpcaller == nail) {
		...
	}
	else if(tmpcaller == screw) {
		...
	}
	else if(tmpcaller == nut) {
		...
	}
	
}
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Icecap »

Självklart inte. En funktion är en funktion och den gör det den ska.
Och varför skulle den veta vem som kallar den? Skulle man göra en sådan funktion blir det ett rent helvete att debugga.
Användarvisningsbild
Jan Almqvist
Inlägg: 1652
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Jan Almqvist »

Magnus_K skrev: Vet en funktion vad som har anropat den?
Det beror på, det är väl inte helt ovanligt att man skickar med vem som anropar som en parameter?

Kod: Markera allt

void someFunction( CObject *sender );
Mr Andersson
Inlägg: 1409
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Mr Andersson »

> Finns det något annat sätt?
Det är ju bara skicka med ett argument till funktionen. T.ex.

Kod: Markera allt

void doSomething(uint8_t tmpcaller) {   
    if(tmpcaller == nail) {
        ...
    }
    else if(tmpcaller == screw) {
        ...
    }
    else if(tmpcaller == nut) {
        ...
    } 
}

void doNail()
{
    doSomething(nail);
}
void doScrew()
{
    doSomething(screw);
}
...
Där nail/screw/nut är enumvärden eller konstanter.
Alternativt gör doSomething() till en privat klassmetod och ha bara de argumentslösa doXXX() publika om du inte vill att användaren ska anropa doSomething direkt.

Edit:
I och för sig behöver man inte ens använda klassmetoder. Lägg alla doXXX-funktioner i en egen TU och gör doSomething static.
Skriv svar