Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
en:iot-open:remotelab:sut:generalpurpose2:b7 [2020/04/28 16:57] – created pczekalskien:iot-open:remotelab:sut:generalpurpose2:b7 [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 8: Line 8:
  
 === Prerequisites === === Prerequisites ===
-The servo is controlled using predefined, precise PWM timing. You will use a predefined library instead of manually setting-up PWM: +You need to understand how a typical servomotor looks like and how it works.\\ 
-<code c> +The servo is controlled using predefined, precise PWM timing. Most servos share exactly the same model (0-180 degree servos), regardless of their size and power voltage. Classical, analogue servo frequency is 50Hz = 20ms period and duty cycle of the high signal is 1ms for 0deg and 2ms for 180deg. So changing the PWM duty cycle from 1ms to 2ms (5% to 10%) rotates servo. There is no need, however, to implement manually (still you can do it) but you will use a predefined library instead of manually setting up PWM. This brings features like range mapping to control servo logical way (i.e. providing angle, not duty cycle).\\ 
-#include <Servo.h> +The library is ''Servo.h''. 
-</code>+ 
 +According to the algorithm of your choice to implement your code, you may hard code rotations one by one or i.e. declare a table with rotation targets and then iterate over it, so familiarity with array operations in C is essential in this case.
  
 === Scenario === === Scenario ===
-In this scenario, you will rotate the servo to the 0 degrees, then 45, 90, 135 and 180 degrees counter wise, then 180, 90, 0, clockwise. Note - Arrow pointing left means servo is set to 0, pointing right is 180 degrees, and when 90 degrees, arrow points down.+In this scenario, you will rotate the servo to 0 degrees, then 45, 90, 135 and 180 degrees counter wise, then 180, 90, 0, clockwise. Note - Arrow pointing left means servo is set to 0, pointing right is 180 degrees, and when 90 degrees, arrow points down. 
 +We use LCD to get feedback about the requested servo angle and to compare it with the result, but please note, it is just for information only and is not necessary to implement servo rotation. 
 + 
 +<note warning>Please DO NOT use ''loop()'' to implement infinite servo rotation as it will wear out quickly and can even burn. Servo is NOT INTENDED to rotate as a motor. Instead, implement your code to run once or twice in the ''setup()'' function. You may reset the node to restart your code without the need to recompile.</note>
  
 === Result === === Result ===
Line 28: Line 32:
 <code c> <code c>
 #include <Servo.h> #include <Servo.h>
- 
 </code> </code>
  
 == Step 2 == == Step 2 ==
-Instantiate software controler component for the LCD display:+Define a servo management class:
 <code c> <code c>
-LiquidCrystal_I2C lcd(0x3F,20,4)  // set the LCD address to 0x3F for nodes 1 through 5, 8 and 9 for a 20 chars and 4 line display +... 
-//LiquidCrystal_I2C lcd(0x27,20,4); // for nodes 10 and 11 only!+Servo servo
 +... 
 +</code>
  
-Adafruit_BMP280 bmp;+If you intend to implement your solution with rotation targets array, here is a hint on array declaration: 
 +<code c> 
 +... 
 +byte angles[] = {0,45,90,135,180,90,0}; 
 +...
 </code> </code>
  
 == Step 3 == == Step 3 ==
-Declare a buffer for ''sprintf'' function and floating point value (single precision is enough) for storing last air pressure reading:+Instantiate software controller component for the LCD display:
 <code c> <code c>
-char buffer [11]+... 
-float pres;+LiquidCrystal_I2C lcd(0x3F,20,4)  // set the LCD address to 0x3F for nodes 1 through 5,  
 +                                 //8 and 9 for a 20 chars and 4 line display 
 +//LiquidCrystal_I2C lcd(0x27,20,4)// for nodes 10 and 11 only! 
 +...
 </code> </code>
  
 == Step 4 == == Step 4 ==
-Initialize LCD and BMP sensors:+In the ''setup()'' function initialize LCD and attach servo, then implement your code:
 <code c> <code c>
 ... ...
Line 54: Line 66:
   lcd.backlight();   lcd.backlight();
   lcd.home();   lcd.home();
 +  lcd.print("Starting");
 ... ...
-  if(!bmp.begin(0x76)) +  servo.attach(servoPin); 
-  { +  servo.write(0); // rotate to 0 degrees.
-    lcd.print("Bosch Sensor Error!")+
-    delay(1000); +
-  }+
-  lcd.home(); +
-  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */ +
-                  Adafruit_BMP280::SAMPLING_X2,     /* Tempoversampling */ +
-                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */ +
-                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */ +
-                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */+
 ... ...
 </code> </code>
-The BMP sensor address is 0x76 and, if not initialised, display error on the LCD screen.+Setting servo to the desired angle is as simple as calling ''servo.write(angle);''The default mapping is 0...180 degrees for micro servos we use here. 
 +\\
  
-== Step 5 == +If you implement your solution using rotation targets array, here is a hint on how to implement the ''for'' loop to iterate over an array:
-Read in the loop:+
 <code c> <code c>
 ... ...
-  pres bmp.readPressure()/100;+  for(int i=0; i<sizeof(angles); i++) 
 +  {
 ... ...
 </code> </code>
-''bmp.readPressure()'' function returns air pressure in //Pa//. You must convert it //hPa//dividing by 100.+The ''sizeof'' operator above brings you an automated evaluation of the array size during compilation, thus if you add or remove an item(s) from the array in the declaration section, the loop will automatically change iteration scopeaccording to the new array size.
  
-To convert float into the string with formatting use ''sprintf'' function:+ 
 +<note tip>Give it at least 2s gap between setting subsequent rotation target for the servo. Otherwise, you may be unable to reliably observe results via video stream.</note> 
 + 
 +== Step 5 == 
 +Keep ''loop()'' dummy, empty method not to overheat the servo or to wear out its gears:
 <code c> <code c>
 ... ...
-  sprintf(buffer,"%4.2f hPa",pres); +void loop() 
-... +{ 
-  delay(5000); +}
-...+
 </code> </code>
-<note tip>''sprintf'' uses number of wildcards that are rendered with data. Refer to the c/c++ documentation on ''sprintf''. Here <code c>%4.2f</code> means: having float number render it to string using four digits before decimal point and two after it. Air pressure readings should be somewhere between 890 and 1060 hPa.\\ 
-''delay(time)'' is measured in milliseconds.</note> 
  
 === Result validation === === Result validation ===
-Observe air pressure readings on the LCD. Note - small oscillations are natural - you can implement moving average (i.e. of 10 subsequent reads, FIFO model) to "flatten" readings. +Observe the arrow rotating to the desired angle.
en/iot-open/remotelab/sut/generalpurpose2/b7.1588093056.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0