1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | int PWM_Out = 64 ; int CounterValue = 1 ; int StepPin = 7 ; int DirPin = 8 ; int Mode = 3 ; int OnOff = 2 ; int Laser = 9 ; void setup ( ) { pinMode ( DirPin , INPUT_PULLUP ) ; pinMode ( StepPin , INPUT_PULLUP ) ; pinMode ( Mode , INPUT_PULLUP ) ; pinMode ( OnOff , INPUT_PULLUP ) ; analogWriteResolution ( 8 ) ; pinMode ( Laser , OUTPUT ) ; attachInterrupt ( digitalPinToInterrupt ( StepPin ) , Count , RISING ) ; attachInterrupt ( digitalPinToInterrupt ( DirPin ) , ChangeDir , CHANGE ) ; void loop ( ) { if ( digitalRead ( Mode ) == HIGH ) { if ( digitalRead ( OnOff ) == HIGH ) { PWM_Out = 254 ; } else { PWM_Out = 0 ; } } analogWrite ( Laser , PWM_Out ) ; void Count ( ) { PWM_Out = PWM_Out + CounterValue ; if ( PWM_Out > 254 ) { PWM_Out = 254 ; } if ( PWM_Out < 0 ) { PWM_Out = 0 ; } } void ChangeDir ( ) { CounterValue = 1 ; if ( digitalRead ( DirPin ) ) { CounterValue = -1 ; _ } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | int PWM_Out = 64; int tmpPWM_Out; int CounterValue = 1; int InHigh = 255; int InLow = 0; int OutputHigh = 128; int OutputLow = 64; int tmp1; int tmp2; float tmp3; int tmp4; float tmp5; // in - outputs int StepPin = 7; int DirPin = 8; int Mode = 3; int OnOff = 2; int ScaleOn = 5; int Laser = 9; void setup() { pinMode(DirPin, INPUT_PULLUP); pinMode(StepPin, INPUT_PULLUP); pinMode(Mode, INPUT_PULLUP); pinMode(OnOff, INPUT_PULLUP); pinMode(ScaleOn, INPUT_PULLUP); analogWriteResolution(8); pinMode(Laser, OUTPUT); // interrupts on de Step an Dir inputs // try to make it as fast as posible, because we don't want to miss steps // maybe the Dir input on a normal input is Better? attachInterrupt(digitalPinToInterrupt(StepPin), Count, RISING); attachInterrupt(digitalPinToInterrupt(DirPin), ChangeDir, CHANGE); } void loop() { if (digitalRead(Mode) == HIGH) // on/off mode on // if the On/Off mode is active, we are not sending step and Dir pulses // so Count and ChangeDir are never called { if (digitalRead(OnOff) == HIGH) // on off input { PWM_Out = 254; } else { PWM_Out = 0; } } if (digitalRead(ScaleOn) == HIGH) // Scale fubction on { // RealActualValue:=( ( ( OutputHigh - OutputLow ) / ( InHigh - InLow ) ) * (r_Raw-InLow)) + OutputLow; tmp1 = OutputHigh - OutputLow; // = 128 - 64 tmp2 = InHigh - InLow; // = 255-0 tmp3 = (float) tmp1 / (float) tmp2; tmp4 = PWM_Out - InLow; tmp5 = tmp3 * (float)tmp4; tmpPWM_Out = (int)tmp5 + OutputLow; } else // Scale fubction off { tmpPWM_Out = PWM_Out; } analogWrite(Laser, tmpPWM_Out); // real output to laser } void Count() { PWM_Out = PWM_Out + CounterValue; // step pulse input on the rising edges Interrupt if (PWM_Out > 254) { PWM_Out = 254; } if (PWM_Out < 0) { PWM_Out = 0; } } void ChangeDir() { CounterValue = 1; // Dir input if (digitalRead(DirPin)) { CounterValue = -1; } } |
Je kan de map functie gebruiken, of je kan gewoon de volgorde van je bewerkingen aanpassen: eerst de vermenigvuldiging uitvoeren, dan pas de deling: dan verlies je enkel de cijfers achter de komma.quote:Op donderdag 26 mei 2022 16:40 schreef Grote_Swets het volgende:
tmpPWM_Out = map(PWM_Out, 0, 255, OutputLow, OutputHigh);
vind net (online) de map fuctie... volgens mij doet dat het zelfde....
weet alleen niet of dat sneller is?
Ik heb nu het onderstaande: en in de simulator werkt het....quote:Op donderdag 26 mei 2022 17:47 schreef FlippingCoin het volgende:
Dus je hele vraagstuk komt neer op een functie die een 0...255 mapt naar een aantal pulsen die respondeert met een grijstint?
Wat gaat er nu mis? Om de snelheid van floating point arithmetics hoef je jezelf geen zorgen te maken lijkt mij, kan mij niet voorstellen dat dit de eventuele bottleneck zou vormen.
Heb je al een werkende versie gehad?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | int PWM_Out = 64; int tmpPWM_Out; int Direction = 1; int InHigh = 255; int InLow = 0; int OutputHigh; int OutputLow; // in - outputs int StepPin = 7; int DirPin = 8; int Mode = 3; int OnOff = 2; int ScaleOn = 5; int AnalogLow = A0; // potentiometer wiper (middle terminal) connected to analog pin 3 int AnalogHigh = A1; // potentiometer wiper (middle terminal) connected to analog pin 3 int Laser = 9; void setup() { pinMode(DirPin, INPUT_PULLUP); pinMode(StepPin, INPUT_PULLUP); pinMode(Mode, INPUT_PULLUP); pinMode(OnOff, INPUT_PULLUP); pinMode(ScaleOn, INPUT_PULLUP); analogWriteResolution(8); pinMode(Laser, OUTPUT); // interrupts on de Step an Dir inputs // try to make it as fast as posible, because we don't want to miss steps // maybe the Dir input on a normal input is Better? attachInterrupt(digitalPinToInterrupt(StepPin), Count, RISING); attachInterrupt(digitalPinToInterrupt(DirPin), ChangeDir, CHANGE); if (digitalRead(DirPin)) // Dir input { Direction = -1; } } void loop() { if (digitalRead(Mode) == HIGH) // on/off mode on // if the On/Off mode is active, we are not sending step and Dir pulses // so Count and ChangeDir are never called { if (digitalRead(OnOff) == HIGH) // on off input { PWM_Out = 255; } else { PWM_Out = 0; } } if (digitalRead(ScaleOn) == HIGH) // Scale fubction on { OutputLow = analogRead(AnalogLow) / 4; OutputHigh = analogRead(AnalogHigh) / 4; tmpPWM_Out = map(PWM_Out, 0, 255, OutputLow, OutputHigh); // scale wanted value between 2 potmeter setpoints.. } else // Scale fubction off { tmpPWM_Out = PWM_Out; } analogWrite(Laser, PWM_Out); // real output to laser } void Count() { PWM_Out = PWM_Out + Direction; // step pulse input on the rising edges Interrupt if (PWM_Out > 255) { PWM_Out = 255; } if (PWM_Out < 0) { PWM_Out = 0; } } void ChangeDir() { Direction = 1; // Dir input on a change interrupt if (digitalRead(DirPin)) { Direction = -1; } } |
Dus je grootste zorg is dat de CNC besturen sneller pulsen stuurt dan je arduino kan afhandelen? Dan zou je daar een buffer tussen kunnen plaatsen misschien.quote:Op donderdag 26 mei 2022 23:42 schreef Grote_Swets het volgende:
[..]
Ik heb nu het onderstaande: en in de simulator werkt het....
dus mach3 stuur dmv 2 outputs (step en dir) de PWM counter op en neer...
En via de map function ( toch wel makkelijk als mijn zelf gemaakt map fuctie, die het trouwens wel gewoon deed)
dus alles werkt....
maar wat er meer door mijn hoofd speelt, hoe snel is het allemaal....
ik wil eigenlijk niet, dat het verhaal pulsen gaat missen vanuit de CNC besturing...
Vandaar dat ik de Step/Dir input al op een interrupt heb zitten....
Het eerste verhaal, zonder de map, of mijn eigen gemaakte scale som , werkte goed...
.
Ik heb eigen geen idee hoe de arduino Due omgaat met dit soort funlties...
ik zou ook even moeten kijken hoesnel de pulsjes zijn van uit de CNC-controller, die hij bij moet houden...
maar dat zit toch wel ergens tussen de 35 a 75 K...
Dus de vraag is meer gaat hij het bijhouden... ?
[ code verwijderd ]
Ja het is ook zo maar kijken of ik een beter resultaat kan krijgen....quote:Op donderdag 26 mei 2022 21:33 schreef crystal_meth het volgende:
[..]
Je kan de map functie gebruiken, of je kan gewoon de volgorde van je bewerkingen aanpassen: eerst de vermenigvuldiging uitvoeren, dan pas de deling: dan verlies je enkel de cijfers achter de komma.
bvb: 49/50*60:
in float: 58.8, en daarna (int)58.8 ---> 58
als je het in integers uitrekent:
49/50*60 --> 0*60 ---> 0
49*60/50 --> 2940/50 ---> 58
Dat je een Due gebruikt maakt het makkelijker (die gebruikt vier bytes voor een int, meer dan genoeg)
tmp1 = OutputHigh - OutputLow; // = 128 - 64
tmp2 = PWM_Out - InLow;
tmp3 = tmp1 * tmp2;
tmp4 = InHigh - InLow; // = 255-0
tmp5 = tmp3 / tmp4;
tmpPWM_Out = tmp5 + OutputLow;
of simpelweg:
tmpPWM_Out= OutputLow + (OutputHigh - OutputLow) * (PWM_Out - InLow) / (InHigh - InLow);
Branden van grijswaarden op hout is lastig. Had zelf een laserbrander in elkaar geknutseld met delen van twee oude flatbed scanners, een arduino uno (met SD Card adapter) en een blauwe 1.8W laserdiode. De afbeelding stond op de SD card, en werd lijn per lijn geschreven (wat erg lang duurde).
Branden van tekst of zwart-wit tekeningen en patronen ging perfect, maar grijstinten...
Probleem is dat het hout (voor zichtbaar licht) niet overal even donker is, de lichtere delen reflecteren veel laserlicht, de donkere delen minder, die absorberen dus meer energie, waardoor ze sneller opwarmen en sneller verkolen. En eens ze verkolen (zwart worden) absorberen ze de energie bijna volledig, waardoor ze nog sterker opwarmen.
Bij "grijze" pixels was dat overduidelijk: iets lichter hout werd bij bvb 10 ms belichting slechts lichtgrijs, terwijl iets donkerder hout na 8 ms reeds zwart was.
Maw, de grijstinten versterkten vooral het contrast dat in het hout aanwezig was. Ander probleem was dat de lijnen iets overlapten (afstand tussen twee lijnen was 0.17 mm, maar een zwart gebrande lijn was iets breder dan 0.17 mm). Dus bij het branden van de volgende lijn was het hout op die plaatsen reeds donkerder dan elders en brandde dus veel sneller in.
Ik dacht dat ik het misschien kon verhelpen met feedback: had 2 fotodiodes (één voor zichtbaar licht, één voor infrarood, maw hitte) aan de laser bevestigd (gericht op het hout), om laserduur te bepalen op basis van de gemeten lichtsterkte (hoe hoger, hoe meer reflectei van de laser, hoe langer belichten) of hittestraling (laser stoppen wanneer een bepaalde waarde bereikt wordt) , maar heb er daarna niets meer mee gedaan (had enkele onderdelen voor een ander project nodig).
Misschien zou het met een infrarood laser beter gaan, ik kon nergens een absorptiespectrum van hout vinden maar best mogelijk dat infrarood veel minder gereflecteerd wordt.
Het is een processor op 84 MHz, 32-bit vermenigvuldiging neemt één clock cyclus in beslag, 32-bit deling is in hardware geimplementeerd. De hele berekening zou minder dan een microseconde in beslag moeten nemen, al hangt dat af van hoe de map functie geimplementeerd is (de meeste "Arduino functies" lijken veel meer tijd te nemen dan nodig).quote:Op donderdag 26 mei 2022 23:42 schreef Grote_Swets het volgende:
[..]
Ik heb nu het onderstaande: en in de simulator werkt het....
dus mach3 stuur dmv 2 outputs (step en dir) de PWM counter op en neer...
En via de map function ( toch wel makkelijker als mijn zelf gemaakt map functie, die het trouwens wel gewoon deed)
dus alles werkt....
maar wat er meer door mijn hoofd speelt, hoe snel is het allemaal....
ik wil eigenlijk niet, dat het verhaal pulsen gaat missen vanuit de CNC besturing...
Vandaar dat ik de Step/Dir input al op een interrupt heb zitten....
Het eerste verhaal, zonder de map, of mijn eigen gemaakte scale som , werkte goed...
.
Ik heb eigen geen idee hoe de arduino Due omgaat met dit soort funlties...
ik zou ook even moeten kijken hoesnel de pulsjes zijn van uit de CNC-controller, die hij bij moet houden...
maar dat zit toch wel ergens tussen de 35 a 75 K...
Dus de vraag is meer gaat hij het bijhouden... ?
[ code verwijderd ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | volatile int tmpPWM_Out; volatile int PWM_Out = 215; volatile int OutputLow = 64; volatile int OutputHigh = 255; void setup() { Serial.begin(9600); unsigned long tijd = micros(); for (long int i = 0; i < 100000; i++) { tmpPWM_Out = map(PWM_Out, 0, 255, OutputLow, OutputHigh); } Serial.println(micros() - tijd); } void loop() { } |
SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.De thread op arduino.cc[ heeft voorbeelden van het verhogen van de de ADCClock, het gebruik van de controller registers ipv de AnalogRead functie, en het inlezen van twee verschillende ADC kanalen (de microcontroller kan ingesteld worden om meerdere conversies na elkaar te doen, van verschillende pinnen).
De registers gebruiken is sneller dan de AnalogRead functie, want AnalogRead moet telkens alle nodige settings instellen voor het inlezen van één waarde van een specifieke pin, daarna de ADC opstarten, en wachten tot de conversie gedaan is. Met de registers moet je de settings slechts één keer instellen in setup() voor de pinnen die je wil inlezen, en na opstarten van de ADC kan het programma verder lopen, de waarden kan het later ophalen uit de registers. Je kan bovendien free running mode instellen, waarin de ADC de ingestelde pinnen steeds opnieuw zal samplen en converteren, dan moet je in loop() enkel de registers lezen waarin de resultaten van de conversie staan. Enkel wanneer de loop minder lang duurt dan 2 ADC conversies zal het programma moeten wachten tot de conversie beëindigd is.
Wat er precies gebeurd wanneer de ADC sneller is dan het programma weet ik niet precies, misschien pauzeert de ADC tot het programma de waarden opgevraagd heeft, of blijft ie runnen en overschrijft de waarden, dunno, maar die thread op arduino.cc lijkt genoeg info te bevatten (ik heb geen Due, heb het dus niet in detail bekeken).Ich glaube, dass es manchmal nicht genügend Steine gibt und
Ich bin mir sicher, dass auch schöne Augen weinen
Mooie snelheid, ik ben jaloers.quote:Op donderdag 26 mei 2022 23:58 schreef Grote_Swets het volgende:
[..]
Ja het is ook zo maar kijken of ik een beter resultaat kan krijgen....
[ afbeelding ]
Dit ziet er al beter uit, maar hier heb ik met Paintshop pro zelf de kleuren zitten verschuiven....
en je ziet wel de verschillende tinten....
maar onder die handen zie je een zwart rechthoek. maar dat rechthoek loopt links van zwart (laser op 255) naar rechts naar wit (laser op 0).
en daar zie je ook dat van wit naar zwart in een heel klein gebied zit..
dus ik wil een bitmap omzetten naar bijvoorbeeld 16 tinten grijs... en dat ik met 2 potmeters wat kan rommelen, en kan zien of ik dan bettere resultaten krijg....
Zwart/wit werkt perfect....
|
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |