Interfacing with my stepper motor
I need 4 stepper motors for my final project to run peristaltic pumps, so I wanted to make a simulator, which presents the motor shaft position in a graphical interface. The motor is not meant to be controlled from the interface, but through measurements.
I found a nice example code about trigonometry representation in Processing and decided to use that as a basis for my motor position simulator. The Processing interface looks a lot like Arduino IDE and behaves in similar manner, which makes it an easy way to start to work on interfacing. It has a setup and loop, which is called draw.
Because the pH agent has to be most accurately dosed, I started to work on that pump in detail. I calculated the amount of 85 % phosphoric acid, which is required to be pumped in the rain water, for the water pH to be between 5.5 and 6.5. Because phosphoric acid is a polyprotic acid the calculation is not straight forward. It requires three dissociation reactions.
Because Ka1 is much bigger number than Ka2 and Ka3, I simplified the equation to take Ka1 only into account. I calculated the 1E-6 M solution to see, if my calculations are correct. The pH naturally resulted to 6 (Simplification results for it to behave like strong acid with complete dissociation and from the tables I can see that the accurate number would be 5.97, which is close enough for my purposes.
I used tables from Wikipedia and aquion to validate my calculations. Then I solved the equation for pH 5.5 and pH 6.5, the results are that the solution is required to be 3.161E-6 M and 3.162E-7 M for pure H3PO4. The molar mass of H3PO4 is 97.99 g/mol, (m=nM) which results to 0.000309741 g/l of pure H3PO4 for the pH 5.5 and 3.0986E-5 for the pH 6.5. The density of pure H3PO4 is 1.885 g/ml and for the 85 % solution 1.685 g/ml, which results to 0.000346506 g/l for pH 5.5 and 3.466E-5 g/l for pH 6.5. In 50 l tank, the amount is 0.032566 g for pH 5.5 and 0.003267 g for pH 6.5, which corresponds to (V=m/density) 0.01938 ml and 0.001939 ml, respectively. This is very small amount and I have to dilute the solution to be able to pump reasonable amount. In the 85 % phosphoric acid there is 14.6423 mol/l and the requirement is 3.161E-6 mol/l to reach correct dose. If I aim for 1 ml dose for the 50 l tank, the pH agent solution should be diluted to 1.5 %, which phosphoric acid concentration is 0.158047256 mol/l. I will confirm the calculations with pH meter when I have built it. Tube for my peristaltic pump has 5 mm outer and 3 mm inner diameters. The rotating part of the pump is 4.4 cm in diameter and it is divided in 4 sections. Therefore the circumference is close to C=PI*d = PI * (0.044 m + 0.0025 m) = 0.146 m, which means that single pumping volume lenght is about 0.0365 m and the volume is V = Pi*r²*h = PI*(0.0015 m)²*0.0365 m = 2.5815E-7 m3 = 0.25815 ml. Single pump rotation equals to about 1.03 ml. Because the tube is pressed down with wheels the real volume is smaller and I can expect to be able to rotate pump once before the pH goes below 5.5. The actual results are to be measured with the actual pump.
Based on these calculations, I started to create the pump controller. The motor position can be demonstrated with Processing and the angle can be seen as well in numbers. Because I had the necessary file to run stepper motor with my board from the Output devices week, I started to work with Processing. At first, I made a tutorial from Sparkfun website, connecting Arduino to Processing, to see how to make it and to understand the process. It seemed to be straight forward process. The tutorial code for the Arduino IDE and Processing are presented below.
To avoid reading nulls and getting false readings, I set a condition to discard nulls. I read the string and convert it to integer and trim the extra rubbish off it.
The rotation is made with an example code that I found from the Processing web site. First the circle is drawn with an object called ellipse(x-coordinate, y-coordinate, width, height). To make a circle ellipse width and height should be the same. Secondly a rectangle is drawn with and object called rect(upper left x-coordinate, upper left y-coordinate, x-dimension, y-dimension). The x and y coordinates are calculated from each step that motor takes using trigonometry. Finally, a line is drawn between the middle point of the circle to the upper left corner of the rectangle. Line is drawn with object called line(start x-coordinate, start y-coordinate, destination x-coordinate, destination y-coordinate). The output text is added to screen with text object text(string, + value, first letter x-coordinate, first letter y-coordinate).
From my computer through the Arduino IDE serial, I send a simple message (stepper motor step count) to serial port: Serial.println(steps); The message ends with endline "\n" and ends the reading with Processing. In processing, the message is read with high = myPort.readStringUntil('\n'); The \n is the endline control character, which is used to mark the end of a line of text and the start of a new one (Wikipedia 2018). Then the stepper motor takes the steps and waits for 2 seconds before doing the same thing.
The interface looks like this:
Running a stepper motor
The connections and the set values are made in the similar manner to the Week12: Output devices. The setup with connections are presented in the following pictures.
Video of the rotating motor with interface is shown below.
Reflection on this weeks assignment
This weeks assignment got me further in the final project and especially in the pH meter-pump control part. There was plenty of learning and I understand a lot more about the Processing, its connection to Arduino IDE project and the effect of phosphoric acid in unbuffered water pH. I had never used Processing in any project and it was really interesting and opens a lot of possibilities for the future projects. The hardest part of this week was to figure out how to remove extra rubbish from the string and to get the actual sent integer for the motor rotation. It took me a long time, because every guide said that it could be done with either number = int(string); or number = Integer.parseInt(string);, which obviously did not work. I needed to add the number = int(string.trim()); and then the number of steps is correct.