Sida 6 av 10
Re: Blandade C++ frågor, nybörjarnivå
Postat: 18 februari 2016, 22:40:44
av baron3d
eller
Kod: Markera allt
for( i = 1; i>0; i<<1) {
if(tmpBuffer & i) {
...
}
}
Re: Blandade C++ frågor, nybörjarnivå
Postat: 19 februari 2016, 15:36:36
av Magnus_K
Oj, ja gnid salt i såret bara
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
Re: Blandade C++ frågor, nybörjarnivå
Postat: 19 februari 2016, 16:20:20
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'?

Re: Blandade C++ frågor, nybörjarnivå
Postat: 19 februari 2016, 16:31:45
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.
Re: Blandade C++ frågor, nybörjarnivå
Postat: 19 februari 2016, 16:45:03
av sodjan
"Få igång" !? Det är väl bara att kompilera och ladda koden...
Tar väl inte många minuter...

Trevlig helg!
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 01:22:46
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
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 01:34:32
av Magnus_K
Jooo, den var nog lite konstig också; för det fungerade inte som jag ville där
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.
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;
}
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 01:44:10
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
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 01:49:53
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!
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 12:22:07
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.
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 12:55:28
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.
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 13:36:53
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) {
...
}
}
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 13:46:20
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.
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 14:00:38
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?
Re: Blandade C++ frågor, nybörjarnivå
Postat: 20 februari 2016, 14:02:16
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.