{"id":414,"date":"2014-03-04T22:48:15","date_gmt":"2014-03-04T22:48:15","guid":{"rendered":"http:\/\/richardalbritton.wordpress.com\/?p=414"},"modified":"2015-02-06T05:37:54","modified_gmt":"2015-02-06T05:37:54","slug":"attiny-85-line-following-robot-code-exsample","status":"publish","type":"post","link":"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/","title":{"rendered":"ATTiny Line Follower"},"content":{"rendered":"<p><span class=\"embed-youtube\" style=\"text-align:center; display: block;\"><iframe loading=\"lazy\" class=\"youtube-player\" width=\"660\" height=\"372\" src=\"https:\/\/www.youtube.com\/embed\/ZEQELKFFFJo?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent\" allowfullscreen=\"true\" style=\"border:0;\" sandbox=\"allow-scripts allow-same-origin allow-popups allow-presentation\"><\/iframe><\/span><br \/>\n<!--more--><\/p>\n<p>Continuing to mess around with the ATTiny85 IC\u2026 I ported the code from my <a title=\"Project 2: Arduino Line following bot \u2013 Test 3\" href=\"http:\/\/42bots.com\/2013\/05\/arduino-line-following-bot-test-3\/\">Arduino Uno line following robot<\/a> to the ATTiny. Some changes were necessary to make it work:<\/p>\n<ul>\n<li>The ATTiny has only 3 analog pins, so the sensor array has 3 TCRT5000 IR LED\/Sensors instead of the 6 the original line follower had<\/li>\n<li>The <a title=\"Arduino Software Servo Library\" href=\"http:\/\/playground.arduino.cc\/ComponentLib\/servo\" target=\"_blank\">SoftwareServo library<\/a> was needed, as the standard servo library that comes with the Arduino IDE does not work on the ATTiny<\/li>\n<\/ul>\n<p>The code used is below, and more info on <a title=\"How to program ATTiny85 with Arduino Uno (part 1)\" href=\"http:\/\/42bots.com\/2013\/06\/how-to-program-attiny85-with-arduino-uno-part-1\/\">how to program the ATTiny chip using your Arduino as a programmer is available in this post<\/a>. There is one more pin available on the ATTiny85, so I am thinking of adding an ultrasound sensor and some basic obstacle avoidance next. Here is the Arduino Code that runs on the ATTiny:<\/p>\n<pre class=\"lang:arduino decode:true \">#include &lt;SoftwareServo.h&gt;\r\n\r\nSoftwareServo LServo; \/\/create servo object for the left servo\r\nSoftwareServo RServo; \/\/create servo object for the right servo\r\n\r\nconst int maxSpeed = 180; \/\/ the range for continuous rotation servos is (0,180)\r\n\r\n\/* Define the pins for the IR sensors *\/\r\nconst int irPins[3] = {A1, A2, A3};\r\n\r\n\/* Define values for the IR Sensor readings *\/\r\nint irSensorDigital[3] = {0, 0, 0};\r\n\r\nint treashold = 600; \/\/ IR sensor treashold value for line detection\r\n\r\n\/\/ binary representation of the sensor reading\r\n\/\/ 1 when the sensor detects the line, 0 otherwise\r\nint irSensors = B000;\r\n\r\n\/\/ A score to determine deviation from the line [-180 ; +180].\r\n\/\/ Negative means the robot is left of the line.\r\nint error = 0;\r\n\r\nint errorLast = 0;  \/\/  store the last value of error\r\n\r\n\/* variables to keep track of current speed of motors *\/\r\nint leftServoSpeed = 90;\r\nint rightServoSpeed = 90;\r\n\r\nvoid setup()\r\n{\r\n  LServo.attach(1); \/\/ attaches the left servo to pin 1\r\n  RServo.attach(0); \/\/ attaches the right servo to pin 0\r\n}\r\n\r\nvoid loop()\r\n{\r\n Scan();\r\n UpdateDirection();\r\n Drive(leftServoSpeed, rightServoSpeed);\r\n SoftwareServo::refresh();\r\n}\r\n\r\nvoid Scan() {\r\n  \/\/ Initialize the sensors\r\n    irSensors = B000;\r\n\r\n  for (int i = 0; i &lt; 3; i++) {\r\n      int sensorValue = analogRead(irPins[i]);\r\n      if (sensorValue &gt;= treashold) {\r\n        irSensorDigital[i] = 1;\r\n      }\r\n\r\n    else {\r\n      irSensorDigital[i] = 0;\r\n    }\r\n\r\n    int b = 2-i;\r\n    irSensors = irSensors + (irSensorDigital[i]&lt;&lt;b);\r\n    }\r\n}\r\n\r\nvoid UpdateDirection() {\r\n\r\n  errorLast = error;\r\n\r\n  switch (irSensors) {\r\n\r\n    case B000: \/\/ no sensor detects the line\r\n       if (errorLast &lt; 0) { error = -120;}\r\n       else if (errorLast &gt; 0) {error = 120;}\r\n       break;\r\n\r\n     case B100: \/\/ left sensor on the line\r\n       error = -70;\r\n       break;\r\n\r\n     case B110:\r\n       error = -40;\r\n       break;\r\n\r\n     case B010:\r\n       error = 0;\r\n       break;\r\n\r\n     case B011:\r\n       error = 40;\r\n       break;\r\n\r\n     case B001: \/\/ right sensor on the line\r\n       error = 70;\r\n       break;\r\n\r\n     case B111:\r\n       error = 0;\r\n       break;\r\n\r\n     default:\r\n       error = errorLast;\r\n  }\r\n\r\n    if (error &gt;= 0) {\r\n      leftServoSpeed = maxSpeed;\r\n      rightServoSpeed = maxSpeed - error;\r\n    }\r\n\r\n    else if (error &lt; 0) {\r\n      leftServoSpeed = maxSpeed + error;\r\n      rightServoSpeed = maxSpeed;\r\n    }\r\n}\r\n\r\nvoid Drive(int leftSpeed, int rightSpeed) {\r\n\r\n    int left = leftSpeed;\r\n    int right = maxSpeed - rightSpeed;\r\n    \/* This is due to servo positioning\r\n       right servo needs to rotate back\r\n       when the robot goes forward\r\n    *\/\r\n\r\n    \/\/ ensure input is in the correct range for servo control\r\n    if (left &lt; 0) {left = 0;}\r\n    else if (left &gt; maxSpeed) {left = maxSpeed;}\r\n\r\n    if (right &lt; 0) {right = 0;}\r\n    else if (right &gt; maxSpeed) {right = maxSpeed;}\r\n\r\n    LServo.write(left);\r\n    RServo.write(right);\r\n}<\/pre>\n<p>And here is the \u201cunderbelly of the beast\u201d. Messy wires everywhere\u2026<\/p>\n<p><a href=\"http:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2014\/03\/ATTinyLineFollowerPIC01.jpg\"><img loading=\"lazy\" class=\" size-full wp-image-734 aligncenter\" src=\"http:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2014\/03\/ATTinyLineFollowerPIC01.jpg\" alt=\"ATTinyLineFollowerPIC01\" width=\"600\" height=\"628\" srcset=\"https:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2014\/03\/ATTinyLineFollowerPIC01.jpg 600w, https:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2014\/03\/ATTinyLineFollowerPIC01-287x300.jpg 287w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-414\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-414\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-414\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-414\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/attiny-85-line-following-robot-code-exsample\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"author":1,"featured_media":734,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"video","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[64],"tags":[26,32,28],"jetpack_featured_media_url":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2014\/03\/ATTinyLineFollowerPIC01.jpg","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5AhH6-6G","_links":{"self":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/414"}],"collection":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/comments?post=414"}],"version-history":[{"count":6,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/414\/revisions"}],"predecessor-version":[{"id":872,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/414\/revisions\/872"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media\/734"}],"wp:attachment":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media?parent=414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/categories?post=414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/tags?post=414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}