Beste Tweakers,
Ik heb vandaag 2 vraagjes voor jullie, ze zijn misschien aardig simpel, maar ik kom er momenteel echt niet uit en werk met een deadline voor komende maandag. (Ach, scholen.)
Ik maak met wat anderen een kleine kas waarin we wat spinazie gaan laten groeien, we willen hierbij een waarde van 1300ppm CO2 hebben. Dit kunnen we natuurlijk aanvoeren door zoutzuur op marmer te druppelen. Maar dat deel is nu niet belangrijk, alleen hoe we dit doen: Met een spuit als de onderstaande, waar ik op het tandwiel een stappenmotor aan ga sluiten.
(Plaatje komt binnenkort!)
Eerst gooi ik maar eens wat code jullie kant op:
Dit is de code die ik momenteel op mijn Arduino laat draaien, een licht aangepaste versie van een standaardcode voor mijn CO2-sensor:
De volgende code is de code die ik gebruik om mijn stappenmotor aan te sturen, degene die werkt met mijn stappenmotortje. Ik heb overigens al mijn info en code van Bret Stateham, die twee geweldige video's heeft over de werking en het aansturen van de 28BYJ-48 stappenmotor met een ULN2003-driverboard. Hier kun je ook alle beschikbare code vinden, evenals door Bret Stateham.
Deze manuele code werkt perfect:
Maar deze code, waarbij hij de (jaja, door mij 100% zeker juist geïnstalleerde) AccelStepper library gebruikt, doet het dan weer niet:
Als ik deze code run beweegt het motortje afentoe een beetje. Het kan natuurlijk zijn dat het te snel gaat en de motor niet lang genoeg de tijd krijgt om naar de beoogde positie te gaan en daarom "freezed", maar ook als ik de speed of acceleration verander blijft dit probleem bestaan.
Ik heb eerder gezegd dat ik op basis van al het bovenstaande 2 hulpvragen heb.
Waarvan 1:
Ik wil afhankelijk van mijn sensorwaarde dat de stappenmotor naar links beweegt, ik wil dit doen wanneer de sensorwaarde onder de 1100 a 1200 PPM uitkomt. Ik kan een if-statement maken, maar de stappenmotor zelf aansturen vind ik nog aardig uitdagend, dus als er een held van een Tweaker is die me ermee kan helpen, zou dat superfijn zijn.
2:
Mijn tweede vraag is er eentje waar ik wel wat meer over gelezen heb, en toen ik voor het huidige project aan het werk was ook gezien heb.
Ik moet denk ik mijn delays gaan vervangen voor millis, want toen ik met de servo bezig was liep er (natuurlijk) een loop, en op het moment dat hij bij het deel van de servo aankwam, gingen de CO2-metingen niet door.
Naar wat ik ervan begrijp blijft je code bij een delay ook echt op dat stuk hangen en gebruikt het de gehele processor, waardoor de metingen niet doorgaan. Bij "millis" zou de processor onthouden hoelang hij een bepaald proces moet blijven uitvoeren en ondertussen doorgaan met het andere.
Als iemand me zou kunnen helpen, zou dat superfijn zijn. Ik kan 2 oplossingen heel erg waarderen: Leer het me of schrijf het bij in de code, die je hier kunt aanpassen.
Alvast bedankt mede-Tweakers!
Diego
PS: Kan een mod de topictitel veranderen? CO2 is duidelijk genoeg en de UBB doet het natuurlijk niet in de titel..
Ik heb vandaag 2 vraagjes voor jullie, ze zijn misschien aardig simpel, maar ik kom er momenteel echt niet uit en werk met een deadline voor komende maandag. (Ach, scholen.)
Ik maak met wat anderen een kleine kas waarin we wat spinazie gaan laten groeien, we willen hierbij een waarde van 1300ppm CO2 hebben. Dit kunnen we natuurlijk aanvoeren door zoutzuur op marmer te druppelen. Maar dat deel is nu niet belangrijk, alleen hoe we dit doen: Met een spuit als de onderstaande, waar ik op het tandwiel een stappenmotor aan ga sluiten.
(Plaatje komt binnenkort!)
Eerst gooi ik maar eens wat code jullie kant op:
Dit is de code die ik momenteel op mijn Arduino laat draaien, een licht aangepaste versie van een standaardcode voor mijn CO2-sensor:
code:
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
| #include <Wire.h> // Wire bibliotheek #include <LiquidCrystal_I2C.h> // I2C lCD bibliotheek LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // I2C adres /************************Hardware Related Macros************************************/ #define MG_PIN (0) //define which analog input channel you are going to use #define BOOL_PIN (2) #define DC_GAIN (8.5) //define the DC gain of amplifier /***********************Software Related Macros************************************/ #define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation #define READ_SAMPLE_TIMES (5) //define the time interval(in milisecond) between each samples in //normal operation /**********************Application Related Macros**********************************/ //These two values differ from sensor to sensor. user should derermine this value. #define ZERO_POINT_VOLTAGE (0.324) //define the output of the sensor in volts when the concentration of CO2 is 400PPM #define REACTION_VOLTGAE (0.020) //define the voltage drop of the sensor when move the sensor from air into 1000ppm CO2 /*****************************Globals***********************************************/ float CO2Curve[3] = {2.602,ZERO_POINT_VOLTAGE,(REACTION_VOLTGAE/(2.602-3))}; //two points are taken from the curve. //with these two points, a line is formed which is //"approximately equivalent" to the original curve. //data format:{ x, y, slope}; point1: (lg400, 0.324), point2: (lg4000, 0.280) //slope = ( reaction voltage ) / (log400 –log1000) void setup() { lcd.begin(16,2); // initialiseer de lcd voor 16 chars 2 line lcd.backlight(); // Zet de backlight aan pinMode(BOOL_PIN, INPUT); //set pin to input digitalWrite(BOOL_PIN, HIGH); //turn on pullup resistors Serial.print("MG-811 Demostration\n"); } void loop() { int percentage; float volts; volts = MGRead(MG_PIN); lcd.setCursor(0,0); lcd.print( "Voltage: " ); lcd.print(volts); lcd.print( "V " ); percentage = MGGetPercentage(volts,CO2Curve); lcd.setCursor(0,1); lcd.print("CO2: "); if (percentage == -1) { lcd.print( "<400" ); } else { lcd.print(percentage); } lcd.print( "ppm" ); delay(200); } /***************************** MGRead ********************************************* Input: mg_pin - analog channel Output: output of SEN-000007 Remarks: This function reads the output of SEN-000007 ************************************************************************************/ float MGRead(int mg_pin) { int i; float v=0; for (i=0;i<READ_SAMPLE_TIMES;i++) { v += analogRead(mg_pin); delay(READ_SAMPLE_INTERVAL); } v = (v/READ_SAMPLE_TIMES) *5/1024 ; return v; } /***************************** MQGetPercentage ********************************** Input: volts - SEN-000007 output measured in volts pcurve - pointer to the curve of the target gas Output: ppm of the target gas Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) of the line could be derived if y(MG-811 output) is provided. As it is a logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic value. ************************************************************************************/ int MGGetPercentage(float volts, float *pcurve) { if ((volts/DC_GAIN )>=ZERO_POINT_VOLTAGE) { return -1; } else { return pow(10, ((volts/DC_GAIN)-pcurve[1])/pcurve[2]+pcurve[0]); } } |
De volgende code is de code die ik gebruik om mijn stappenmotor aan te sturen, degene die werkt met mijn stappenmotortje. Ik heb overigens al mijn info en code van Bret Stateham, die twee geweldige video's heeft over de werking en het aansturen van de 28BYJ-48 stappenmotor met een ULN2003-driverboard. Hier kun je ook alle beschikbare code vinden, evenals door Bret Stateham.
Deze manuele code werkt perfect:
code:
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
105
106
107
108
| //Put all the pins in an array to make them easy to work with int pins[] { 2, //IN1 on the ULN2003 Board, BLUE end of the Blue/Yellow motor coil 3, //IN2 on the ULN2003 Board, PINK end of the Pink/Orange motor coil 4, //IN3 on the ULN2003 Board, YELLOW end of the Blue/Yellow motor coil 5 //IN4 on the ULN2003 Board, ORANGE end of the Pink/Orange motor coil }; //Define the wave drive sequence. //With the pin (coil) states as an array of arrays int waveStepCount = 4; int waveSteps[][4] = { {HIGH,LOW,LOW,LOW}, {LOW,HIGH,LOW,LOW}, {LOW,LOW,HIGH,LOW}, {LOW,LOW,LOW,HIGH} }; //Define the full step sequence. //With the pin (coil) states as an array of arrays int fullStepCount = 4; int fullSteps[][4] = { {HIGH,HIGH,LOW,LOW}, {LOW,HIGH,HIGH,LOW}, {LOW,LOW,HIGH,HIGH}, {HIGH,LOW,LOW,HIGH} }; //Keeps track of the current step. //We'll use a zero based index. int currentStep = 0; //Keeps track of the current direction //Relative to the face of the motor. //Clockwise (true) or Counterclockwise(false) //We'll default to clockwise bool clockwise = true; // How many steps to go before reversing, set to zero to not bounce. //int targetSteps = 0; //targetSteps 0 means the motor will just run in a single direction. int targetSteps = 2048; //2049 steps per rotation when wave or full stepping //int targetSteps = 4096; //4096 steps per rotation when half stepping void setup() { // put your setup code here, to run once: Serial.begin(9600); for(int pin = 0; pin < 4; pin++) { pinMode(pins[pin], OUTPUT); digitalWrite(pins[pin], LOW); } } void step(int steps[][4], int stepCount) { //Then we can figure out what our current step within the sequence from the overall current step //and the number of steps in the sequence int currentStepInSequence = currentStep % stepCount; //Figure out which step to use. If clock wise, it is the same is the current step //if not clockwise, we fire them in the reverse order... int directionStep = clockwise ? currentStepInSequence : (stepCount-1) - currentStepInSequence; //Set the four pins to their proper state for the current step in the sequence, //and for the current direction for(int pin=0; pin < 4; pin++){ digitalWrite(pins[pin],steps[directionStep][pin]); } } void loop() { //Comment out the Serial prints to speed things up //Serial.print("Step: "); //Serial.println(currentStep); //Get a local reference to the number of steps in the sequence //And call the step method to advance the motor in the proper direction //Wave Drive //int stepCount = waveStepCount; //step(waveSteps,waveStepCount); //Full Step int stepCount = fullStepCount; step(fullSteps,fullStepCount); // Increment the program field tracking the current step we are on ++currentStep; // If targetSteps has been specified, and we have reached // that number of steps, reset the currentStep, and reverse directions if(targetSteps != 0 && currentStep == targetSteps){ currentStep = 0; clockwise = !clockwise; } else if(targetSteps == 0 && currentStep == stepCount) { // don't reverse direction, just reset the currentStep to 0 // resetting this will prevent currentStep from // eventually overflowing the int variable it is stored in. currentStep = 0; } //2000 microseconds, or 2 milliseconds seems to be //about the shortest delay that is usable. Anything //lower and the motor starts to freeze. //delayMicroseconds(2250); delay(2); } |
Maar deze code, waarbij hij de (jaja, door mij 100% zeker juist geïnstalleerde) AccelStepper library gebruikt, doet het dan weer niet:
code:
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
| #include <AccelStepper.h> #define HALFSTEP 8 #define FULLSTEP 4 // You need the AccelStepper library for this sketch to run. You can get it from here: http://aka.ms/AccelStepper // The AccelStepper constructor expects the "pins" specified to be the ends of each coil respectively. // First the ends of the Blue/Yellow coil, then the ends of the Pink/Orange coil (Blue,Yellow,Pink,Orange) // However, 28BYJ connector, ULN2003 board, and our current configuration is that pins are arranged in the proper FIRING order, // Blue, Pink, Yellow, Orange. // No biggie, that just means that we need to pay attention to what pins on our Arduino, // map to which ends of the coils, and pass the pin numbers in in the proper sequence. // To help with that, I will specify my pin variables based on their color. #define blue 2 #define pink 3 #define yellow 4 #define orange 5 //Keeps track of the current direction //Relative to the face of the motor. //Clockwise (true) or Counterclockwise(false) //We'll default to clockwise bool clockwise = true; // How many steps to go before reversing int targetPosition = 2048; //2049 steps per rotation when wave or full stepping // int targetPosition = 4096; //4096 steps per rotation when half stepping // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48 // Notice, I'm passing them as Blue, Yellow, Pink, Orange (coil ends order) not // Blue, Pink, Yellow, Orange (firing order). AccelStepper stepper1(HALFSTEP, blue, yellow, pink, orange); void setup() { //Set the initial speed (read the AccelStepper docs on what "speed" means stepper1.setSpeed(50.0); //Tell it how fast to accelerate stepper1.setAcceleration(50.0); //Set a maximum speed it should exceed stepper1.setMaxSpeed(4000.0); //Tell it to move to the target position stepper1.moveTo(targetPosition); } void loop() { clockwise = true; //Check to see if the stepper has reached the target: if(stepper1.distanceToGo() == 0){ if(clockwise == true){ clockwise = false; //Go counterclockwise now stepper1.moveTo(0); //Go back to the "home" (original) position } else { clockwise = true; //Go clockwise now stepper1.moveTo(targetPosition); //Go to the target position } } //If the stepper still needs to move (distanceToGo() != 0) //continue to advance (step) the motor stepper1.run(); } |
Als ik deze code run beweegt het motortje afentoe een beetje. Het kan natuurlijk zijn dat het te snel gaat en de motor niet lang genoeg de tijd krijgt om naar de beoogde positie te gaan en daarom "freezed", maar ook als ik de speed of acceleration verander blijft dit probleem bestaan.
Ik heb eerder gezegd dat ik op basis van al het bovenstaande 2 hulpvragen heb.
Waarvan 1:
Ik wil afhankelijk van mijn sensorwaarde dat de stappenmotor naar links beweegt, ik wil dit doen wanneer de sensorwaarde onder de 1100 a 1200 PPM uitkomt. Ik kan een if-statement maken, maar de stappenmotor zelf aansturen vind ik nog aardig uitdagend, dus als er een held van een Tweaker is die me ermee kan helpen, zou dat superfijn zijn.
2:
Mijn tweede vraag is er eentje waar ik wel wat meer over gelezen heb, en toen ik voor het huidige project aan het werk was ook gezien heb.
Ik moet denk ik mijn delays gaan vervangen voor millis, want toen ik met de servo bezig was liep er (natuurlijk) een loop, en op het moment dat hij bij het deel van de servo aankwam, gingen de CO2-metingen niet door.
Naar wat ik ervan begrijp blijft je code bij een delay ook echt op dat stuk hangen en gebruikt het de gehele processor, waardoor de metingen niet doorgaan. Bij "millis" zou de processor onthouden hoelang hij een bepaald proces moet blijven uitvoeren en ondertussen doorgaan met het andere.
Als iemand me zou kunnen helpen, zou dat superfijn zijn. Ik kan 2 oplossingen heel erg waarderen: Leer het me of schrijf het bij in de code, die je hier kunt aanpassen.
Alvast bedankt mede-Tweakers!
Diego
PS: Kan een mod de topictitel veranderen? CO2 is duidelijk genoeg en de UBB doet het natuurlijk niet in de titel..
