Steuerung des Relais-Addierers mit einem alten Tintenstrahler + Arduino
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
8.0KB

  1. /*
  2. Es gibt 6 Positionen die vom Druckkopf angefahren werden müssen.
  3. für jede Position 1-6 wird in einem Array die genaue Position angegeben.
  4. boundRight wird durch eine Zahl im Array ersetzt.
  5. Wird diese Position erreicht stoppt der Kopf und das
  6. Programm Schalter umlegen wird aufgerufen.
  7. Der Zähler wird auf die nächste Position gesetzt und der Druckkopf wieder gestartet
  8. Hat der Kopf die letzte Position erreicht wird der Druckkopf zur Ausgangsposition
  9. zurückgefahren und die Position bei erreichen der Lichtschranke auf 0 gesetzt.
  10. Damit beim Umlegen der Schalter die richtige Bewegung ausgeführt wird müssen
  11. die Positionen aller Schalter bekannt sein
  12. (Alternativ wird die Position durch ein LDR vor der jeweiligen Statuslampe oder
  13. einem elektrischen Kontakt am Hebel ermittelt)
  14. Welche Schalter umgelegt werden wird über ein Array Schalter 2*6 über die Serielle
  15. Verbindung übertragen. Wenn in Arduino keine 2D Arrays möglich sind wird ein 1D Array
  16. mit doppelter Länge gewählt. (Ist auch einfacher für die Datenübertragung)
  17. Der Abgleich der Position wird aus dem ArraySchalter ermittelt
  18. ArraySchalter ( position 1 ) wenn einer der beiden Werte 1 ist wird die Position (1)
  19. an das Array Position über geben um in einen Wert für die Position umgerechnet
  20. Bsp 1 = 254.
  21. Nach Umlegen der Schalter wird der Zähler hochgesetzt bis eine Spalte im Array erreicht wird
  22. deren Wert nicht 0 ist.
  23. Initialisierung zur Positionsbestimmung?
  24. */
  25. #include <Servo.h>
  26. #define SERVO_TOP_PIN 5
  27. #define SERVO_BOTTOM_PIN 6
  28. #define SIGN_PIN 4
  29. #define INTERRUPT_PIN 2
  30. #define HEAD_MOTOR_PIN1 9
  31. #define HEAD_MOTOR_PIN2 10
  32. #define MAX_SWITCH 3 // only allow 2 bits for now
  33. #define BUMPER_PIN 3
  34. Servo servoTop, servoBottom;
  35. const int posDown=30, posUp=160, posMid=90;
  36. const int servoDelay=1000;
  37. const int boundLeft=0;
  38. const int initBoundRight=10;
  39. const int velo=33;
  40. int boundRight=200;
  41. volatile bool interruptPinChanged=false;
  42. volatile int headPos=0;
  43. volatile bool bump = false;
  44. bool switches[12]={false,false,false,false,false,false,false,false,false,false,false,false};
  45. bool switches_old[12]={false,false,false,false,false,false,false,false,false,false,false,false};
  46. int switchPositions[6]={10,20,30,40,50,60};
  47. int currentSwitch=-1;
  48. bool waitForInput=false;
  49. byte readarr[11];
  50. int spos = 0;
  51. byte initialize=0;
  52. void setup()
  53. {
  54. // init servos
  55. servoTop.attach(SERVO_TOP_PIN);
  56. servoBottom.attach(SERVO_BOTTOM_PIN);
  57. // head motor pins to output
  58. pinMode(HEAD_MOTOR_PIN1, OUTPUT);
  59. pinMode(HEAD_MOTOR_PIN2, OUTPUT);
  60. attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), interruptPositionUpdate, RISING);
  61. attachInterrupt(digitalPinToInterrupt(BUMPER_PIN), interruptBumper, RISING);
  62. Serial.begin(19200);
  63. }
  64. void loop()
  65. {
  66. if(initialize==0) {
  67. analogWrite(HEAD_MOTOR_PIN1, velo); //Kopf geht nach rechts
  68. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  69. initialize=1;
  70. } else {
  71. if(initialize==1) {
  72. if(interruptPinChanged) {
  73. interruptPinChanged = false;
  74. if (headPos >= initBoundRight) {
  75. digitalWrite(HEAD_MOTOR_PIN1, LOW);
  76. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  77. delay(100);
  78. digitalWrite(HEAD_MOTOR_PIN1, LOW); //Kopf geht nach links
  79. analogWrite(HEAD_MOTOR_PIN2, velo);
  80. initialize = 2;
  81. }
  82. }
  83. } else {
  84. if(initialize==2) {
  85. if(bump) {
  86. digitalWrite(HEAD_MOTOR_PIN1, LOW);
  87. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  88. detachInterrupt(digitalPinToInterrupt(BUMPER_PIN));
  89. headPos = 0;
  90. initialize=3;
  91. waitForInput=true;
  92. }
  93. } else {
  94. if((!waitForInput) && interruptPinChanged) {
  95. interruptPinChanged = false;
  96. //Serial.println(headPos);
  97. if(headPos <= boundLeft) {
  98. Serial.println("Start Position reached");// und warten auf neue Eingabe durch Nutzer
  99. digitalWrite(HEAD_MOTOR_PIN1, LOW);
  100. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  101. waitForInput = true; //
  102. } else {
  103. if (headPos >= boundRight) {
  104. Serial.println("Position reached");//Motor anhalten und Schalterprogramm ausführen
  105. digitalWrite(HEAD_MOTOR_PIN1, LOW);
  106. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  107. flipswitch();
  108. updateBoundRight();
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. void interruptPositionUpdate() {
  117. if(!waitForInput) {
  118. interruptPinChanged = true;
  119. if(digitalRead(SIGN_PIN)) {
  120. headPos--;
  121. } else {
  122. headPos++;
  123. }
  124. }
  125. }
  126. void interruptBumper() {
  127. bump = true;
  128. }
  129. void updateBoundRight() {
  130. /*
  131. Es wird bestimmt welche Position als nächstes angefahren wird.
  132. Dann wird der Kopf wieder gestartet
  133. */
  134. int oldCurrentSwitch = currentSwitch;
  135. currentSwitch++;
  136. while((currentSwitch<6) && (switches[currentSwitch]==switches_old[currentSwitch]) && (switches[currentSwitch+6]==switches_old[currentSwitch+6])) {
  137. currentSwitch++;
  138. }
  139. if(currentSwitch >= MAX_SWITCH) {
  140. currentSwitch=-1;
  141. if(oldCurrentSwitch>=0) {
  142. digitalWrite(HEAD_MOTOR_PIN1, LOW); //Kopf geht nach links
  143. analogWrite(HEAD_MOTOR_PIN2, velo);
  144. }
  145. } else {
  146. boundRight=switchPositions[currentSwitch];
  147. analogWrite(HEAD_MOTOR_PIN1, velo); //Kopf geht nach rechts
  148. digitalWrite(HEAD_MOTOR_PIN2, LOW);
  149. }
  150. }
  151. void flipswitch(){
  152. /*
  153. Über Array Schalter wird entschieden welcher Schalter betätigt wird
  154. aus ArraySchalteralt wird ermittelt in welche Richtung der Servo
  155. den Schalter umlegen muss.
  156. Danach wird updateboundRight ausgeführt und die nächste Kopfposition bestimmt.
  157. Die Servos sind in Mittelstellung analogWrite(127) von dort dann ca 45°
  158. nach oben oder unten und wieder in Ausgangsstellung.
  159. Genaue Servopositionen sind dabei noch abhängig der Einbauposition zu ermitteln.
  160. */
  161. if(switches[currentSwitch] && (!switches_old[currentSwitch])) {
  162. servoTop.write(posDown);
  163. delay(servoDelay);
  164. servoTop.write(posMid);
  165. delay(servoDelay);
  166. }
  167. if(!switches[currentSwitch] && (switches_old[currentSwitch])) {
  168. servoTop.write(posUp);
  169. delay(servoDelay);
  170. servoTop.write(posMid);
  171. delay(servoDelay);
  172. }
  173. if(switches[currentSwitch+6] && (!switches_old[currentSwitch+6])) {
  174. servoBottom.write(posDown);
  175. delay(servoDelay);
  176. servoBottom.write(posMid);
  177. delay(servoDelay);
  178. }
  179. if(!switches[currentSwitch+6] && (switches_old[currentSwitch+6])) {
  180. servoBottom.write(posUp);
  181. delay(servoDelay);
  182. servoBottom.write(posMid);
  183. delay(servoDelay);
  184. }
  185. // optional: have both switchs switch at the same time
  186. /*
  187. if(switches[currentSwitch] && (!switches_old[currentSwitch])) {
  188. servoTop.write(posDown);
  189. }
  190. if(!switches[currentSwitch] && (switches_old[currentSwitch])) {
  191. servoTop.write(posUp);
  192. }
  193. if(switches[currentSwitch+6] && (!switches_old[currentSwitch+6])) {
  194. servoBottom.write(posDown);
  195. }
  196. if(!switches[currentSwitch+6] && (switches_old[currentSwitch+6])) {
  197. servoBottom.write(posUp);
  198. }
  199. delay(servoDelay);
  200. servoTop.write(posMid);
  201. servoBottom.write(posMid);
  202. delay(servoDelay);
  203. */
  204. switches_old[currentSwitch] = switches[currentSwitch];
  205. switches_old[currentSwitch+6] = switches[currentSwitch+6];
  206. }
  207. void serialEvent()
  208. {
  209. /*
  210. Wenn eine Eingabe abgearbeitet wurde inputflag=1 wird der Controller frei für die
  211. nächste Eingabe. Vorherige Eingaben werden somit verworfen. Die Eingabe wird aus
  212. dem EingabeArray in ArraySchalter geschrieben und der Kopf nach rechts gestartet.
  213. */
  214. while(Serial.available()) {
  215. // get the new byte:
  216. byte inChar = Serial.read();
  217. if (inChar == 'A') {
  218. spos = 0;
  219. continue;
  220. }
  221. if (inChar != 'E' && spos < 11) {
  222. readarr[spos++] = inChar;
  223. }
  224. else {
  225. if (inChar == 'E') {
  226. if ( waitForInput ) {
  227. if(readarr[0] == '-') {
  228. switches[6] = true;
  229. } else {
  230. switches[6] = false;
  231. }
  232. for(int i=1;i<6;i++) {
  233. switches[i] = (readarr[i] == '1');
  234. switches[i+6] = (readarr[i+5] == '1');
  235. }
  236. waitForInput = false;
  237. updateBoundRight();
  238. } // else: discard input
  239. }
  240. }
  241. }
  242. }