{"id":16219380,"url":"https://github.com/ivanseidel/arduinosensors","last_synced_at":"2025-03-19T11:30:31.914Z","repository":{"id":10481014,"uuid":"12659183","full_name":"ivanseidel/ArduinoSensors","owner":"ivanseidel","description":"A Library of Libraries of Sensors. Infrared, Ultrasonic, Compass and many others, ready to work with ArduinoThread and fully object oriented","archived":false,"fork":false,"pushed_at":"2021-05-26T17:45:13.000Z","size":127,"stargazers_count":54,"open_issues_count":1,"forks_count":17,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-28T18:22:41.595Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivanseidel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-07T03:16:57.000Z","updated_at":"2024-08-13T09:01:47.000Z","dependencies_parsed_at":"2022-09-09T17:20:40.423Z","dependency_job_id":null,"html_url":"https://github.com/ivanseidel/ArduinoSensors","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanseidel%2FArduinoSensors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanseidel%2FArduinoSensors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanseidel%2FArduinoSensors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanseidel%2FArduinoSensors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivanseidel","download_url":"https://codeload.github.com/ivanseidel/ArduinoSensors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243985615,"owners_count":20379175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T11:54:28.111Z","updated_at":"2025-03-19T11:30:31.639Z","avatar_url":"https://github.com/ivanseidel.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Arduino-Sensors\r\n\r\nA \"Library\" of Libraries of Sensors. Infrared, Ultrasonic, Compass and many others,\r\nready to work with [ArduinoThread](https://github.com/ivanseidel/ArduinoThread) and fully object oriented.\r\n\r\nThis library was made to provide lot's of out-of-the-box features, such as 'Interfaces', 'Threadable' sensors,\r\nand reliability over C++ Objects.\r\n\r\nIf you are a developer, please consider developing more sensor Libraries following the given pattern. I will be\r\npleased to incorporate it to the library!\r\n\r\n## Installation\r\n\r\n1. [Download](https://github.com/ivanseidel/ArduinoSensors/archive/master.zip) the Latest release from gitHub.\r\n2. Unzip and modify the Folder name to \"ArduinoSensors\" (Remove the '-version')\r\n3. Paste the modified folder on your Library folder (On your `Libraries` folder inside Sketchbooks or Arduino software).\r\n4. Download and Install [ArduinoThread](https://github.com/ivanseidel/ArduinoThread)\r\n5. Restart the Arduino IDE\r\n\r\n## Included Generic Classes:\r\n\r\n* AnalogIn\r\n* DigitalIn\r\n* DigitalOut\r\n* AnalogVoltage\r\n\r\n## Included Sensor Classes:\r\n\r\n* MLX90614 Temperature Sensor\r\n* HMC6352 Compass sensor\r\n* EZ Ultrasonic Sensor\r\n* Ping Ultrasonic Sensor\r\n* HC-SR04 Ultrasonic Sensor\r\n* InvenSense IMU MPU9150\r\n* InvenSense IMU MPU6050\r\n* Sharp Infrared Short Distance Sensor (GP2D120XJ00F)\r\n* Sharp Infrared Medium Distance Sensor (GP2Y0A21YK)\r\n* Sharp Infrared Long Distance Sensor (GP2Y0A02YK0F)\r\n\r\n# The Concept of this Library\r\n\r\nIf you are here, you are probably looking for some sensor library. Perhaps an Distance sensor, or a Compass sensor, or even a IMU sensor. What do they all have in common? They are all sensors, and do some measurement. Perhaps an Angle, or a Distance, or a Speed...\r\n\r\nSome libraries uses functions and others use Classes witch are better to maitain and even to understand the code. This Library tries to create a patterns that allows others to create better Sensor libraries with it, while keeping method names generic and compatibility across multiple platforms. Also, Sensors extend from it's base the a Thread (from [ArduinoThread](https://github.com/ivanseidel/ArduinoThread) Library), allowing `async` fetch of sensor data pretty easily.\r\n\r\nBut to do all that, we must have a strong and nice Base to work with. For example: There are many platforms that are 3.3v, 5v and even 1.8V. How can we make it work with multiple ADC values? How can we make it simple to develop and to use? Continue reading and you will understand.\r\n\r\n# Base Classes\r\n\r\nConsists of a set of classes that helps another classes like `DigitalIn`, `AnalogIn`, `DigitalOut`, `AnalogVoltage`. \r\n\r\nAlso contains a set of Interfaces such as `AngleInterface`, `DistanceInterface`, `TemperatureInterface`, `VoltageInterface`, used by different sensor types.\r\n\r\nLet's say we have a new Temperature sensor, and we want to create a Library for it. What we expect to have:\r\n* **Generic method names.** In this case, it would extend a `TemperatureInterface`, that has the method `getTemperature` and `readTemperature`\r\n* **Caching it's value.** We should be able to both `read` it's value (actually fetch sensor data, read analog, communicate...), or `get` it's current value (basically, return what was read last, like a caching).\r\n* **Work Asynchronously.** Implementing Thread from [ArduinoThread](https://github.com/ivanseidel/ArduinoThread) Library, we can make it read with a fixed timing, and  get it's value latter without further delay.\r\n\r\n## Interfaces\r\n\r\nInterfaces are a very good way of transforming your usual code into a more generic way. It's basicaly a set of methods and properties (variables), that a Class will inherit. For example, every class that extends `AngleInterface`, will have a method called `readAngle` and `getAngle`. If a new sensor library is created, that reads an angle (perhaps a potentiometer, Compass or even a encoder), it could inherit from this interface, and get those methods.\r\n\r\nI will explain why it's good to use with an experience I had:\r\n\r\nI was developing a complex robot, that would require multiple Distance Sensor types. That included two types of Infrared distance sensor, and one type of Ultrasonic sensor. I have developed this library thinking that whenever I needed, I could change the sensor in hardware for another, and it would still work. Shure that there are physical differences between them, but what I wanted was to work with multiple sensors without altering more than ONE line of code. I so I did it. We could test with different sensors, without taking so much time on software and also hardware.\r\n\r\nWe also used a IMU from Invensense, that has a Compass. After a while, we decide to change that for a simple Compass Sensor. Both of the sensors libraries was made by me, implementing it's `AngleInterface`.\r\n\r\n## Base Classes\r\n\r\nBase Classes are used by other classes, and also by you (if you want), providing a even more High Level approach for IO manipulation.\r\n\r\n### DigitalIn Class\r\n\r\nProvides a easy approach for manipulating a Digital Input pin:\r\n\r\n```\r\nDigitalIn myButton(9);\r\n\r\n// Check if Pin is HIGH\r\nif (myButton)...\r\n  \r\n// Check if Pin is LOW\r\nif (myButton == LOW)...\r\n\r\n// Reads it's value\r\nboolean val = myButton.readValue();\r\n\r\n// Get last read value\r\nval = myButton.getValue();\r\n```\r\n\r\nAlso, if you initialize it passing `true` as a seccond param, every read will be inverted:\r\n```\r\nDigitalIn myInvertedButton(10, true);\r\n\r\n// Check if Pin is LOW\r\nif(myInvertedButton)\r\n\r\n// Read it's value (inverted)\r\nmyInvertedButton.readValue();\r\n```\r\n\r\n### DigitalOut Class\r\n\r\nUsed to manipulate Digital Output pins in a easy way.\r\n\r\n```\r\nDigitalOut myLed(13);\r\n\r\n// Turns LED on\r\nmyLed = HIGH;\r\nmyLed.turn(HIGH);\r\nmyLed.turnOn();\r\n\r\n// Turns LED off\r\nmyLed = LOW;\r\nmyLed.turn(LOW);\r\nmyLed.turnOff();\r\n```\r\n\r\nLike DigitalIn, if you assign an seccond parameter in it's initialization, it will automatically invert it's output\r\n```\r\nDigitalOut myLedInverted(13, true);\r\n\r\n// Turns LED off\r\nmyLedInverted = HIGH\r\n\r\n// You can also check it's istate like this:\r\nif(myLedInverted == HIGH) ...\r\n```\r\n\r\n### AnalogIn Class\r\n\r\nWe usually need to use Analog Pins as Digital. Or even Read it's value multiple times. I usually consider a lot the timing of things, knowing every milisecond that is happening on my program. Because of that you might consider using this class instead of usual `analogRead` function.\r\n\r\n```\r\nAnalogIn myPot(A0);\r\n\r\n// Reads it's value\r\nval = myPot.read();\r\n\r\n// Get it's cached value (does not reads ADC, only returns last value)\r\nval = myPot.getValue();\r\n```\r\n\r\nOne usual case, is setting a threshold to compare. We do it for you:\r\n\r\n```\r\n// Set threshold for 500\r\nmyPot.setThreshold(500);\r\n\r\n// Check if below 500\r\nif(myPot.belowThreshold())...\r\n\r\nif(myPot == false)...\r\n\r\n// Check if above 500\r\nif(myPot.aboveThreshold())...\r\n\r\nif(myPot == true)...\r\n```\r\n\r\n## AnalogVoltage Class\r\n\r\nThis is a nice step for next generations of Libraries, because there are many Analog Sensors around, that it's converted value should be mapped to a Voltage, not a ADC value. But that's a problem becoming larger today, since there are platforms that runs with 5v, others with 3.3v... And imagine, every single library thrying to work whit that (or not)?\r\n\r\n```\r\nAnalogVoltage myVoltimeter(A0);\r\n\r\n// Read the voltage (in Volts)\r\nfloat pinVoltage = myVoltimeter.readVoltage();\r\n```\r\n\r\nWell, you might be wondering: How does it do it's magic? The answer is pretty simple: **Preprocessor macros**.\r\n\r\nIn compiling time, we detect weather you are using a 3.3v or 5v platform, and set a definition called `ADC_DEFAULT_AREF`. We use it later to scale the ADC to a voltage. But keep calm, you can override that pretty easily, and allows you to create custom `linear` voltage in readers (Like a voltage divider, to read a battery voltage).\r\n\r\n```\r\n// 0 in ADC now means -5v. full ADC (1024) means 10v\r\nAnalogVoltage myCustomVoltimeter(A0, -5, 10);\r\n\r\nfloat pinVoltage = myCustomVoltimeter.readVoltage();\r\n```\r\n\r\n# Working toguether with ArduinoThread\r\n\r\nRead more about [ArduinoThread](https://github.com/ivanseidel/ArduinoThread) here. It's a library I created to simplify complex softwares that requires multiple async tasks. Let's say:\r\n* Read Compass every 50ms\r\n* Read Distance Sensors every 70ms\r\n* Read a button every 5ms\r\n* Get battery voltage every 1 minute\r\n* and so on...\r\n\r\nIf you want a REAL example of it working, take a look at our [2013 RoboCup Junior Soccer Robot code](https://github.com/ivanseidel/Robot-Soccer-2013/tree/master/Software/Soccer_v02).\r\n\r\nThe idea is that you can register Threads in ThreadController (a group of Threads), and let the system check if it should be runned. In that way, you just GET sensor values in your main code, without consuming time every time you need something.\r\n\r\n```\r\n// Create a new ThreadController that will run always\r\n// (means it will check if it's threads should be runned everytime)\r\nThreadController threads(0);\r\n\r\n// Create some sensors\r\nDistanceInterface *myDist1 = new SharpLong(A0);\r\nDistanceInterface *myDist2 = new SharpShort(A1);\r\nTemperatureInterface *thermometer = new MLX90614(0x32);\r\nAngleInterface *myCompass = new HMC6352();\r\n\r\n// Each sensor has it's interval set to minimum possible\r\n// or something good to work with (20ms - 70ms).\r\n\r\n// But they ARE Thread objects, so you can make use of\r\n// it's methods:\r\n\r\n// Compass should be read every 60ms\r\nmyCompass.setInterval(60);\r\n\r\n// Add to the thread controller\r\nthreads.add(\u0026myDist1);\r\nthreads.add(\u0026myDist2);\r\nthreads.add(\u0026thermometer);\r\nthreads.add(\u0026myCompass);\r\n\r\n// Now, just call threads.run(); to automatically run what is needed\r\n// (perhaps in a Timer Callback? or in Loop.. whatever)\r\nloop(){\r\n  threads.run();\r\n  \r\n  // Get the most recend value WITHOUT reading the sensor\r\n  double currentAngle = myCompass-\u003egetAngle();\r\n  float distance = myDist1-\u003egetDistance();\r\n  [...]\r\n}\r\n\r\n```\r\n\r\n## Rest of Documentation under development...\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanseidel%2Farduinosensors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivanseidel%2Farduinosensors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanseidel%2Farduinosensors/lists"}