├── CMakeLists.txt ├── LICENSE ├── README.md ├── html-front-end ├── eventemitter2.js ├── eventemitter2.min.js ├── index.html ├── robot_function.js ├── roslib.js ├── roslib.min.js └── three.min.js ├── joy ├── CHANGELOG.rst ├── CMakeLists.txt ├── mainpage.dox ├── migration_rules │ └── Joy.bmr ├── package.xml ├── src │ └── joy_node.cpp └── test │ ├── saved │ └── Joy.saved │ └── test_joy_msg_migration.py └── urobot ├── CMakeLists.txt ├── InterfaceArduino ├── InterfaceArduino.ino └── rosToInterface.hpp ├── Robot ├── IRremote │ ├── .gitignore │ ├── .travis.yml │ ├── Contributors.md │ ├── IRremote.cpp │ ├── IRremote.h │ ├── IRremoteInt.h │ ├── LICENSE.txt │ ├── README.md │ ├── changelog.md │ ├── examples │ │ ├── AiwaRCT501SendDemo │ │ │ └── AiwaRCT501SendDemo.ino │ │ ├── IRrecord │ │ │ └── IRrecord.ino │ │ ├── IRrecvDemo │ │ │ └── IRrecvDemo.ino │ │ ├── IRrecvDump │ │ │ └── IRrecvDump.ino │ │ ├── IRrecvDumpV2 │ │ │ └── IRrecvDumpV2.ino │ │ ├── IRrelay │ │ │ └── IRrelay.ino │ │ ├── IRremoteInfo │ │ │ └── IRremoteInfo.ino │ │ ├── IRsendDemo │ │ │ └── IRsendDemo.ino │ │ ├── IRsendRawDemo │ │ │ └── IRsendRawDemo.ino │ │ ├── IRtest │ │ │ └── IRtest.ino │ │ ├── IRtest2 │ │ │ └── IRtest2.ino │ │ ├── JVCPanasonicSendDemo │ │ │ └── JVCPanasonicSendDemo.ino │ │ └── LGACSendDemo │ │ │ ├── LGACSendDemo.ino │ │ │ └── LGACSendDemo.md │ ├── irPronto.cpp │ ├── irRecv.cpp │ ├── irSend.cpp │ ├── ir_Aiwa.cpp │ ├── ir_Denon.cpp │ ├── ir_Dish.cpp │ ├── ir_JVC.cpp │ ├── ir_LG.cpp │ ├── ir_Mitsubishi.cpp │ ├── ir_NEC.cpp │ ├── ir_Panasonic.cpp │ ├── ir_RC5_RC6.cpp │ ├── ir_Samsung.cpp │ ├── ir_Sanyo.cpp │ ├── ir_Sharp.cpp │ ├── ir_Sony.cpp │ ├── ir_Template.cpp │ ├── ir_Whynter.cpp │ ├── keywords.txt │ ├── library.json │ └── library.properties ├── LED.cpp ├── LED.h ├── Robot.ino ├── Timer-master │ ├── Event.cpp │ ├── Event.h │ ├── ReadMe.txt │ ├── Timer.cpp │ ├── Timer.h │ ├── examples │ │ ├── blink2 │ │ │ └── blink2.ino │ │ ├── kitchen_sink │ │ │ └── kitchen_sink.pde │ │ ├── pin_high_10_mins │ │ │ └── pin_high_10_mins.pde │ │ └── read_A0_flashLED │ │ │ └── read_A0_flashLED.pde │ └── keywords.txt ├── ir.cpp ├── ir.h ├── rosToInterface.hpp ├── stepper.cpp └── stepper.h ├── arduinoTransmitter └── arduinoTransmitter.ino ├── launch └── runrobots.launch ├── package.xml └── src ├── 2016-06-13-192006.jpg ├── 2016-06-13-192023.jpg ├── 2016-06-13-192037.jpg ├── 2016-06-13-192048.jpg ├── RobotClass.cpp ├── RobotClass.hpp ├── activity_node.cpp ├── camera_node.cpp ├── communication_node.cpp ├── location_node.cpp ├── niceLight.jpg ├── rosToInterface.hpp ├── urobot_init_node.cpp └── wellLitbig.jpg /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # toplevel CMakeLists.txt for a catkin workspace 2 | # catkin/cmake/toplevel.cmake 3 | 4 | cmake_minimum_required(VERSION 2.8.3) 5 | 6 | set(CATKIN_TOPLEVEL TRUE) 7 | 8 | # search for catkin within the workspace 9 | set(_cmd "catkin_find_pkg" "catkin" "${CMAKE_SOURCE_DIR}") 10 | execute_process(COMMAND ${_cmd} 11 | RESULT_VARIABLE _res 12 | OUTPUT_VARIABLE _out 13 | ERROR_VARIABLE _err 14 | OUTPUT_STRIP_TRAILING_WHITESPACE 15 | ERROR_STRIP_TRAILING_WHITESPACE 16 | ) 17 | if(NOT _res EQUAL 0 AND NOT _res EQUAL 2) 18 | # searching fot catkin resulted in an error 19 | string(REPLACE ";" " " _cmd_str "${_cmd}") 20 | message(FATAL_ERROR "Search for 'catkin' in workspace failed (${_cmd_str}): ${_err}") 21 | endif() 22 | 23 | # include catkin from workspace or via find_package() 24 | if(_res EQUAL 0) 25 | set(catkin_EXTRAS_DIR "${CMAKE_SOURCE_DIR}/${_out}/cmake") 26 | # include all.cmake without add_subdirectory to let it operate in same scope 27 | include(${catkin_EXTRAS_DIR}/all.cmake NO_POLICY_SCOPE) 28 | add_subdirectory("${_out}") 29 | 30 | else() 31 | # use either CMAKE_PREFIX_PATH explicitly passed to CMake as a command line argument 32 | # or CMAKE_PREFIX_PATH from the environment 33 | if(NOT DEFINED CMAKE_PREFIX_PATH) 34 | if(NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "") 35 | string(REPLACE ":" ";" CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH}) 36 | endif() 37 | endif() 38 | 39 | # list of catkin workspaces 40 | set(catkin_search_path "") 41 | foreach(path ${CMAKE_PREFIX_PATH}) 42 | if(EXISTS "${path}/.catkin") 43 | list(FIND catkin_search_path ${path} _index) 44 | if(_index EQUAL -1) 45 | list(APPEND catkin_search_path ${path}) 46 | endif() 47 | endif() 48 | endforeach() 49 | 50 | # search for catkin in all workspaces 51 | set(CATKIN_TOPLEVEL_FIND_PACKAGE TRUE) 52 | find_package(catkin QUIET 53 | NO_POLICY_SCOPE 54 | PATHS ${catkin_search_path} 55 | NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 56 | unset(CATKIN_TOPLEVEL_FIND_PACKAGE) 57 | 58 | if(NOT catkin_FOUND) 59 | message(FATAL_ERROR "find_package(catkin) failed. catkin was neither found in the workspace nor in the CMAKE_PREFIX_PATH. One reason may be that no ROS setup.sh was sourced before.") 60 | endif() 61 | endif() 62 | 63 | catkin_workspace() 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | It should be noted that there may be others code within this repository, I have left the origional headers in case of files. I have added inline attributation to informal sources of snippets. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microRobotsROS 2 | Repository of code for the micro robots for education project. Provides a ros interface for the small robots. 3 | 4 | mkdir -p ~/uRobot_ws/src 5 | 6 | cd ~/uRobot_ws/src 7 | 8 | catkin_init_workspace 9 | 10 | git clone https://github.com/je310/microRobotsROS ~/uRobot_ws/src 11 | 12 | cd ~/uRobot_ws/ 13 | 14 | catkin_make 15 | 16 | roslaunch urobot runrobots.launch 17 | 18 | sudo apt-get install libusb-dev 19 | sudo apt-get install libspnav-dev (needed for joy drivers) 20 | 21 | We claim no ownership of the joystick drivers,see https://github.com/ros-drivers/joystick_drivers.git 22 | -------------------------------------------------------------------------------- /html-front-end/eventemitter2.min.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(){this._events={};if(this._conf){i.call(this,this._conf)}}function i(e){if(e){this._conf=e;e.delimiter&&(this.delimiter=e.delimiter);e.maxListeners&&(this._events.maxListeners=e.maxListeners);e.wildcard&&(this.wildcard=e.wildcard);e.newListener&&(this.newListener=e.newListener);if(this.wildcard){this.listenerTree={}}}}function s(e){this._events={};this.newListener=false;i.call(this,e)}function o(e,t,n,r){if(!n){return[]}var i=[],s,u,a,f,l,c,h,p=t.length,d=t[r],v=t[r+1];if(r===p&&n._listeners){if(typeof n._listeners==="function"){e&&e.push(n._listeners);return[n]}else{for(s=0,u=n._listeners.length;s0&&o._listeners.length>a){o._listeners.warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",o._listeners.length);console.trace()}}}return true}u=e.shift()}return true}var t=Array.isArray?Array.isArray:function(t){return Object.prototype.toString.call(t)==="[object Array]"};var n=10;s.prototype.delimiter=".";s.prototype.setMaxListeners=function(e){this._events||r.call(this);this._events.maxListeners=e;if(!this._conf)this._conf={};this._conf.maxListeners=e};s.prototype.event="";s.prototype.once=function(e,t){this.many(e,1,t);return this};s.prototype.many=function(e,t,n){function i(){if(--t===0){r.off(e,i)}n.apply(this,arguments)}var r=this;if(typeof n!=="function"){throw new Error("many only accepts instances of Function")}i._origin=n;this.on(e,i);return r};s.prototype.emit=function(){this._events||r.call(this);var e=arguments[0];if(e==="newListener"&&!this.newListener){if(!this._events.newListener){return false}}if(this._all){var t=arguments.length;var n=new Array(t-1);for(var i=1;i1)switch(arguments.length){case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:var t=arguments.length;var n=new Array(t-1);for(var i=1;i0||!!this._all}else{return!!this._all}};s.prototype.on=function(e,i){if(typeof e==="function"){this.onAny(e);return this}if(typeof i!=="function"){throw new Error("on only accepts instances of Function")}this._events||r.call(this);this.emit("newListener",e,i);if(this.wildcard){u.call(this,e,i);return this}if(!this._events[e]){this._events[e]=i}else if(typeof this._events[e]==="function"){this._events[e]=[this._events[e],i]}else if(t(this._events[e])){this._events[e].push(i);if(!this._events[e].warned){var s=n;if(typeof this._events.maxListeners!=="undefined"){s=this._events.maxListeners}if(s>0&&this._events[e].length>s){this._events[e].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[e].length);console.trace()}}}return this};s.prototype.onAny=function(e){if(typeof e!=="function"){throw new Error("onAny only accepts instances of Function")}if(!this._all){this._all=[]}this._all.push(e);return this};s.prototype.addListener=s.prototype.on;s.prototype.off=function(e,n){if(typeof n!=="function"){throw new Error("removeListener only takes instances of Function")}var r,i=[];if(this.wildcard){var s=typeof e==="string"?e.split(this.delimiter):e.slice();i=o.call(this,null,s,this.listenerTree,0)}else{if(!this._events[e])return this;r=this._events[e];i.push({_listeners:r})}for(var u=0;u0){r=this._all;for(t=0,n=r.length;t 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 |

Simple roslib Example

15 |

Run the following commands in the terminal then refresh this page. Check the JavaScript 16 | console for the output.

17 |
    18 |
  1. roscore
  2. 19 |
  3. rostopic pub /listener std_msgs/String "Hello, World"
  4. 20 |
  5. rostopic echo /cmd_vel
  6. 21 |
  7. rosrun rospy_tutorials add_two_ints_server
  8. 22 |
  9. roslaunch rosbridge_server rosbridge_websocket.launch
  10. 23 |
24 |
25 |

26 | Connecting to rosbridge... 27 |

28 | 31 | 34 | 37 |
38 | 39 | -------------------------------------------------------------------------------- /html-front-end/robot_function.js: -------------------------------------------------------------------------------- 1 | // Connecting to ROS 2 | // ----------------- 3 | var ros = new ROSLIB.Ros(); 4 | // If there is an error on the backend, an 'error' emit will be emitted. 5 | ros.on('error', function(error) { 6 | console.log(error); 7 | }); 8 | // Find out exactly when we made a connection. 9 | ros.on('connection', function() { 10 | console.log('Connection made!'); 11 | }); 12 | ros.on('close', function() { 13 | console.log('Connection closed.'); 14 | }); 15 | // Create a connection to the rosbridge WebSocket server. 16 | ros.connect("ws://" + window.location.hostname + ":9090"); 17 | // Publishing a Topic 18 | // ------------------ 19 | // First, we create a Topic object with details of the topic's name and message type. 20 | var cmdVel = new ROSLIB.Topic({ 21 | ros : ros, 22 | name : '/robot0/twist', 23 | messageType : 'geometry_msgs/Twist' 24 | }); 25 | // Then we create the payload to be published. The object we pass in to ros.Message matches the 26 | // fields defined in the geometry_msgs/Twist.msg definition. 27 | var twist = new ROSLIB.Message({ 28 | linear : { 29 | x : 0, 30 | y : 0, 31 | z : 0 32 | }, 33 | angular : { 34 | x : 0, 35 | y : 0, 36 | z : 0 37 | } 38 | }); 39 | // And finally, publish. 40 | cmdVel.publish(twist); 41 | //Subscribing to a Topic 42 | //---------------------- 43 | // Like when publishing a topic, we first create a Topic object with details of the topic's name 44 | // and message type. Note that we can call publish or subscribe on the same topic object. 45 | var listener = new ROSLIB.Topic({ 46 | ros : ros, 47 | name : '/listener', 48 | messageType : 'std_msgs/String' 49 | }); 50 | // Then we add a callback to be called every time a message is published on this topic. 51 | 52 | // Calling a service 53 | // ----------------- 54 | // First, we create a Service client with details of the service's name and service type. 55 | 56 | // Then we create a Service Request. The object we pass in to ROSLIB.ServiceRequest matches the 57 | // fields defined in the rospy_tutorials AddTwoInts.srv file. 58 | var request = new ROSLIB.ServiceRequest({ 59 | a : 1, 60 | b : 2 61 | }); 62 | // Setting a param value 63 | // --------------------- 64 | ros.getParams(function(params) { 65 | console.log(params); 66 | }); 67 | // First, we create a Param object with the name of the param. 68 | var maxVelX = new ROSLIB.Param({ 69 | ros : ros, 70 | name : 'max_vel_y' 71 | }); 72 | //Then we set the value of the param, which is sent to the ROS Parameter Server. 73 | maxVelX.set(0.8); 74 | maxVelX.get(function(value) { 75 | console.log('MAX VAL: ' + value); 76 | }); 77 | // Getting a param value 78 | // --------------------- 79 | var favoriteColor = new ROSLIB.Param({ 80 | ros : ros, 81 | name : 'favorite_color' 82 | }); 83 | 84 | favoriteColor.set('red'); 85 | favoriteColor.get(function(value) { 86 | console.log('My robot\'s favorite color is ' + value); 87 | 88 | }) 89 | 90 | function moveX(inputX){ 91 | var twist2 = new ROSLIB.Message({ 92 | linear : { 93 | x : inputX, 94 | y : 0, 95 | z : 0 96 | }, 97 | angular : { 98 | x : 0, 99 | y : 0, 100 | z : 0 101 | } 102 | }); 103 | // And finally, publish. 104 | cmdVel.publish(twist2); 105 | } 106 | 107 | function rotateZ(inputZ){ 108 | var twist = new ROSLIB.Message({ 109 | linear : { 110 | x : 0, 111 | y : 0, 112 | z : 0 113 | }, 114 | angular : { 115 | x : 0, 116 | y : 0, 117 | z : inputZ 118 | } 119 | }); 120 | // And finally, publish. 121 | cmdVel.publish(twist); 122 | } 123 | ; -------------------------------------------------------------------------------- /joy/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package joy 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 1.10.1 (2015-05-24) 6 | ------------------- 7 | * Remove stray architechture_independent flags 8 | * Contributors: Jonathan Bohren, Scott K Logan 9 | 10 | 1.10.0 (2014-06-26) 11 | ------------------- 12 | * First indigo release 13 | -------------------------------------------------------------------------------- /joy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # http://ros.org/doc/groovy/api/catkin/html/user_guide/supposed.html 2 | cmake_minimum_required(VERSION 2.8.3) 3 | project(joy) 4 | 5 | # Load catkin and all dependencies required for this package 6 | set(CATKIN_DEPS roscpp diagnostic_updater sensor_msgs) 7 | set(ROSDEP_DEPS joystick) 8 | find_package(catkin REQUIRED ${CATKIN_DEPS}) 9 | catkin_package(DEPENDS ${CATKIN_DEPS} ${ROSDEP_DEPS}) 10 | 11 | # Look for 12 | include(CheckIncludeFiles) 13 | check_include_files(linux/joystick.h HAVE_LINUX_JOYSTICK_H) 14 | 15 | if(HAVE_LINUX_JOYSTICK_H) 16 | include_directories(msg/cpp ${catkin_INCLUDE_DIRS}) 17 | add_executable(joy_node src/joy_node.cpp) 18 | target_link_libraries(joy_node ${catkin_LIBRARIES}) 19 | else(HAVE_LINUX_JOYSTICK_H) 20 | message("Warning: no ; won't build joy node") 21 | endif(HAVE_LINUX_JOYSTICK_H) 22 | 23 | #catkin_add_nosetests(test/test_joy_msg_migration.py) 24 | 25 | # Install targets 26 | install(TARGETS joy_node 27 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 28 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 29 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 30 | 31 | install(DIRECTORY migration_rules 32 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 33 | ) 34 | -------------------------------------------------------------------------------- /joy/mainpage.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \mainpage 4 | \htmlinclude manifest.html 5 | 6 | \b joy ROS joystick drivers for Linux. This package works with Logitech joysticks and PS3 SIXAXIS/DUALSHOCK devices. This package will only build is linux/joystick.h 7 | 8 | \section rosapi ROS API 9 | 10 | This package contains the message "Joy", which carries data from the joystick's axes and buttons. It also has the joy_node, which reads from a given joystick port and publishes "Joy" messages. 11 | 12 | List of nodes: 13 | - \b joy_node 14 | 15 | Deprecated nodes: 16 | - \b txjoy 17 | - \b joy 18 | The deprecated nodes are the same as the joy_node, but they will warn users when used. They are actually just bash scripts that call "joy_node" and print a warning. 19 | 20 |
21 | 22 | \subsection joy joy 23 | 24 | \b joy ROS joystick driver for all linux joysticks. The driver will poll a given port until it can read from it, the publish Joy messages of the joystick state. If the port closes, or it reads an error, it will reopen the port. All axes are in the range [-1, 1], and all buttons are 0 (off) or 1 (on). 25 | 26 | Since the driver will poll for the joystick port, and automatically reopen the port if it's closed, the joy_node should be "on" whenever possible. It is typically part of the robot's launch file. 27 | 28 | \subsubsection autorepeat Auto-Repeat/Signal Loss 29 | 30 | The joy_node takes an "~autorepeat_rate" parameter. If the linux kernal receives no events during the autorepeat interval, it will automatically repeat the last value of the joystick. This is an important safety feature, and allows users to recover from a joystick that has timed out. 31 | 32 | \subsubsection usage Usage 33 | \verbatim 34 | $ joy [standard ROS args] 35 | \endverbatim 36 | 37 | \subsubsection topic ROS topics 38 | 39 | Subscribes to (name / type): 40 | - None 41 | 42 | Publishes to (name / type): 43 | - \b "joy/Joy" : Joystick output. Axes are [-1, 1], buttons are 0 or 1 (depressed). 44 | 45 | \subsubsection parameters ROS parameters 46 | - \b "~dev" : Input device for joystick. Default: /dev/input/js0 47 | - \b "~deadzone" : Output is zero for axis in deadzone. Range: [-0.9, 0.9]. Default 0.05 48 | - \b "~autorepeat_rate" : If no events, repeats last known state at this rate. Defualt: 0 (disabled) 49 | - \b "~coalesce_interval" : Waits for this interval (seconds) after receiving an event. If multiple events happen in this interval, only one message will be sent. Reduces number of messages. Default: 0.001. 50 | 51 | 52 |
53 | 54 | 55 | 56 | */ 57 | -------------------------------------------------------------------------------- /joy/migration_rules/Joy.bmr: -------------------------------------------------------------------------------- 1 | class update_joy_Joy_e3ef016fcdf22397038b36036c66f7c8(MessageUpdateRule): 2 | old_type = "joy/Joy" 3 | old_full_text = """ 4 | float32[] axes 5 | int32[] buttons 6 | """ 7 | 8 | new_type = "sensor_msgs/Joy" 9 | new_full_text = """ 10 | # Reports the state of a joysticks axes and buttons. 11 | Header header # timestamp in the header is the time the data is received from the joystick 12 | float32[] axes # the axes measurements from a joystick 13 | int32[] buttons # the buttons measurements from a joystick 14 | 15 | ================================================================================ 16 | MSG: std_msgs/Header 17 | # Standard metadata for higher-level stamped data types. 18 | # This is generally used to communicate timestamped data 19 | # in a particular coordinate frame. 20 | # 21 | # sequence ID: consecutively increasing ID 22 | uint32 seq 23 | #Two-integer timestamp that is expressed as: 24 | # * stamp.secs: seconds (stamp_secs) since epoch 25 | # * stamp.nsecs: nanoseconds since stamp_secs 26 | # time-handling sugar is provided by the client library 27 | time stamp 28 | #Frame this data is associated with 29 | # 0: no frame 30 | # 1: global frame 31 | string frame_id 32 | """ 33 | 34 | order = 0 35 | migrated_types = [] 36 | 37 | valid = True 38 | 39 | def update(self, old_msg, new_msg): 40 | #No matching field name in old message 41 | new_msg.header = self.get_new_class('Header')() 42 | new_msg.axes = old_msg.axes 43 | new_msg.buttons = old_msg.buttons 44 | -------------------------------------------------------------------------------- /joy/package.xml: -------------------------------------------------------------------------------- 1 | 2 | joy 3 | 1.10.1 4 | BSD 5 | 6 | 7 | ROS driver for a generic Linux joystick. 8 | The joy package contains joy_node, a node that interfaces a 9 | generic Linux joystick to ROS. This node publishes a "Joy" 10 | message, which contains the current state of each one of the 11 | joystick's buttons and axes. 12 | 13 | 14 | Jonathan Bohren 15 | Morgan Quigley 16 | Brian Gerkey 17 | Kevin Watts 18 | Blaise Gassend 19 | 20 | http://www.ros.org/wiki/joy 21 | https://github.com/ros-drivers/joystick_drivers 22 | https://github.com/ros-drivers/joystick_drivers/issues 23 | 24 | catkin 25 | 26 | roscpp 27 | diagnostic_updater 28 | sensor_msgs 29 | joystick 30 | 31 | roscpp 32 | diagnostic_updater 33 | sensor_msgs 34 | joystick 35 | 36 | rosbag 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /joy/test/saved/Joy.saved: -------------------------------------------------------------------------------- 1 | [joy/Joy]: 2 | float32[] axes 3 | int32[] buttons 4 | 5 | 6 | -------------------------------------------------------------------------------- /joy/test/test_joy_msg_migration.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Software License Agreement (BSD License) 3 | # 4 | # Copyright (c) 2008, Willow Garage, Inc. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions 9 | # are met: 10 | # 11 | # * Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # * Redistributions in binary form must reproduce the above 14 | # copyright notice, this list of conditions and the following 15 | # disclaimer in the documentation and/or other materials provided 16 | # with the distribution. 17 | # * Neither the name of Willow Garage, Inc. nor the names of its 18 | # contributors may be used to endorse or promote products derived 19 | # from this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | # POSSIBILITY OF SUCH DAMAGE. 33 | # 34 | 35 | import roslib 36 | roslib.load_manifest('joy') 37 | 38 | import sys 39 | import struct 40 | 41 | import unittest 42 | 43 | import rostest 44 | import rosbag 45 | import rosbagmigration 46 | 47 | import re 48 | from cStringIO import StringIO 49 | import os 50 | 51 | import rospy 52 | 53 | 54 | 55 | migrator = rosbagmigration.MessageMigrator() 56 | 57 | 58 | def repack(x): 59 | return struct.unpack('.*/ 18 | 19 | #include 20 | 21 | #include "rosToInterface.hpp" 22 | #define numberOfRobots 1 //this should be set up nicly 23 | #define myID 0 24 | int LED = 13; 25 | char commandQ[numberOfRobots + 1]; //one for the command type 26 | void addEntry(instructionUnion thisUnion); 27 | void sendIR(); 28 | int robotsRecieved = 0; 29 | const int IROUT = 11; 30 | const int IRRecvPin = 3; 31 | 32 | #ifndef cbi 33 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 34 | #endif 35 | #ifndef sbi 36 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 37 | #endif 38 | #define SYSCLOCK 16000000 // main system clock (Hz) 39 | #define PULSECLOCK 38000 // Hz 40 | 41 | SoftwareSerial irserial(IRRecvPin,-1); 42 | 43 | void setup() { 44 | // put your setup code here, to run once: 45 | pinMode(LED, OUTPUT); 46 | digitalWrite(LED, LOW); 47 | Serial.begin(115200); 48 | irserial.begin(2400); 49 | cbi(TCCR2A,COM2A1) ; // connect OC2A (COM2A0 = 1) 50 | sbi(TCCR2A,COM2A0) ; 51 | 52 | cbi(TCCR2B,WGM22) ; // CTC mode for TIMER2 53 | sbi(TCCR2A,WGM21) ; 54 | cbi(TCCR2A,WGM20) ; 55 | 56 | TCNT2 = 0 ; 57 | 58 | cbi(ASSR,AS2) ; // use system clock for timer 2 59 | 60 | OCR2A = 255 ; // set TOP to 255 for now 61 | 62 | cbi(TCCR2B,CS22) ; // TIMER2 prescale = 1 63 | cbi(TCCR2B,CS21) ; 64 | sbi(TCCR2B,CS20) ; 65 | 66 | cbi(TCCR2B,FOC2A) ; // clear forced output compare bits 67 | cbi(TCCR2B,FOC2B) ; 68 | 69 | pinMode(IROUT, OUTPUT) ; // set OC2A to OUPUT 70 | OCR2A = timer2top(PULSECLOCK) ; 71 | sei() ; 72 | } 73 | instructionUnion thisUnion; 74 | int bytesCollected = 0; 75 | void loop() { 76 | if (Serial.available() > 0) { 77 | // read the incoming byte: 78 | thisUnion.bytes[bytesCollected] = Serial.read(); 79 | bytesCollected++; 80 | if(bytesCollected == sizeof thisUnion){ 81 | bytesCollected = 0; 82 | addEntry(thisUnion); 83 | } 84 | 85 | } 86 | } 87 | 88 | void addEntry(instructionUnion thisUnion){ 89 | static int currentCID = 0; 90 | if(thisUnion.pack.robotID == 0){ 91 | commandQ[0] = thisUnion.pack.instructionType; 92 | currentCID = thisUnion.pack.instructionID; 93 | 94 | } 95 | commandQ[thisUnion.pack.robotID + 1] = thisUnion.pack.value1; 96 | if(thisUnion.pack.robotID == numberOfRobots){ 97 | sendIR(); 98 | } 99 | } 100 | 101 | void sendIR(){ 102 | 103 | Serial.write(commandQ, sizeof(commandQ)); 104 | 105 | } 106 | 107 | // return TIMER2 TOP value per given desired frequency (Hz) 108 | uint8_t timer2top(unsigned long freq) { 109 | return((byte)((unsigned long)SYSCLOCK/2/freq) - 1) ; 110 | } 111 | -------------------------------------------------------------------------------- /urobot/InterfaceArduino/rosToInterface.hpp: -------------------------------------------------------------------------------- 1 | ../src/rosToInterface.hpp -------------------------------------------------------------------------------- /urobot/Robot/IRremote/.gitignore: -------------------------------------------------------------------------------- 1 | *.un~ 2 | *.sublime-project 3 | *.sublime-workspace -------------------------------------------------------------------------------- /urobot/Robot/IRremote/.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | 5 | env: 6 | - PLATFORMIO_CI_SRC=examples/AiwaRCT501SendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_AIWA_RC_T501" 7 | - PLATFORMIO_CI_SRC=examples/IRrecord PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" 8 | - PLATFORMIO_CI_SRC=examples/IRrecvDemo 9 | - PLATFORMIO_CI_SRC=examples/IRrecvDump 10 | - PLATFORMIO_CI_SRC=examples/IRrecvDumpV2 11 | - PLATFORMIO_CI_SRC=examples/IRrelay 12 | - PLATFORMIO_CI_SRC=examples/IRsendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_SONY" 13 | - PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" 14 | - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" 15 | - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" 16 | - PLATFORMIO_CI_SRC=examples/IRremoteInfo 17 | 18 | install: 19 | - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" 20 | 21 | script: 22 | - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 23 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/Contributors.md: -------------------------------------------------------------------------------- 1 | ## Contributors 2 | These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. 3 | 4 | - [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. 5 | * Email: zetoslab@gmail.com 6 | * Skype: polarised16 7 | - [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support 8 | - [Informatic](https://github.com/Informatic) : Active contributor 9 | - [fmeschia](https://github.com/fmeschia) : Active contributor 10 | - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor 11 | - [crash7](https://github.com/crash7) : Active contributor 12 | - [Neco777](https://github.com/neco777) : Active contributor 13 | - [Lauszus](https://github.com/lauszus) : Active contributor 14 | - [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. 15 | - [Sebazzz](https://github.com/sebazz): Contributor 16 | - [lumbric](https://github.com/lumbric): Contributor 17 | - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor 18 | 19 | Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. 20 | 21 | 22 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/IRremote.cpp: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // IRremote 3 | // Version 2.0.1 June, 2015 4 | // Copyright 2009 Ken Shirriff 5 | // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html 6 | // 7 | // Modified by Paul Stoffregen to support other boards and timers 8 | // Modified by Mitra Ardron 9 | // Added Sanyo and Mitsubishi controllers 10 | // Modified Sony to spot the repeat codes that some Sony's send 11 | // 12 | // Interrupt code based on NECIRrcv by Joe Knapp 13 | // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 14 | // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ 15 | // 16 | // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) 17 | // LG added by Darryl Smith (based on the JVC protocol) 18 | // Whynter A/C ARC-110WD added by Francesco Meschia 19 | //****************************************************************************** 20 | 21 | #include 22 | 23 | // Defining IR_GLOBAL here allows us to declare the instantiation of global variables 24 | #define IR_GLOBAL 25 | # include "IRremote.h" 26 | # include "IRremoteInt.h" 27 | #undef IR_GLOBAL 28 | 29 | //+============================================================================= 30 | // The match functions were (apparently) originally MACROs to improve code speed 31 | // (although this would have bloated the code) hence the names being CAPS 32 | // A later release implemented debug output and so they needed to be converted 33 | // to functions. 34 | // I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some 35 | // reason, no matter what I did I could not get them to function as macros again. 36 | // I have found a *lot* of bugs in the Arduino compiler over the last few weeks, 37 | // and I am currently assuming that one of these bugs is my problem. 38 | // I may revisit this code at a later date and look at the assembler produced 39 | // in a hope of finding out what is going on, but for now they will remain as 40 | // functions even in non-DEBUG mode 41 | // 42 | int MATCH (int measured, int desired) 43 | { 44 | DBG_PRINT(F("Testing: ")); 45 | DBG_PRINT(TICKS_LOW(desired), DEC); 46 | DBG_PRINT(F(" <= ")); 47 | DBG_PRINT(measured, DEC); 48 | DBG_PRINT(F(" <= ")); 49 | DBG_PRINT(TICKS_HIGH(desired), DEC); 50 | 51 | bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); 52 | if (passed) 53 | DBG_PRINTLN(F("?; passed")); 54 | else 55 | DBG_PRINTLN(F("?; FAILED")); 56 | return passed; 57 | } 58 | 59 | //+======================================================== 60 | // Due to sensor lag, when received, Marks tend to be 100us too long 61 | // 62 | int MATCH_MARK (int measured_ticks, int desired_us) 63 | { 64 | DBG_PRINT(F("Testing mark (actual vs desired): ")); 65 | DBG_PRINT(measured_ticks * USECPERTICK, DEC); 66 | DBG_PRINT(F("us vs ")); 67 | DBG_PRINT(desired_us, DEC); 68 | DBG_PRINT("us"); 69 | DBG_PRINT(": "); 70 | DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); 71 | DBG_PRINT(F(" <= ")); 72 | DBG_PRINT(measured_ticks * USECPERTICK, DEC); 73 | DBG_PRINT(F(" <= ")); 74 | DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS) * USECPERTICK, DEC); 75 | 76 | bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) 77 | && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); 78 | if (passed) 79 | DBG_PRINTLN(F("?; passed")); 80 | else 81 | DBG_PRINTLN(F("?; FAILED")); 82 | return passed; 83 | } 84 | 85 | //+======================================================== 86 | // Due to sensor lag, when received, Spaces tend to be 100us too short 87 | // 88 | int MATCH_SPACE (int measured_ticks, int desired_us) 89 | { 90 | DBG_PRINT(F("Testing space (actual vs desired): ")); 91 | DBG_PRINT(measured_ticks * USECPERTICK, DEC); 92 | DBG_PRINT(F("us vs ")); 93 | DBG_PRINT(desired_us, DEC); 94 | DBG_PRINT("us"); 95 | DBG_PRINT(": "); 96 | DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); 97 | DBG_PRINT(F(" <= ")); 98 | DBG_PRINT(measured_ticks * USECPERTICK, DEC); 99 | DBG_PRINT(F(" <= ")); 100 | DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS) * USECPERTICK, DEC); 101 | 102 | bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) 103 | && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); 104 | if (passed) 105 | DBG_PRINTLN(F("?; passed")); 106 | else 107 | DBG_PRINTLN(F("?; FAILED")); 108 | return passed; 109 | } 110 | 111 | //+============================================================================= 112 | // Interrupt Service Routine - Fires every 50uS 113 | // TIMER2 interrupt code to collect raw data. 114 | // Widths of alternating SPACE, MARK are recorded in rawbuf. 115 | // Recorded in ticks of 50uS [microseconds, 0.000050 seconds] 116 | // 'rawlen' counts the number of entries recorded so far. 117 | // First entry is the SPACE between transmissions. 118 | // As soon as a the first [SPACE] entry gets long: 119 | // Ready is set; State switches to IDLE; Timing of SPACE continues. 120 | // As soon as first MARK arrives: 121 | // Gap width is recorded; Ready is cleared; New logging starts 122 | // 123 | ISR (TIMER_INTR_NAME) 124 | { 125 | TIMER_RESET; 126 | 127 | // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] 128 | // digitalRead() is very slow. Optimisation is possible, but makes the code unportable 129 | uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); 130 | 131 | irparams.timer++; // One more 50uS tick 132 | if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow 133 | 134 | switch(irparams.rcvstate) { 135 | //...................................................................... 136 | case STATE_IDLE: // In the middle of a gap 137 | if (irdata == MARK) { 138 | if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap. 139 | irparams.timer = 0; 140 | 141 | } else { 142 | // Gap just ended; Record duration; Start recording transmission 143 | irparams.overflow = false; 144 | irparams.rawlen = 0; 145 | irparams.rawbuf[irparams.rawlen++] = irparams.timer; 146 | irparams.timer = 0; 147 | irparams.rcvstate = STATE_MARK; 148 | } 149 | } 150 | break; 151 | //...................................................................... 152 | case STATE_MARK: // Timing Mark 153 | if (irdata == SPACE) { // Mark ended; Record time 154 | irparams.rawbuf[irparams.rawlen++] = irparams.timer; 155 | irparams.timer = 0; 156 | irparams.rcvstate = STATE_SPACE; 157 | } 158 | break; 159 | //...................................................................... 160 | case STATE_SPACE: // Timing Space 161 | if (irdata == MARK) { // Space just ended; Record time 162 | irparams.rawbuf[irparams.rawlen++] = irparams.timer; 163 | irparams.timer = 0; 164 | irparams.rcvstate = STATE_MARK; 165 | 166 | } else if (irparams.timer > GAP_TICKS) { // Space 167 | // A long Space, indicates gap between codes 168 | // Flag the current code as ready for processing 169 | // Switch to STOP 170 | // Don't reset timer; keep counting Space width 171 | irparams.rcvstate = STATE_STOP; 172 | } 173 | break; 174 | //...................................................................... 175 | case STATE_STOP: // Waiting; Measuring Gap 176 | if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer 177 | break; 178 | //...................................................................... 179 | case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine 180 | irparams.overflow = true; 181 | irparams.rcvstate = STATE_STOP; 182 | break; 183 | } 184 | 185 | // If requested, flash LED while receiving IR data 186 | if (irparams.blinkflag) { 187 | if (irdata == MARK) 188 | if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on 189 | else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on 190 | else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on 191 | else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/README.md: -------------------------------------------------------------------------------- 1 | # IRremote Arduino Library 2 | 3 | [![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=dev)](https://travis-ci.org/z3t0/Arduino-IRremote) 4 | 5 | [![Join the chat at https://gitter.im/z3t0/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | 7 | This library enables you to send and receive using infra-red signals on an Arduino. 8 | 9 | Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. 10 | 11 | ## Version - 2.1.0 12 | 13 | ## Installation 14 | 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. 15 | 2. Download the latest release. 16 | 3. Extract the zip file 17 | 4. Move the "IRremote" folder that has been extracted to your libraries directory. 18 | 5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors. 19 | 20 | ## Usage 21 | - TODO (Check examples for now) 22 | 23 | ## Contributing 24 | If you want to contribute to this project: 25 | - Report bugs and errors 26 | - Ask for enhancements 27 | - Create issues and pull requests 28 | - Tell other people about this library 29 | - Contribute new protocols 30 | - 31 | 32 | ## Contact 33 | The only way to contact me at the moment is by email: zetoslab@gmail.com 34 | I am not currently monitoring any PRs or Issues due to other issues but will respond to all emails. If anyone wants contributor access, feel free to email me. Or if you find any Issues/PRs to be of importance that my attention is needed please email me. 35 | 36 | ## Contributors 37 | Check [here](Contributors.md) 38 | 39 | ## Copyright 40 | Copyright 2009-2012 Ken Shirriff 41 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/changelog.md: -------------------------------------------------------------------------------- 1 | ## 2.1.0 - 2016/02/20 2 | - Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) 3 | - Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) 4 | 5 | ## 2.0.4 - 2016/02/20 6 | - Add Panasonic and JVC to IRrecord example [PR](https://github.com/z3t0/Arduino-IRremote/pull/54) 7 | 8 | ## 2.0.3 - 2016/02/20 9 | - Change IRSend Raw parameter to const [PR](https://github.com/z3t0/Arduino-IRremote/pull/227) 10 | 11 | ## 2.0.2 - 2015/12/02 12 | - Added IRremoteInfo Sketch - [PR](https://github.com/z3t0/Arduino-IRremote/pull/241) 13 | - Enforcing changelog.md 14 | 15 | ## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) 16 | ### Changes 17 | - Updated README 18 | - Updated Contributors 19 | - Fixed #110 Mess 20 | - Created Gitter Room 21 | - Added Gitter Badge 22 | - Standardised Code Base 23 | - Clean Debug Output 24 | - Optimized Send Loops 25 | - Modularized Design 26 | - Optimized and Updated Examples 27 | - Improved Documentation 28 | - Fixed and Improved many coding errors 29 | - Fixed Aiwa RC-T501 Decoding 30 | - Fixed Interrupt on ATmega8 31 | - Switched to Stable Release of @PlatformIO 32 | 33 | ### Additions 34 | - Added Aiwa RC-T501 Protocol 35 | - Added Denon Protocol 36 | - Added Pronto Support 37 | - Added Library Properties 38 | - Added Template For New Protocols 39 | - Added this changelog 40 | - Added Teensy LC Support 41 | - Added ATtiny84 Support 42 | - Added ATtiny85 Support 43 | - Added isIdle method 44 | 45 | ### Deletions 46 | - Removed (Fixed) #110 47 | - Broke Teensy 3 / 3.1 Support 48 | 49 | ### Not Working 50 | - Teensy 3 / 3.1 Support is in Development 51 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend 3 | * An IR LED must be connected to Arduino PWM pin 3. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | */ 8 | 9 | #include "IRremote.h" 10 | 11 | #define POWER 0x7F80 12 | #define AIWA_RC_T501 13 | 14 | IRsend irsend; 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | Serial.println("Arduino Ready"); 19 | } 20 | 21 | void loop() { 22 | if (Serial.read() != -1) { 23 | irsend.sendAiwaRCT501(POWER); 24 | delay(60); // Optional 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRrecord/IRrecord.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRrecord: record and play back IR signals as a minimal 3 | * An IR detector/demodulator must be connected to the input RECV_PIN. 4 | * An IR LED must be connected to the output PWM pin 3. 5 | * A button must be connected to the input BUTTON_PIN; this is the 6 | * send button. 7 | * A visible LED can be connected to STATUS_PIN to provide status. 8 | * 9 | * The logic is: 10 | * If the button is pressed, send the IR code. 11 | * If an IR code is received, record it. 12 | * 13 | * Version 0.11 September, 2009 14 | * Copyright 2009 Ken Shirriff 15 | * http://arcfn.com 16 | */ 17 | 18 | #include 19 | 20 | int RECV_PIN = 11; 21 | int BUTTON_PIN = 12; 22 | int STATUS_PIN = 13; 23 | 24 | IRrecv irrecv(RECV_PIN); 25 | IRsend irsend; 26 | 27 | decode_results results; 28 | 29 | void setup() 30 | { 31 | Serial.begin(9600); 32 | irrecv.enableIRIn(); // Start the receiver 33 | pinMode(BUTTON_PIN, INPUT); 34 | pinMode(STATUS_PIN, OUTPUT); 35 | } 36 | 37 | // Storage for the recorded code 38 | int codeType = -1; // The type of code 39 | unsigned long codeValue; // The code value if not raw 40 | unsigned int rawCodes[RAWBUF]; // The durations if raw 41 | int codeLen; // The length of the code 42 | int toggle = 0; // The RC5/6 toggle state 43 | 44 | // Stores the code for later playback 45 | // Most of this code is just logging 46 | void storeCode(decode_results *results) { 47 | codeType = results->decode_type; 48 | int count = results->rawlen; 49 | if (codeType == UNKNOWN) { 50 | Serial.println("Received unknown code, saving as raw"); 51 | codeLen = results->rawlen - 1; 52 | // To store raw codes: 53 | // Drop first value (gap) 54 | // Convert from ticks to microseconds 55 | // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion 56 | for (int i = 1; i <= codeLen; i++) { 57 | if (i % 2) { 58 | // Mark 59 | rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS; 60 | Serial.print(" m"); 61 | } 62 | else { 63 | // Space 64 | rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS; 65 | Serial.print(" s"); 66 | } 67 | Serial.print(rawCodes[i - 1], DEC); 68 | } 69 | Serial.println(""); 70 | } 71 | else { 72 | if (codeType == NEC) { 73 | Serial.print("Received NEC: "); 74 | if (results->value == REPEAT) { 75 | // Don't record a NEC repeat value as that's useless. 76 | Serial.println("repeat; ignoring."); 77 | return; 78 | } 79 | } 80 | else if (codeType == SONY) { 81 | Serial.print("Received SONY: "); 82 | } 83 | else if (codeType == PANASONIC) { 84 | Serial.print("Received PANASONIC: "); 85 | } 86 | else if (codeType == JVC) { 87 | Serial.print("Received JVC: "); 88 | } 89 | else if (codeType == RC5) { 90 | Serial.print("Received RC5: "); 91 | } 92 | else if (codeType == RC6) { 93 | Serial.print("Received RC6: "); 94 | } 95 | else { 96 | Serial.print("Unexpected codeType "); 97 | Serial.print(codeType, DEC); 98 | Serial.println(""); 99 | } 100 | Serial.println(results->value, HEX); 101 | codeValue = results->value; 102 | codeLen = results->bits; 103 | } 104 | } 105 | 106 | void sendCode(int repeat) { 107 | if (codeType == NEC) { 108 | if (repeat) { 109 | irsend.sendNEC(REPEAT, codeLen); 110 | Serial.println("Sent NEC repeat"); 111 | } 112 | else { 113 | irsend.sendNEC(codeValue, codeLen); 114 | Serial.print("Sent NEC "); 115 | Serial.println(codeValue, HEX); 116 | } 117 | } 118 | else if (codeType == SONY) { 119 | irsend.sendSony(codeValue, codeLen); 120 | Serial.print("Sent Sony "); 121 | Serial.println(codeValue, HEX); 122 | } 123 | else if (codeType == PANASONIC) { 124 | irsend.sendPanasonic(codeValue, codeLen); 125 | Serial.print("Sent Panasonic"); 126 | Serial.println(codeValue, HEX); 127 | } 128 | else if (codeType == JVC) { 129 | irsend.sendPanasonic(codeValue, codeLen); 130 | Serial.print("Sent JVC"); 131 | Serial.println(codeValue, HEX); 132 | } 133 | else if (codeType == RC5 || codeType == RC6) { 134 | if (!repeat) { 135 | // Flip the toggle bit for a new button press 136 | toggle = 1 - toggle; 137 | } 138 | // Put the toggle bit into the code to send 139 | codeValue = codeValue & ~(1 << (codeLen - 1)); 140 | codeValue = codeValue | (toggle << (codeLen - 1)); 141 | if (codeType == RC5) { 142 | Serial.print("Sent RC5 "); 143 | Serial.println(codeValue, HEX); 144 | irsend.sendRC5(codeValue, codeLen); 145 | } 146 | else { 147 | irsend.sendRC6(codeValue, codeLen); 148 | Serial.print("Sent RC6 "); 149 | Serial.println(codeValue, HEX); 150 | } 151 | } 152 | else if (codeType == UNKNOWN /* i.e. raw */) { 153 | // Assume 38 KHz 154 | irsend.sendRaw(rawCodes, codeLen, 38); 155 | Serial.println("Sent raw"); 156 | } 157 | } 158 | 159 | int lastButtonState; 160 | 161 | void loop() { 162 | // If button pressed, send the code. 163 | int buttonState = digitalRead(BUTTON_PIN); 164 | if (lastButtonState == HIGH && buttonState == LOW) { 165 | Serial.println("Released"); 166 | irrecv.enableIRIn(); // Re-enable receiver 167 | } 168 | 169 | if (buttonState) { 170 | Serial.println("Pressed, sending"); 171 | digitalWrite(STATUS_PIN, HIGH); 172 | sendCode(lastButtonState == buttonState); 173 | digitalWrite(STATUS_PIN, LOW); 174 | delay(50); // Wait a bit between retransmissions 175 | } 176 | else if (irrecv.decode(&results)) { 177 | digitalWrite(STATUS_PIN, HIGH); 178 | storeCode(&results); 179 | irrecv.resume(); // resume receiver 180 | digitalWrite(STATUS_PIN, LOW); 181 | } 182 | lastButtonState = buttonState; 183 | } 184 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRrecvDemo/IRrecvDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv 3 | * An IR detector/demodulator must be connected to the input RECV_PIN. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | */ 8 | 9 | #include 10 | 11 | int RECV_PIN = 11; 12 | 13 | IRrecv irrecv(RECV_PIN); 14 | 15 | decode_results results; 16 | 17 | void setup() 18 | { 19 | Serial.begin(9600); 20 | irrecv.enableIRIn(); // Start the receiver 21 | } 22 | 23 | void loop() { 24 | if (irrecv.decode(&results)) { 25 | Serial.println(results.value, HEX); 26 | irrecv.resume(); // Receive the next value 27 | } 28 | delay(100); 29 | } 30 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRrecvDump/IRrecvDump.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRrecvDump - dump details of IR codes with IRrecv 3 | * An IR detector/demodulator must be connected to the input RECV_PIN. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) 8 | * LG added by Darryl Smith (based on the JVC protocol) 9 | */ 10 | 11 | #include 12 | 13 | /* 14 | * Default is Arduino pin D11. 15 | * You can change this to another available Arduino Pin. 16 | * Your IR receiver should be connected to the pin defined here 17 | */ 18 | int RECV_PIN = 11; 19 | 20 | IRrecv irrecv(RECV_PIN); 21 | 22 | decode_results results; 23 | 24 | void setup() 25 | { 26 | Serial.begin(9600); 27 | irrecv.enableIRIn(); // Start the receiver 28 | } 29 | 30 | 31 | void dump(decode_results *results) { 32 | // Dumps out the decode_results structure. 33 | // Call this after IRrecv::decode() 34 | int count = results->rawlen; 35 | if (results->decode_type == UNKNOWN) { 36 | Serial.print("Unknown encoding: "); 37 | } 38 | else if (results->decode_type == NEC) { 39 | Serial.print("Decoded NEC: "); 40 | 41 | } 42 | else if (results->decode_type == SONY) { 43 | Serial.print("Decoded SONY: "); 44 | } 45 | else if (results->decode_type == RC5) { 46 | Serial.print("Decoded RC5: "); 47 | } 48 | else if (results->decode_type == RC6) { 49 | Serial.print("Decoded RC6: "); 50 | } 51 | else if (results->decode_type == PANASONIC) { 52 | Serial.print("Decoded PANASONIC - Address: "); 53 | Serial.print(results->address, HEX); 54 | Serial.print(" Value: "); 55 | } 56 | else if (results->decode_type == LG) { 57 | Serial.print("Decoded LG: "); 58 | } 59 | else if (results->decode_type == JVC) { 60 | Serial.print("Decoded JVC: "); 61 | } 62 | else if (results->decode_type == AIWA_RC_T501) { 63 | Serial.print("Decoded AIWA RC T501: "); 64 | } 65 | else if (results->decode_type == WHYNTER) { 66 | Serial.print("Decoded Whynter: "); 67 | } 68 | Serial.print(results->value, HEX); 69 | Serial.print(" ("); 70 | Serial.print(results->bits, DEC); 71 | Serial.println(" bits)"); 72 | Serial.print("Raw ("); 73 | Serial.print(count, DEC); 74 | Serial.print("): "); 75 | 76 | for (int i = 1; i < count; i++) { 77 | if (i & 1) { 78 | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); 79 | } 80 | else { 81 | Serial.write('-'); 82 | Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC); 83 | } 84 | Serial.print(" "); 85 | } 86 | Serial.println(); 87 | } 88 | 89 | void loop() { 90 | if (irrecv.decode(&results)) { 91 | Serial.println(results.value, HEX); 92 | dump(&results); 93 | irrecv.resume(); // Receive the next value 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Include the IRremote library header 3 | // 4 | #include 5 | 6 | //------------------------------------------------------------------------------ 7 | // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) 8 | // 9 | int recvPin = 11; 10 | IRrecv irrecv(recvPin); 11 | 12 | //+============================================================================= 13 | // Configure the Arduino 14 | // 15 | void setup ( ) 16 | { 17 | Serial.begin(9600); // Status message will be sent to PC at 9600 baud 18 | irrecv.enableIRIn(); // Start the receiver 19 | } 20 | 21 | //+============================================================================= 22 | // Display IR code 23 | // 24 | void ircode (decode_results *results) 25 | { 26 | // Panasonic has an Address 27 | if (results->decode_type == PANASONIC) { 28 | Serial.print(results->address, HEX); 29 | Serial.print(":"); 30 | } 31 | 32 | // Print Code 33 | Serial.print(results->value, HEX); 34 | } 35 | 36 | //+============================================================================= 37 | // Display encoding type 38 | // 39 | void encoding (decode_results *results) 40 | { 41 | switch (results->decode_type) { 42 | default: 43 | case UNKNOWN: Serial.print("UNKNOWN"); break ; 44 | case NEC: Serial.print("NEC"); break ; 45 | case SONY: Serial.print("SONY"); break ; 46 | case RC5: Serial.print("RC5"); break ; 47 | case RC6: Serial.print("RC6"); break ; 48 | case DISH: Serial.print("DISH"); break ; 49 | case SHARP: Serial.print("SHARP"); break ; 50 | case JVC: Serial.print("JVC"); break ; 51 | case SANYO: Serial.print("SANYO"); break ; 52 | case MITSUBISHI: Serial.print("MITSUBISHI"); break ; 53 | case SAMSUNG: Serial.print("SAMSUNG"); break ; 54 | case LG: Serial.print("LG"); break ; 55 | case WHYNTER: Serial.print("WHYNTER"); break ; 56 | case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ; 57 | case PANASONIC: Serial.print("PANASONIC"); break ; 58 | case DENON: Serial.print("Denon"); break ; 59 | } 60 | } 61 | 62 | //+============================================================================= 63 | // Dump out the decode_results structure. 64 | // 65 | void dumpInfo (decode_results *results) 66 | { 67 | // Check if the buffer overflowed 68 | if (results->overflow) { 69 | Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN"); 70 | return; 71 | } 72 | 73 | // Show Encoding standard 74 | Serial.print("Encoding : "); 75 | encoding(results); 76 | Serial.println(""); 77 | 78 | // Show Code & length 79 | Serial.print("Code : "); 80 | ircode(results); 81 | Serial.print(" ("); 82 | Serial.print(results->bits, DEC); 83 | Serial.println(" bits)"); 84 | } 85 | 86 | //+============================================================================= 87 | // Dump out the decode_results structure. 88 | // 89 | void dumpRaw (decode_results *results) 90 | { 91 | // Print Raw data 92 | Serial.print("Timing["); 93 | Serial.print(results->rawlen-1, DEC); 94 | Serial.println("]: "); 95 | 96 | for (int i = 1; i < results->rawlen; i++) { 97 | unsigned long x = results->rawbuf[i] * USECPERTICK; 98 | if (!(i & 1)) { // even 99 | Serial.print("-"); 100 | if (x < 1000) Serial.print(" ") ; 101 | if (x < 100) Serial.print(" ") ; 102 | Serial.print(x, DEC); 103 | } else { // odd 104 | Serial.print(" "); 105 | Serial.print("+"); 106 | if (x < 1000) Serial.print(" ") ; 107 | if (x < 100) Serial.print(" ") ; 108 | Serial.print(x, DEC); 109 | if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one 110 | } 111 | if (!(i % 8)) Serial.println(""); 112 | } 113 | Serial.println(""); // Newline 114 | } 115 | 116 | //+============================================================================= 117 | // Dump out the decode_results structure. 118 | // 119 | void dumpCode (decode_results *results) 120 | { 121 | // Start declaration 122 | Serial.print("unsigned int "); // variable type 123 | Serial.print("rawData["); // array name 124 | Serial.print(results->rawlen - 1, DEC); // array size 125 | Serial.print("] = {"); // Start declaration 126 | 127 | // Dump data 128 | for (int i = 1; i < results->rawlen; i++) { 129 | Serial.print(results->rawbuf[i] * USECPERTICK, DEC); 130 | if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one 131 | if (!(i & 1)) Serial.print(" "); 132 | } 133 | 134 | // End declaration 135 | Serial.print("};"); // 136 | 137 | // Comment 138 | Serial.print(" // "); 139 | encoding(results); 140 | Serial.print(" "); 141 | ircode(results); 142 | 143 | // Newline 144 | Serial.println(""); 145 | 146 | // Now dump "known" codes 147 | if (results->decode_type != UNKNOWN) { 148 | 149 | // Some protocols have an address 150 | if (results->decode_type == PANASONIC) { 151 | Serial.print("unsigned int addr = 0x"); 152 | Serial.print(results->address, HEX); 153 | Serial.println(";"); 154 | } 155 | 156 | // All protocols have data 157 | Serial.print("unsigned int data = 0x"); 158 | Serial.print(results->value, HEX); 159 | Serial.println(";"); 160 | } 161 | } 162 | 163 | //+============================================================================= 164 | // The repeating section of the code 165 | // 166 | void loop ( ) 167 | { 168 | decode_results results; // Somewhere to store the results 169 | 170 | if (irrecv.decode(&results)) { // Grab an IR code 171 | dumpInfo(&results); // Output the results 172 | dumpRaw(&results); // Output the results in RAW format 173 | dumpCode(&results); // Output the results as source code 174 | Serial.println(""); // Blank line between entries 175 | irrecv.resume(); // Prepare for the next value 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRrelay/IRrelay.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv 3 | * An IR detector/demodulator must be connected to the input RECV_PIN. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | */ 8 | 9 | #include 10 | 11 | int RECV_PIN = 11; 12 | int RELAY_PIN = 4; 13 | 14 | IRrecv irrecv(RECV_PIN); 15 | decode_results results; 16 | 17 | // Dumps out the decode_results structure. 18 | // Call this after IRrecv::decode() 19 | // void * to work around compiler issue 20 | //void dump(void *v) { 21 | // decode_results *results = (decode_results *)v 22 | void dump(decode_results *results) { 23 | int count = results->rawlen; 24 | if (results->decode_type == UNKNOWN) { 25 | Serial.println("Could not decode message"); 26 | } 27 | else { 28 | if (results->decode_type == NEC) { 29 | Serial.print("Decoded NEC: "); 30 | } 31 | else if (results->decode_type == SONY) { 32 | Serial.print("Decoded SONY: "); 33 | } 34 | else if (results->decode_type == RC5) { 35 | Serial.print("Decoded RC5: "); 36 | } 37 | else if (results->decode_type == RC6) { 38 | Serial.print("Decoded RC6: "); 39 | } 40 | Serial.print(results->value, HEX); 41 | Serial.print(" ("); 42 | Serial.print(results->bits, DEC); 43 | Serial.println(" bits)"); 44 | } 45 | Serial.print("Raw ("); 46 | Serial.print(count, DEC); 47 | Serial.print("): "); 48 | 49 | for (int i = 0; i < count; i++) { 50 | if ((i % 2) == 1) { 51 | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); 52 | } 53 | else { 54 | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); 55 | } 56 | Serial.print(" "); 57 | } 58 | Serial.println(""); 59 | } 60 | 61 | void setup() 62 | { 63 | pinMode(RELAY_PIN, OUTPUT); 64 | pinMode(13, OUTPUT); 65 | Serial.begin(9600); 66 | irrecv.enableIRIn(); // Start the receiver 67 | } 68 | 69 | int on = 0; 70 | unsigned long last = millis(); 71 | 72 | void loop() { 73 | if (irrecv.decode(&results)) { 74 | // If it's been at least 1/4 second since the last 75 | // IR received, toggle the relay 76 | if (millis() - last > 250) { 77 | on = !on; 78 | digitalWrite(RELAY_PIN, on ? HIGH : LOW); 79 | digitalWrite(13, on ? HIGH : LOW); 80 | dump(&results); 81 | } 82 | last = millis(); 83 | irrecv.resume(); // Receive the next value 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRsendDemo/IRsendDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend 3 | * An IR LED must be connected to Arduino PWM pin 3. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | */ 8 | 9 | 10 | #include 11 | 12 | IRsend irsend; 13 | 14 | void setup() 15 | { 16 | } 17 | 18 | void loop() { 19 | for (int i = 0; i < 3; i++) { 20 | irsend.sendSony(0xa90, 12); 21 | delay(40); 22 | } 23 | delay(5000); //5 second delay between each signal burst 24 | } 25 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw 3 | * An IR LED must be connected to Arduino PWM pin 3. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | * 8 | * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 9 | * 10 | * This example shows how to send a RAW signal using the IRremote library. 11 | * The example signal is actually a 32 bit NEC signal. 12 | * Remote Control button: LGTV Power On/Off. 13 | * Hex Value: 0x20DF10EF, 32 bits 14 | * 15 | * It is more efficient to use the sendNEC function to send NEC signals. 16 | * Use of sendRaw here, serves only as an example of using the function. 17 | * 18 | */ 19 | 20 | 21 | #include 22 | 23 | IRsend irsend; 24 | 25 | void setup() 26 | { 27 | 28 | } 29 | 30 | void loop() { 31 | int khz = 38; // 38kHz carrier frequency for the NEC protocol 32 | unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW 33 | 34 | irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. 35 | 36 | delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. 37 | } 38 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/IRtest/IRtest.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRtest unittest 3 | * Version 0.1 July, 2009 4 | * Copyright 2009 Ken Shirriff 5 | * http://arcfn.com 6 | * 7 | * Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST" 8 | * You must then recompile the library by removing IRremote.o and restarting 9 | * the arduino IDE. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | // Dumps out the decode_results structure. 16 | // Call this after IRrecv::decode() 17 | // void * to work around compiler issue 18 | //void dump(void *v) { 19 | // decode_results *results = (decode_results *)v 20 | void dump(decode_results *results) { 21 | int count = results->rawlen; 22 | if (results->decode_type == UNKNOWN) { 23 | Serial.println("Could not decode message"); 24 | } 25 | else { 26 | if (results->decode_type == NEC) { 27 | Serial.print("Decoded NEC: "); 28 | } 29 | else if (results->decode_type == SONY) { 30 | Serial.print("Decoded SONY: "); 31 | } 32 | else if (results->decode_type == RC5) { 33 | Serial.print("Decoded RC5: "); 34 | } 35 | else if (results->decode_type == RC6) { 36 | Serial.print("Decoded RC6: "); 37 | } 38 | Serial.print(results->value, HEX); 39 | Serial.print(" ("); 40 | Serial.print(results->bits, DEC); 41 | Serial.println(" bits)"); 42 | } 43 | Serial.print("Raw ("); 44 | Serial.print(count, DEC); 45 | Serial.print("): "); 46 | 47 | for (int i = 0; i < count; i++) { 48 | if ((i % 2) == 1) { 49 | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); 50 | } 51 | else { 52 | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); 53 | } 54 | Serial.print(" "); 55 | } 56 | Serial.println(""); 57 | } 58 | 59 | IRrecv irrecv(0); 60 | decode_results results; 61 | 62 | class IRsendDummy : 63 | public IRsend 64 | { 65 | public: 66 | // For testing, just log the marks/spaces 67 | #define SENDLOG_LEN 128 68 | int sendlog[SENDLOG_LEN]; 69 | int sendlogcnt; 70 | IRsendDummy() : 71 | IRsend() { 72 | } 73 | void reset() { 74 | sendlogcnt = 0; 75 | } 76 | void mark(int time) { 77 | sendlog[sendlogcnt] = time; 78 | if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; 79 | } 80 | void space(int time) { 81 | sendlog[sendlogcnt] = -time; 82 | if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; 83 | } 84 | // Copies the dummy buf into the interrupt buf 85 | void useDummyBuf() { 86 | int last = SPACE; 87 | irparams.rcvstate = STATE_STOP; 88 | irparams.rawlen = 1; // Skip the gap 89 | for (int i = 0 ; i < sendlogcnt; i++) { 90 | if (sendlog[i] < 0) { 91 | if (last == MARK) { 92 | // New space 93 | irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK; 94 | last = SPACE; 95 | } 96 | else { 97 | // More space 98 | irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK; 99 | } 100 | } 101 | else if (sendlog[i] > 0) { 102 | if (last == SPACE) { 103 | // New mark 104 | irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK; 105 | last = MARK; 106 | } 107 | else { 108 | // More mark 109 | irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK; 110 | } 111 | } 112 | } 113 | if (irparams.rawlen % 2) { 114 | irparams.rawlen--; // Remove trailing space 115 | } 116 | } 117 | }; 118 | 119 | IRsendDummy irsenddummy; 120 | 121 | void verify(unsigned long val, int bits, int type) { 122 | irsenddummy.useDummyBuf(); 123 | irrecv.decode(&results); 124 | Serial.print("Testing "); 125 | Serial.print(val, HEX); 126 | if (results.value == val && results.bits == bits && results.decode_type == type) { 127 | Serial.println(": OK"); 128 | } 129 | else { 130 | Serial.println(": Error"); 131 | dump(&results); 132 | } 133 | } 134 | 135 | void testNEC(unsigned long val, int bits) { 136 | irsenddummy.reset(); 137 | irsenddummy.sendNEC(val, bits); 138 | verify(val, bits, NEC); 139 | } 140 | void testSony(unsigned long val, int bits) { 141 | irsenddummy.reset(); 142 | irsenddummy.sendSony(val, bits); 143 | verify(val, bits, SONY); 144 | } 145 | void testRC5(unsigned long val, int bits) { 146 | irsenddummy.reset(); 147 | irsenddummy.sendRC5(val, bits); 148 | verify(val, bits, RC5); 149 | } 150 | void testRC6(unsigned long val, int bits) { 151 | irsenddummy.reset(); 152 | irsenddummy.sendRC6(val, bits); 153 | verify(val, bits, RC6); 154 | } 155 | 156 | void test() { 157 | Serial.println("NEC tests"); 158 | testNEC(0x00000000, 32); 159 | testNEC(0xffffffff, 32); 160 | testNEC(0xaaaaaaaa, 32); 161 | testNEC(0x55555555, 32); 162 | testNEC(0x12345678, 32); 163 | Serial.println("Sony tests"); 164 | testSony(0xfff, 12); 165 | testSony(0x000, 12); 166 | testSony(0xaaa, 12); 167 | testSony(0x555, 12); 168 | testSony(0x123, 12); 169 | Serial.println("RC5 tests"); 170 | testRC5(0xfff, 12); 171 | testRC5(0x000, 12); 172 | testRC5(0xaaa, 12); 173 | testRC5(0x555, 12); 174 | testRC5(0x123, 12); 175 | Serial.println("RC6 tests"); 176 | testRC6(0xfffff, 20); 177 | testRC6(0x00000, 20); 178 | testRC6(0xaaaaa, 20); 179 | testRC6(0x55555, 20); 180 | testRC6(0x12345, 20); 181 | } 182 | 183 | void setup() 184 | { 185 | Serial.begin(9600); 186 | test(); 187 | } 188 | 189 | void loop() { 190 | } 191 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend 3 | * An IR LED must be connected to Arduino PWM pin 3. 4 | * Version 0.1 July, 2009 5 | * Copyright 2009 Ken Shirriff 6 | * http://arcfn.com 7 | * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) 8 | */ 9 | #include 10 | 11 | #define PanasonicAddress 0x4004 // Panasonic address (Pre data) 12 | #define PanasonicPower 0x100BCBD // Panasonic Power button 13 | 14 | #define JVCPower 0xC5E8 15 | 16 | IRsend irsend; 17 | 18 | void setup() 19 | { 20 | } 21 | 22 | void loop() { 23 | irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off 24 | 25 | irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat 26 | delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information 27 | irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat 28 | delayMicroseconds(50); 29 | } 30 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/LGACSendDemo/LGACSendDemo.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | IRsend irsend; 6 | // not used 7 | int RECV_PIN = 11; 8 | IRrecv irrecv (RECV_PIN); 9 | 10 | const int AC_TYPE = 0; 11 | // 0 : TOWER 12 | // 1 : WALL 13 | // 14 | 15 | int AC_HEAT = 0; 16 | // 0 : cooling 17 | // 1 : heating 18 | 19 | int AC_POWER_ON = 0; 20 | // 0 : off 21 | // 1 : on 22 | 23 | int AC_AIR_ACLEAN = 0; 24 | // 0 : off 25 | // 1 : on --> power on 26 | 27 | int AC_TEMPERATURE = 27; 28 | // temperature : 18 ~ 30 29 | 30 | int AC_FLOW = 1; 31 | // 0 : low 32 | // 1 : mid 33 | // 2 : high 34 | // if AC_TYPE =1, 3 : change 35 | // 36 | 37 | 38 | const int AC_FLOW_TOWER[3] = {0, 4, 6}; 39 | const int AC_FLOW_WALL[4] = {0, 2, 4, 5}; 40 | 41 | unsigned long AC_CODE_TO_SEND; 42 | 43 | int r = LOW; 44 | int o_r = LOW; 45 | 46 | byte a, b; 47 | 48 | void ac_send_code(unsigned long code) 49 | { 50 | Serial.print("code to send : "); 51 | Serial.print(code, BIN); 52 | Serial.print(" : "); 53 | Serial.println(code, HEX); 54 | 55 | irsend.sendLG(code, 28); 56 | } 57 | 58 | void ac_activate(int temperature, int air_flow) 59 | { 60 | 61 | int AC_MSBITS1 = 8; 62 | int AC_MSBITS2 = 8; 63 | int AC_MSBITS3 = 0; 64 | int AC_MSBITS4 ; 65 | if ( AC_HEAT == 1 ) { 66 | // heating 67 | AC_MSBITS4 = 4; 68 | } else { 69 | // cooling 70 | AC_MSBITS4 = 0; 71 | } 72 | int AC_MSBITS5 = temperature - 15; 73 | int AC_MSBITS6 ; 74 | 75 | if ( AC_TYPE == 0) { 76 | AC_MSBITS6 = AC_FLOW_TOWER[air_flow]; 77 | } else { 78 | AC_MSBITS6 = AC_FLOW_WALL[air_flow]; 79 | } 80 | 81 | int AC_MSBITS7 = (AC_MSBITS3 + AC_MSBITS4 + AC_MSBITS5 + AC_MSBITS6) & B00001111; 82 | 83 | AC_CODE_TO_SEND = AC_MSBITS1 << 4 ; 84 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS2) << 4; 85 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS3) << 4; 86 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS4) << 4; 87 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS5) << 4; 88 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS6) << 4; 89 | AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS7); 90 | 91 | ac_send_code(AC_CODE_TO_SEND); 92 | 93 | AC_POWER_ON = 1; 94 | AC_TEMPERATURE = temperature; 95 | AC_FLOW = air_flow; 96 | } 97 | 98 | void ac_change_air_swing(int air_swing) 99 | { 100 | if ( AC_TYPE == 0) { 101 | if ( air_swing == 1) { 102 | AC_CODE_TO_SEND = 0x881316B; 103 | } else { 104 | AC_CODE_TO_SEND = 0x881317C; 105 | } 106 | } else { 107 | if ( air_swing == 1) { 108 | AC_CODE_TO_SEND = 0x8813149; 109 | } else { 110 | AC_CODE_TO_SEND = 0x881315A; 111 | } 112 | } 113 | 114 | ac_send_code(AC_CODE_TO_SEND); 115 | } 116 | 117 | void ac_power_down() 118 | { 119 | AC_CODE_TO_SEND = 0x88C0051; 120 | 121 | ac_send_code(AC_CODE_TO_SEND); 122 | 123 | AC_POWER_ON = 0; 124 | } 125 | 126 | void ac_air_clean(int air_clean) 127 | { 128 | if ( air_clean == 1) { 129 | AC_CODE_TO_SEND = 0x88C000C; 130 | } else { 131 | AC_CODE_TO_SEND = 0x88C0084; 132 | } 133 | 134 | ac_send_code(AC_CODE_TO_SEND); 135 | 136 | AC_AIR_ACLEAN = air_clean; 137 | } 138 | 139 | void setup() 140 | { 141 | Serial.begin(38400); 142 | delay(1000); 143 | Wire.begin(7); 144 | Wire.onReceive(receiveEvent); 145 | 146 | Serial.println(" - - - T E S T - - - "); 147 | 148 | /* test 149 | ac_activate(25, 1); 150 | delay(5000); 151 | ac_activate(27, 2); 152 | delay(5000); 153 | 154 | */ 155 | } 156 | 157 | void loop() 158 | { 159 | 160 | 161 | ac_activate(25, 1); 162 | delay(5000); 163 | ac_activate(27, 0); 164 | delay(5000); 165 | 166 | 167 | if ( r != o_r) { 168 | 169 | /* 170 | # a : mode or temp b : air_flow, temp, swing, clean, cooling/heating 171 | # 18 ~ 30 : temp 0 ~ 2 : flow // on 172 | # 0 : off 0 173 | # 1 : on 0 174 | # 2 : air_swing 0 or 1 175 | # 3 : air_clean 0 or 1 176 | # 4 : air_flow 0 ~ 2 : flow 177 | # 5 : temp 18 ~ 30 178 | # + : temp + 1 179 | # - : temp - 1 180 | # m : change cooling to air clean, air clean to cooling 181 | */ 182 | Serial.print("a : "); 183 | Serial.print(a); 184 | Serial.print(" b : "); 185 | Serial.println(b); 186 | 187 | switch (a) { 188 | case 0: // off 189 | ac_power_down(); 190 | break; 191 | case 1: // on 192 | ac_activate(AC_TEMPERATURE, AC_FLOW); 193 | break; 194 | case 2: 195 | if ( b == 0 | b == 1 ) { 196 | ac_change_air_swing(b); 197 | } 198 | break; 199 | case 3: // 1 : clean on, power on 200 | if ( b == 0 | b == 1 ) { 201 | ac_air_clean(b); 202 | } 203 | break; 204 | case 4: 205 | if ( 0 <= b && b <= 2 ) { 206 | ac_activate(AC_TEMPERATURE, b); 207 | } 208 | break; 209 | case 5: 210 | if (18 <= b && b <= 30 ) { 211 | ac_activate(b, AC_FLOW); 212 | } 213 | break; 214 | case '+': 215 | if ( 18 <= AC_TEMPERATURE && AC_TEMPERATURE <= 29 ) { 216 | ac_activate((AC_TEMPERATURE + 1), AC_FLOW); 217 | } 218 | break; 219 | case '-': 220 | if ( 19 <= AC_TEMPERATURE && AC_TEMPERATURE <= 30 ) { 221 | ac_activate((AC_TEMPERATURE - 1), AC_FLOW); 222 | } 223 | break; 224 | case 'm': 225 | /* 226 | if ac is on, 1) turn off, 2) turn on ac_air_clean(1) 227 | if ac is off, 1) turn on, 2) turn off ac_air_clean(0) 228 | */ 229 | if ( AC_POWER_ON == 1 ) { 230 | ac_power_down(); 231 | delay(100); 232 | ac_air_clean(1); 233 | } else { 234 | if ( AC_AIR_ACLEAN == 1) { 235 | ac_air_clean(0); 236 | delay(100); 237 | } 238 | ac_activate(AC_TEMPERATURE, AC_FLOW); 239 | } 240 | break; 241 | default: 242 | if ( 18 <= a && a <= 30 ) { 243 | if ( 0 <= b && b <= 2 ) { 244 | ac_activate(a, b); 245 | } 246 | } 247 | } 248 | 249 | o_r = r ; 250 | } 251 | delay(100); 252 | } 253 | 254 | 255 | 256 | void receiveEvent(int howMany) 257 | { 258 | a = Wire.read(); 259 | b = Wire.read(); 260 | r = !r ; 261 | } 262 | 263 | 264 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/examples/LGACSendDemo/LGACSendDemo.md: -------------------------------------------------------------------------------- 1 | === decoding for LG A/C ==== 2 | - 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000 3 | - 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem 4 | - 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/ 5 | - 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8 6 | - 5) remove first two byte(11) 7 | - 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860 8 | 9 | 10 | === *** === 11 | - 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d 12 | - 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 13 | 14 | 15 | === *** === 16 | - (0) : Cooling or Heating 17 | - (1) : fixed 18 | - (2) : fixed 19 | - (3) : special(power, swing, air clean) 20 | - (4) : change air flow, temperature, cooling(0)/heating(4) 21 | - (5) : temperature ( 15 + (5) = ) 22 | - (6) : air flow 23 | - (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 24 | 25 | 26 | °F = °C × 1.8 + 32 27 | °C = (°F − 32) / 1.8 28 | 29 | 30 | === *** === 31 | * remote / Korea / without heating 32 | 33 | | status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) 34 | |----------------|---|----|----|----|----|----|----|---- 35 | | on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 36 | | on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 37 | | on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 38 | | on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 39 | | on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 40 | | on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 41 | | on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 42 | | on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 43 | |----------------|---|----|----|----|----|----|----|---- 44 | | 1 up | C |1000|1000|0000|1000|1101|0100|1001 45 | |----------------|---|----|----|----|----|----|----|---- 46 | | Cool power | C |1000|1000|0001|0000|0000|1100|1101 47 | | energy saving | C |1000|1000|0001|0000|0000|0100|0101 48 | | power | C |1000|1000|0001|0000|0000|1000|1001 49 | | flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 50 | | up/down off | C |1000|1000|0001|0011|0001|0101|1010 51 | | flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 52 | | left/right off | C |1000|1000|0001|0011|0001|0111|1100 53 | |----------------|---|----|----|----|----|----|----|---- 54 | | Air clean | C |1000|1000|1100|0000|0000|0000|1100 55 | |----------------|---|----|----|----|----|----|----|---- 56 | | off | C |1000|1000|1100|0000|0000|0101|0001 57 | 58 | 59 | 60 | * remote / with heating 61 | * converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf 62 | 63 | | status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) 64 | |----------------|---|----|----|----|----|----|----|---- 65 | | on | C |1000|1000|0000|0000|1011|0010|1101 66 | |----------------|---|----|----|----|----|----|----|---- 67 | | off | C |1000|1000|1100|0000|0000|0101|0001 68 | |----------------|---|----|----|----|----|----|----|---- 69 | | 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111 70 | | 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000 71 | | 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001 72 | | 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010 73 | | 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011 74 | | 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100 75 | | 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110 76 | | 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111 77 | | 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 78 | | 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 79 | | 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 80 | | 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011 81 | |----------------|---|----|----|----|----|----|----|---- 82 | | heat64 | H |1000|1000|0000|0100|0011|0100|1011 83 | | heat66 | H |1000|1000|0000|0100|0100|0100|1100 84 | | heat68 | H |1000|1000|0000|0100|0101|0100|1101 85 | | heat70 | H |1000|1000|0000|0100|0110|0100|1110 86 | | heat72 | H |1000|1000|0000|0100|0111|0100|1111 87 | | heat74 | H |1000|1000|0000|0100|1000|0100|0000 88 | | heat76 | H |1000|1000|0000|0100|1001|0100|0001 89 | | heat78 | H |1000|1000|0000|0100|1011|0100|0011 90 | | heat80 | H |1000|1000|0000|0100|1100|0100|0100 91 | | heat82 | H |1000|1000|0000|0100|1101|0100|0101 92 | | heat84 | H |1000|1000|0000|0100|1110|0100|0110 93 | | heat86 | H |1000|1000|0000|0100|1111|0100|0111 94 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/irRecv.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //+============================================================================= 5 | // Decodes the received IR message 6 | // Returns 0 if no data ready, 1 if data ready. 7 | // Results of decoding are stored in results 8 | // 9 | int IRrecv::decode (decode_results *results) 10 | { 11 | results->rawbuf = irparams.rawbuf; 12 | results->rawlen = irparams.rawlen; 13 | 14 | results->overflow = irparams.overflow; 15 | 16 | if (irparams.rcvstate != STATE_STOP) return false ; 17 | 18 | #if DECODE_NEC 19 | DBG_PRINTLN("Attempting NEC decode"); 20 | if (decodeNEC(results)) return true ; 21 | #endif 22 | 23 | #if DECODE_SONY 24 | DBG_PRINTLN("Attempting Sony decode"); 25 | if (decodeSony(results)) return true ; 26 | #endif 27 | 28 | #if DECODE_SANYO 29 | DBG_PRINTLN("Attempting Sanyo decode"); 30 | if (decodeSanyo(results)) return true ; 31 | #endif 32 | 33 | #if DECODE_MITSUBISHI 34 | DBG_PRINTLN("Attempting Mitsubishi decode"); 35 | if (decodeMitsubishi(results)) return true ; 36 | #endif 37 | 38 | #if DECODE_RC5 39 | DBG_PRINTLN("Attempting RC5 decode"); 40 | if (decodeRC5(results)) return true ; 41 | #endif 42 | 43 | #if DECODE_RC6 44 | DBG_PRINTLN("Attempting RC6 decode"); 45 | if (decodeRC6(results)) return true ; 46 | #endif 47 | 48 | #if DECODE_PANASONIC 49 | DBG_PRINTLN("Attempting Panasonic decode"); 50 | if (decodePanasonic(results)) return true ; 51 | #endif 52 | 53 | #if DECODE_LG 54 | DBG_PRINTLN("Attempting LG decode"); 55 | if (decodeLG(results)) return true ; 56 | #endif 57 | 58 | #if DECODE_JVC 59 | DBG_PRINTLN("Attempting JVC decode"); 60 | if (decodeJVC(results)) return true ; 61 | #endif 62 | 63 | #if DECODE_SAMSUNG 64 | DBG_PRINTLN("Attempting SAMSUNG decode"); 65 | if (decodeSAMSUNG(results)) return true ; 66 | #endif 67 | 68 | #if DECODE_WHYNTER 69 | DBG_PRINTLN("Attempting Whynter decode"); 70 | if (decodeWhynter(results)) return true ; 71 | #endif 72 | 73 | #if DECODE_AIWA_RC_T501 74 | DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); 75 | if (decodeAiwaRCT501(results)) return true ; 76 | #endif 77 | 78 | #if DECODE_DENON 79 | DBG_PRINTLN("Attempting Denon decode"); 80 | if (decodeDenon(results)) return true ; 81 | #endif 82 | 83 | // decodeHash returns a hash on any input. 84 | // Thus, it needs to be last in the list. 85 | // If you add any decodes, add them before this. 86 | if (decodeHash(results)) return true ; 87 | 88 | // Throw away and start over 89 | resume(); 90 | return false; 91 | } 92 | 93 | //+============================================================================= 94 | IRrecv::IRrecv (int recvpin) 95 | { 96 | irparams.recvpin = recvpin; 97 | irparams.blinkflag = 0; 98 | } 99 | 100 | IRrecv::IRrecv (int recvpin, int blinkpin) 101 | { 102 | irparams.recvpin = recvpin; 103 | irparams.blinkpin = blinkpin; 104 | pinMode(blinkpin, OUTPUT); 105 | irparams.blinkflag = 0; 106 | } 107 | 108 | 109 | 110 | //+============================================================================= 111 | // initialization 112 | // 113 | void IRrecv::enableIRIn ( ) 114 | { 115 | cli(); 116 | // Setup pulse clock timer interrupt 117 | // Prescale /8 (16M/8 = 0.5 microseconds per tick) 118 | // Therefore, the timer interval can range from 0.5 to 128 microseconds 119 | // Depending on the reset value (255 to 0) 120 | TIMER_CONFIG_NORMAL(); 121 | 122 | // Timer2 Overflow Interrupt Enable 123 | TIMER_ENABLE_INTR; 124 | 125 | TIMER_RESET; 126 | 127 | sei(); // enable interrupts 128 | 129 | // Initialize state machine variables 130 | irparams.rcvstate = STATE_IDLE; 131 | irparams.rawlen = 0; 132 | 133 | // Set pin modes 134 | pinMode(irparams.recvpin, INPUT); 135 | } 136 | 137 | //+============================================================================= 138 | // Enable/disable blinking of pin 13 on IR processing 139 | // 140 | void IRrecv::blink13 (int blinkflag) 141 | { 142 | irparams.blinkflag = blinkflag; 143 | if (blinkflag) pinMode(BLINKLED, OUTPUT) ; 144 | } 145 | 146 | //+============================================================================= 147 | // Return if receiving new IR signals 148 | // 149 | bool IRrecv::isIdle ( ) 150 | { 151 | return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; 152 | } 153 | //+============================================================================= 154 | // Restart the ISR state machine 155 | // 156 | void IRrecv::resume ( ) 157 | { 158 | irparams.rcvstate = STATE_IDLE; 159 | irparams.rawlen = 0; 160 | } 161 | 162 | //+============================================================================= 163 | // hashdecode - decode an arbitrary IR code. 164 | // Instead of decoding using a standard encoding scheme 165 | // (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. 166 | // 167 | // The algorithm: look at the sequence of MARK signals, and see if each one 168 | // is shorter (0), the same length (1), or longer (2) than the previous. 169 | // Do the same with the SPACE signals. Hash the resulting sequence of 0's, 170 | // 1's, and 2's to a 32-bit value. This will give a unique value for each 171 | // different code (probably), for most code systems. 172 | // 173 | // http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html 174 | // 175 | // Compare two tick values, returning 0 if newval is shorter, 176 | // 1 if newval is equal, and 2 if newval is longer 177 | // Use a tolerance of 20% 178 | // 179 | int IRrecv::compare (unsigned int oldval, unsigned int newval) 180 | { 181 | if (newval < oldval * .8) return 0 ; 182 | else if (oldval < newval * .8) return 2 ; 183 | else return 1 ; 184 | } 185 | 186 | //+============================================================================= 187 | // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param 188 | // Converts the raw code values into a 32-bit hash code. 189 | // Hopefully this code is unique for each button. 190 | // This isn't a "real" decoding, just an arbitrary value. 191 | // 192 | #define FNV_PRIME_32 16777619 193 | #define FNV_BASIS_32 2166136261 194 | 195 | long IRrecv::decodeHash (decode_results *results) 196 | { 197 | long hash = FNV_BASIS_32; 198 | 199 | // Require at least 6 samples to prevent triggering on noise 200 | if (results->rawlen < 6) return false ; 201 | 202 | for (int i = 1; (i + 2) < results->rawlen; i++) { 203 | int value = compare(results->rawbuf[i], results->rawbuf[i+2]); 204 | // Add value into the hash 205 | hash = (hash * FNV_PRIME_32) ^ value; 206 | } 207 | 208 | results->value = hash; 209 | results->bits = 32; 210 | results->decode_type = UNKNOWN; 211 | 212 | return true; 213 | } 214 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/irSend.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //+============================================================================= 5 | void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) 6 | { 7 | // Set IR carrier frequency 8 | enableIROut(hz); 9 | 10 | for (unsigned int i = 0; i < len; i++) { 11 | if (i & 1) space(buf[i]) ; 12 | else mark (buf[i]) ; 13 | } 14 | 15 | space(0); // Always end with the LED off 16 | } 17 | 18 | //+============================================================================= 19 | // Sends an IR mark for the specified number of microseconds. 20 | // The mark output is modulated at the PWM frequency. 21 | // 22 | void IRsend::mark (unsigned int time) 23 | { 24 | TIMER_ENABLE_PWM; // Enable pin 3 PWM output 25 | if (time > 0) custom_delay_usec(time); 26 | } 27 | 28 | //+============================================================================= 29 | // Leave pin off for time (given in microseconds) 30 | // Sends an IR space for the specified number of microseconds. 31 | // A space is no output, so the PWM output is disabled. 32 | // 33 | void IRsend::space (unsigned int time) 34 | { 35 | TIMER_DISABLE_PWM; // Disable pin 3 PWM output 36 | if (time > 0) IRsend::custom_delay_usec(time); 37 | } 38 | 39 | 40 | 41 | 42 | 43 | //+============================================================================= 44 | // Enables IR output. The khz value controls the modulation frequency in kilohertz. 45 | // The IR output will be on pin 3 (OC2B). 46 | // This routine is designed for 36-40KHz; if you use it for other values, it's up to you 47 | // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) 48 | // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B 49 | // controlling the duty cycle. 50 | // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) 51 | // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. 52 | // A few hours staring at the ATmega documentation and this will all make sense. 53 | // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. 54 | // 55 | void IRsend::enableIROut (int khz) 56 | { 57 | // Disable the Timer2 Interrupt (which is used for receiving IR) 58 | TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt 59 | 60 | pinMode(TIMER_PWM_PIN, OUTPUT); 61 | digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low 62 | 63 | // COM2A = 00: disconnect OC2A 64 | // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted 65 | // WGM2 = 101: phase-correct PWM with OCRA as top 66 | // CS2 = 000: no prescaling 67 | // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. 68 | TIMER_CONFIG_KHZ(khz); 69 | } 70 | 71 | //+============================================================================= 72 | // Custom delay function that circumvents Arduino's delayMicroseconds limit 73 | 74 | void IRsend::custom_delay_usec(unsigned long uSecs) { 75 | if (uSecs > 4) { 76 | unsigned long start = micros(); 77 | unsigned long endMicros = start + uSecs - 4; 78 | if (endMicros < start) { // Check if overflow 79 | while ( micros() > start ) {} // wait until overflow 80 | } 81 | while ( micros() < endMicros ) {} // normal wait 82 | } 83 | //else { 84 | // __asm__("nop\n\t"); // must have or compiler optimizes out 85 | //} 86 | } 87 | 88 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Aiwa.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // AAA IIIII W W AAA 6 | // A A I W W A A 7 | // AAAAA I W W W AAAAA 8 | // A A I W W W A A 9 | // A A IIIII WWW A A 10 | //============================================================================== 11 | 12 | // Based off the RC-T501 RCU 13 | // Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 14 | 15 | #define AIWA_RC_T501_HZ 38 16 | #define AIWA_RC_T501_BITS 15 17 | #define AIWA_RC_T501_PRE_BITS 26 18 | #define AIWA_RC_T501_POST_BITS 1 19 | #define AIWA_RC_T501_SUM_BITS (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS) 20 | #define AIWA_RC_T501_HDR_MARK 8800 21 | #define AIWA_RC_T501_HDR_SPACE 4500 22 | #define AIWA_RC_T501_BIT_MARK 500 23 | #define AIWA_RC_T501_ONE_SPACE 600 24 | #define AIWA_RC_T501_ZERO_SPACE 1700 25 | 26 | //+============================================================================= 27 | #if SEND_AIWA_RC_T501 28 | void IRsend::sendAiwaRCT501 (int code) 29 | { 30 | unsigned long pre = 0x0227EEC0; // 26-bits 31 | 32 | // Set IR carrier frequency 33 | enableIROut(AIWA_RC_T501_HZ); 34 | 35 | // Header 36 | mark(AIWA_RC_T501_HDR_MARK); 37 | space(AIWA_RC_T501_HDR_SPACE); 38 | 39 | // Send "pre" data 40 | for (unsigned long mask = 1UL << (26 - 1); mask; mask >>= 1) { 41 | mark(AIWA_RC_T501_BIT_MARK); 42 | if (pre & mask) space(AIWA_RC_T501_ONE_SPACE) ; 43 | else space(AIWA_RC_T501_ZERO_SPACE) ; 44 | } 45 | 46 | //-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! 47 | // it only send 15bits and ignores the top bit 48 | // then uses TOPBIT which is 0x80000000 to check the bit code 49 | // I suspect TOPBIT should be changed to 0x00008000 50 | 51 | // Skip first code bit 52 | code <<= 1; 53 | // Send code 54 | for (int i = 0; i < 15; i++) { 55 | mark(AIWA_RC_T501_BIT_MARK); 56 | if (code & 0x80000000) space(AIWA_RC_T501_ONE_SPACE) ; 57 | else space(AIWA_RC_T501_ZERO_SPACE) ; 58 | code <<= 1; 59 | } 60 | 61 | //-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! 62 | 63 | // POST-DATA, 1 bit, 0x0 64 | mark(AIWA_RC_T501_BIT_MARK); 65 | space(AIWA_RC_T501_ZERO_SPACE); 66 | 67 | mark(AIWA_RC_T501_BIT_MARK); 68 | space(0); 69 | } 70 | #endif 71 | 72 | //+============================================================================= 73 | #if DECODE_AIWA_RC_T501 74 | bool IRrecv::decodeAiwaRCT501 (decode_results *results) 75 | { 76 | int data = 0; 77 | int offset = 1; 78 | 79 | // Check SIZE 80 | if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ; 81 | 82 | // Check HDR Mark/Space 83 | if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK )) return false ; 84 | if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE)) return false ; 85 | 86 | offset += 26; // skip pre-data - optional 87 | while(offset < irparams.rawlen - 4) { 88 | if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ; 89 | else return false ; 90 | 91 | // ONE & ZERO 92 | if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ; 93 | else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE)) data = (data << 1) | 0 ; 94 | else break ; // End of one & zero detected 95 | offset++; 96 | } 97 | 98 | results->bits = (offset - 1) / 2; 99 | if (results->bits < 42) return false ; 100 | 101 | results->value = data; 102 | results->decode_type = AIWA_RC_T501; 103 | return true; 104 | } 105 | #endif 106 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Denon.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | // Reverse Engineered by looking at RAW dumps generated by IRremote 5 | 6 | // I have since discovered that Denon publish all their IR codes: 7 | // https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet 8 | // -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls 9 | 10 | // Having looked at the official Denon Pronto sheet and reverse engineered 11 | // the timing values from it, it is obvious that Denon have a range of 12 | // different timings and protocols ...the values here work for my AVR-3801 Amp! 13 | 14 | //============================================================================== 15 | // DDDD EEEEE N N OOO N N 16 | // D D E NN N O O NN N 17 | // D D EEE N N N O O N N N 18 | // D D E N NN O O N NN 19 | // DDDD EEEEE N N OOO N N 20 | //============================================================================== 21 | 22 | #define BITS 14 // The number of bits in the command 23 | 24 | #define HDR_MARK 300 // The length of the Header:Mark 25 | #define HDR_SPACE 750 // The lenght of the Header:Space 26 | 27 | #define BIT_MARK 300 // The length of a Bit:Mark 28 | #define ONE_SPACE 1800 // The length of a Bit:Space for 1's 29 | #define ZERO_SPACE 750 // The length of a Bit:Space for 0's 30 | 31 | //+============================================================================= 32 | // 33 | #if SEND_DENON 34 | void IRsend::sendDenon (unsigned long data, int nbits) 35 | { 36 | // Set IR carrier frequency 37 | enableIROut(38); 38 | 39 | // Header 40 | mark (HDR_MARK); 41 | space(HDR_SPACE); 42 | 43 | // Data 44 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 45 | if (data & mask) { 46 | mark (BIT_MARK); 47 | space(ONE_SPACE); 48 | } else { 49 | mark (BIT_MARK); 50 | space(ZERO_SPACE); 51 | } 52 | } 53 | 54 | // Footer 55 | mark(BIT_MARK); 56 | space(0); // Always end with the LED off 57 | } 58 | #endif 59 | 60 | //+============================================================================= 61 | // 62 | #if DECODE_DENON 63 | bool IRrecv::decodeDenon (decode_results *results) 64 | { 65 | unsigned long data = 0; // Somewhere to build our code 66 | int offset = 1; // Skip the Gap reading 67 | 68 | // Check we have the right amount of data 69 | if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; 70 | 71 | // Check initial Mark+Space match 72 | if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; 73 | if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; 74 | 75 | // Read the bits in 76 | for (int i = 0; i < BITS; i++) { 77 | // Each bit looks like: MARK + SPACE_1 -> 1 78 | // or : MARK + SPACE_0 -> 0 79 | if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; 80 | 81 | // IR data is big-endian, so we shuffle it in from the right: 82 | if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; 83 | else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; 84 | else return false ; 85 | offset++; 86 | } 87 | 88 | // Success 89 | results->bits = BITS; 90 | results->value = data; 91 | results->decode_type = DENON; 92 | return true; 93 | } 94 | #endif 95 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Dish.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // DDDD IIIII SSSS H H 6 | // D D I S H H 7 | // D D I SSS HHHHH 8 | // D D I S H H 9 | // DDDD IIIII SSSS H H 10 | //============================================================================== 11 | 12 | // Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) 13 | // 14 | // The sned function needs to be repeated 4 times 15 | // 16 | // Only send the last for characters of the hex. 17 | // I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file. 18 | // 19 | // Here is the LIRC file I found that seems to match the remote codes from the 20 | // oscilloscope: 21 | // DISH NETWORK (echostar 301): 22 | // http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx 23 | 24 | #define DISH_BITS 16 25 | #define DISH_HDR_MARK 400 26 | #define DISH_HDR_SPACE 6100 27 | #define DISH_BIT_MARK 400 28 | #define DISH_ONE_SPACE 1700 29 | #define DISH_ZERO_SPACE 2800 30 | #define DISH_RPT_SPACE 6200 31 | 32 | //+============================================================================= 33 | #if SEND_DISH 34 | void IRsend::sendDISH (unsigned long data, int nbits) 35 | { 36 | // Set IR carrier frequency 37 | enableIROut(56); 38 | 39 | mark(DISH_HDR_MARK); 40 | space(DISH_HDR_SPACE); 41 | 42 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 43 | if (data & mask) { 44 | mark(DISH_BIT_MARK); 45 | space(DISH_ONE_SPACE); 46 | } else { 47 | mark(DISH_BIT_MARK); 48 | space(DISH_ZERO_SPACE); 49 | } 50 | } 51 | } 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_JVC.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // JJJJJ V V CCCC 6 | // J V V C 7 | // J V V C 8 | // J J V V C 9 | // J V CCCC 10 | //============================================================================== 11 | 12 | #define JVC_BITS 16 13 | #define JVC_HDR_MARK 8000 14 | #define JVC_HDR_SPACE 4000 15 | #define JVC_BIT_MARK 600 16 | #define JVC_ONE_SPACE 1600 17 | #define JVC_ZERO_SPACE 550 18 | #define JVC_RPT_LENGTH 60000 19 | 20 | //+============================================================================= 21 | // JVC does NOT repeat by sending a separate code (like NEC does). 22 | // The JVC protocol repeats by skipping the header. 23 | // To send a JVC repeat signal, send the original code value 24 | // and set 'repeat' to true 25 | // 26 | #if SEND_JVC 27 | void IRsend::sendJVC (unsigned long data, int nbits, bool repeat) 28 | { 29 | // Set IR carrier frequency 30 | enableIROut(38); 31 | 32 | // Only send the Header if this is NOT a repeat command 33 | if (!repeat){ 34 | mark(JVC_HDR_MARK); 35 | space(JVC_HDR_SPACE); 36 | } 37 | 38 | // Data 39 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 40 | if (data & mask) { 41 | mark(JVC_BIT_MARK); 42 | space(JVC_ONE_SPACE); 43 | } else { 44 | mark(JVC_BIT_MARK); 45 | space(JVC_ZERO_SPACE); 46 | } 47 | } 48 | 49 | // Footer 50 | mark(JVC_BIT_MARK); 51 | space(0); // Always end with the LED off 52 | } 53 | #endif 54 | 55 | //+============================================================================= 56 | #if DECODE_JVC 57 | bool IRrecv::decodeJVC (decode_results *results) 58 | { 59 | long data = 0; 60 | int offset = 1; // Skip first space 61 | 62 | // Check for repeat 63 | if ( (irparams.rawlen - 1 == 33) 64 | && MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) 65 | && MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK) 66 | ) { 67 | results->bits = 0; 68 | results->value = REPEAT; 69 | results->decode_type = JVC; 70 | return true; 71 | } 72 | 73 | // Initial mark 74 | if (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK)) return false ; 75 | 76 | if (irparams.rawlen < (2 * JVC_BITS) + 1 ) return false ; 77 | 78 | // Initial space 79 | if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE)) return false ; 80 | 81 | for (int i = 0; i < JVC_BITS; i++) { 82 | if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK)) return false ; 83 | 84 | if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) data = (data << 1) | 1 ; 85 | else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) data = (data << 1) | 0 ; 86 | else return false ; 87 | offset++; 88 | } 89 | 90 | // Stop bit 91 | if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ; 92 | 93 | // Success 94 | results->bits = JVC_BITS; 95 | results->value = data; 96 | results->decode_type = JVC; 97 | 98 | return true; 99 | } 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_LG.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // L GGGG 6 | // L G 7 | // L G GG 8 | // L G G 9 | // LLLLL GGG 10 | //============================================================================== 11 | 12 | #define LG_BITS 28 13 | 14 | #define LG_HDR_MARK 8000 15 | #define LG_HDR_SPACE 4000 16 | #define LG_BIT_MARK 600 17 | #define LG_ONE_SPACE 1600 18 | #define LG_ZERO_SPACE 550 19 | #define LG_RPT_LENGTH 60000 20 | 21 | //+============================================================================= 22 | #if DECODE_LG 23 | bool IRrecv::decodeLG (decode_results *results) 24 | { 25 | long data = 0; 26 | int offset = 1; // Skip first space 27 | 28 | // Check we have the right amount of data 29 | if (irparams.rawlen < (2 * LG_BITS) + 1 ) return false ; 30 | 31 | // Initial mark/space 32 | if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK)) return false ; 33 | if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE)) return false ; 34 | 35 | for (int i = 0; i < LG_BITS; i++) { 36 | if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK)) return false ; 37 | 38 | if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ; 39 | else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data = (data << 1) | 0 ; 40 | else return false ; 41 | offset++; 42 | } 43 | 44 | // Stop bit 45 | if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; 46 | 47 | // Success 48 | results->bits = LG_BITS; 49 | results->value = data; 50 | results->decode_type = LG; 51 | return true; 52 | } 53 | #endif 54 | 55 | //+============================================================================= 56 | #if SEND_LG 57 | void IRsend::sendLG (unsigned long data, int nbits) 58 | { 59 | // Set IR carrier frequency 60 | enableIROut(38); 61 | 62 | // Header 63 | mark(LG_HDR_MARK); 64 | space(LG_HDR_SPACE); 65 | mark(LG_BIT_MARK); 66 | 67 | // Data 68 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 69 | if (data & mask) { 70 | space(LG_ONE_SPACE); 71 | mark(LG_BIT_MARK); 72 | } else { 73 | space(LG_ZERO_SPACE); 74 | mark(LG_BIT_MARK); 75 | } 76 | } 77 | space(0); // Always end with the LED off 78 | } 79 | #endif 80 | 81 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Mitsubishi.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII 6 | // M M M I T S U U B B I S H H I 7 | // M M M I T SSS U U BBBB I SSS HHHHH I 8 | // M M I T S U U B B I S H H I 9 | // M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII 10 | //============================================================================== 11 | 12 | // Looks like Sony except for timings, 48 chars of data and time/space different 13 | 14 | #define MITSUBISHI_BITS 16 15 | 16 | // Mitsubishi RM 75501 17 | // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 18 | // #define MITSUBISHI_HDR_MARK 250 // seen range 3500 19 | #define MITSUBISHI_HDR_SPACE 350 // 7*50+100 20 | #define MITSUBISHI_ONE_MARK 1950 // 41*50-100 21 | #define MITSUBISHI_ZERO_MARK 750 // 17*50-100 22 | // #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround 23 | // #define MITSUBISHI_RPT_LENGTH 45000 24 | 25 | //+============================================================================= 26 | #if DECODE_MITSUBISHI 27 | bool IRrecv::decodeMitsubishi (decode_results *results) 28 | { 29 | // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); 30 | long data = 0; 31 | if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ; 32 | int offset = 0; // Skip first space 33 | // Initial space 34 | 35 | #if 0 36 | // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay 37 | Serial.print("IR Gap: "); 38 | Serial.println( results->rawbuf[offset]); 39 | Serial.println( "test against:"); 40 | Serial.println(results->rawbuf[offset]); 41 | #endif 42 | 43 | #if 0 44 | // Not seeing double keys from Mitsubishi 45 | if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { 46 | // Serial.print("IR Gap found: "); 47 | results->bits = 0; 48 | results->value = REPEAT; 49 | results->decode_type = MITSUBISHI; 50 | return true; 51 | } 52 | #endif 53 | 54 | offset++; 55 | 56 | // Typical 57 | // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 58 | 59 | // Initial Space 60 | if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return false ; 61 | offset++; 62 | 63 | while (offset + 1 < irparams.rawlen) { 64 | if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) data = (data << 1) | 1 ; 65 | else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) data <<= 1 ; 66 | else return false ; 67 | offset++; 68 | 69 | if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; 70 | offset++; 71 | } 72 | 73 | // Success 74 | results->bits = (offset - 1) / 2; 75 | if (results->bits < MITSUBISHI_BITS) { 76 | results->bits = 0; 77 | return false; 78 | } 79 | 80 | results->value = data; 81 | results->decode_type = MITSUBISHI; 82 | return true; 83 | } 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_NEC.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // N N EEEEE CCCC 6 | // NN N E C 7 | // N N N EEE C 8 | // N NN E C 9 | // N N EEEEE CCCC 10 | //============================================================================== 11 | 12 | #define NEC_BITS 32 13 | #define NEC_HDR_MARK 9000 14 | #define NEC_HDR_SPACE 4500 15 | #define NEC_BIT_MARK 560 16 | #define NEC_ONE_SPACE 1690 17 | #define NEC_ZERO_SPACE 560 18 | #define NEC_RPT_SPACE 2250 19 | 20 | //+============================================================================= 21 | #if SEND_NEC 22 | void IRsend::sendNEC (unsigned long data, int nbits) 23 | { 24 | // Set IR carrier frequency 25 | enableIROut(38); 26 | 27 | // Header 28 | mark(NEC_HDR_MARK); 29 | space(NEC_HDR_SPACE); 30 | 31 | // Data 32 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 33 | if (data & mask) { 34 | mark(NEC_BIT_MARK); 35 | space(NEC_ONE_SPACE); 36 | } else { 37 | mark(NEC_BIT_MARK); 38 | space(NEC_ZERO_SPACE); 39 | } 40 | } 41 | 42 | // Footer 43 | mark(NEC_BIT_MARK); 44 | space(0); // Always end with the LED off 45 | } 46 | #endif 47 | 48 | //+============================================================================= 49 | // NECs have a repeat only 4 items long 50 | // 51 | #if DECODE_NEC 52 | bool IRrecv::decodeNEC (decode_results *results) 53 | { 54 | long data = 0; // We decode in to here; Start with nothing 55 | int offset = 1; // Index in to results; Skip first entry!? 56 | 57 | // Check header "mark" 58 | if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return false ; 59 | offset++; 60 | 61 | // Check for repeat 62 | if ( (irparams.rawlen == 4) 63 | && MATCH_SPACE(results->rawbuf[offset ], NEC_RPT_SPACE) 64 | && MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK ) 65 | ) { 66 | results->bits = 0; 67 | results->value = REPEAT; 68 | results->decode_type = NEC; 69 | return true; 70 | } 71 | 72 | // Check we have enough data 73 | if (irparams.rawlen < (2 * NEC_BITS) + 4) return false ; 74 | 75 | // Check header "space" 76 | if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return false ; 77 | offset++; 78 | 79 | // Build the data 80 | for (int i = 0; i < NEC_BITS; i++) { 81 | // Check data "mark" 82 | if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return false ; 83 | offset++; 84 | // Suppend this bit 85 | if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE )) data = (data << 1) | 1 ; 86 | else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data = (data << 1) | 0 ; 87 | else return false ; 88 | offset++; 89 | } 90 | 91 | // Success 92 | results->bits = NEC_BITS; 93 | results->value = data; 94 | results->decode_type = NEC; 95 | 96 | return true; 97 | } 98 | #endif 99 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Panasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // PPPP AAA N N AAA SSSS OOO N N IIIII CCCC 6 | // P P A A NN N A A S O O NN N I C 7 | // PPPP AAAAA N N N AAAAA SSS O O N N N I C 8 | // P A A N NN A A S O O N NN I C 9 | // P A A N N A A SSSS OOO N N IIIII CCCC 10 | //============================================================================== 11 | 12 | #define PANASONIC_BITS 48 13 | #define PANASONIC_HDR_MARK 3502 14 | #define PANASONIC_HDR_SPACE 1750 15 | #define PANASONIC_BIT_MARK 502 16 | #define PANASONIC_ONE_SPACE 1244 17 | #define PANASONIC_ZERO_SPACE 400 18 | 19 | //+============================================================================= 20 | #if SEND_PANASONIC 21 | void IRsend::sendPanasonic (unsigned int address, unsigned long data) 22 | { 23 | // Set IR carrier frequency 24 | enableIROut(35); 25 | 26 | // Header 27 | mark(PANASONIC_HDR_MARK); 28 | space(PANASONIC_HDR_SPACE); 29 | 30 | // Address 31 | for (unsigned long mask = 1UL << (16 - 1); mask; mask >>= 1) { 32 | mark(PANASONIC_BIT_MARK); 33 | if (address & mask) space(PANASONIC_ONE_SPACE) ; 34 | else space(PANASONIC_ZERO_SPACE) ; 35 | } 36 | 37 | // Data 38 | for (unsigned long mask = 1UL << (32 - 1); mask; mask >>= 1) { 39 | mark(PANASONIC_BIT_MARK); 40 | if (data & mask) space(PANASONIC_ONE_SPACE) ; 41 | else space(PANASONIC_ZERO_SPACE) ; 42 | } 43 | 44 | // Footer 45 | mark(PANASONIC_BIT_MARK); 46 | space(0); // Always end with the LED off 47 | } 48 | #endif 49 | 50 | //+============================================================================= 51 | #if DECODE_PANASONIC 52 | bool IRrecv::decodePanasonic (decode_results *results) 53 | { 54 | unsigned long long data = 0; 55 | int offset = 1; 56 | 57 | if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK )) return false ; 58 | if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE)) return false ; 59 | 60 | // decode address 61 | for (int i = 0; i < PANASONIC_BITS; i++) { 62 | if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) return false ; 63 | 64 | if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE )) data = (data << 1) | 1 ; 65 | else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) data = (data << 1) | 0 ; 66 | else return false ; 67 | offset++; 68 | } 69 | 70 | results->value = (unsigned long)data; 71 | results->address = (unsigned int)(data >> 32); 72 | results->decode_type = PANASONIC; 73 | results->bits = PANASONIC_BITS; 74 | 75 | return true; 76 | } 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_RC5_RC6.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //+============================================================================= 5 | // Gets one undecoded level at a time from the raw buffer. 6 | // The RC5/6 decoding is easier if the data is broken into time intervals. 7 | // E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, 8 | // successive calls to getRClevel will return MARK, MARK, SPACE. 9 | // offset and used are updated to keep track of the current position. 10 | // t1 is the time interval for a single bit in microseconds. 11 | // Returns -1 for error (measured time interval is not a multiple of t1). 12 | // 13 | #if (DECODE_RC5 || DECODE_RC6) 14 | int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) 15 | { 16 | int width; 17 | int val; 18 | int correction; 19 | int avail; 20 | 21 | if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE. 22 | width = results->rawbuf[*offset]; 23 | val = ((*offset) % 2) ? MARK : SPACE; 24 | correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; 25 | 26 | if (MATCH(width, ( t1) + correction)) avail = 1 ; 27 | else if (MATCH(width, (2*t1) + correction)) avail = 2 ; 28 | else if (MATCH(width, (3*t1) + correction)) avail = 3 ; 29 | else return -1 ; 30 | 31 | (*used)++; 32 | if (*used >= avail) { 33 | *used = 0; 34 | (*offset)++; 35 | } 36 | 37 | DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); 38 | 39 | return val; 40 | } 41 | #endif 42 | 43 | //============================================================================== 44 | // RRRR CCCC 55555 45 | // R R C 5 46 | // RRRR C 5555 47 | // R R C 5 48 | // R R CCCC 5555 49 | // 50 | // NB: First bit must be a one (start bit) 51 | // 52 | #define MIN_RC5_SAMPLES 11 53 | #define RC5_T1 889 54 | #define RC5_RPT_LENGTH 46000 55 | 56 | //+============================================================================= 57 | #if SEND_RC5 58 | void IRsend::sendRC5 (unsigned long data, int nbits) 59 | { 60 | // Set IR carrier frequency 61 | enableIROut(36); 62 | 63 | // Start 64 | mark(RC5_T1); 65 | space(RC5_T1); 66 | mark(RC5_T1); 67 | 68 | // Data 69 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 70 | if (data & mask) { 71 | space(RC5_T1); // 1 is space, then mark 72 | mark(RC5_T1); 73 | } else { 74 | mark(RC5_T1); 75 | space(RC5_T1); 76 | } 77 | } 78 | 79 | space(0); // Always end with the LED off 80 | } 81 | #endif 82 | 83 | //+============================================================================= 84 | #if DECODE_RC5 85 | bool IRrecv::decodeRC5 (decode_results *results) 86 | { 87 | int nbits; 88 | long data = 0; 89 | int used = 0; 90 | int offset = 1; // Skip gap space 91 | 92 | if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ; 93 | 94 | // Get start bits 95 | if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; 96 | if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ; 97 | if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; 98 | 99 | for (nbits = 0; offset < irparams.rawlen; nbits++) { 100 | int levelA = getRClevel(results, &offset, &used, RC5_T1); 101 | int levelB = getRClevel(results, &offset, &used, RC5_T1); 102 | 103 | if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ; 104 | else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ; 105 | else return false ; 106 | } 107 | 108 | // Success 109 | results->bits = nbits; 110 | results->value = data; 111 | results->decode_type = RC5; 112 | return true; 113 | } 114 | #endif 115 | 116 | //+============================================================================= 117 | // RRRR CCCC 6666 118 | // R R C 6 119 | // RRRR C 6666 120 | // R R C 6 6 121 | // R R CCCC 666 122 | // 123 | // NB : Caller needs to take care of flipping the toggle bit 124 | // 125 | #define MIN_RC6_SAMPLES 1 126 | #define RC6_HDR_MARK 2666 127 | #define RC6_HDR_SPACE 889 128 | #define RC6_T1 444 129 | #define RC6_RPT_LENGTH 46000 130 | 131 | #if SEND_RC6 132 | void IRsend::sendRC6 (unsigned long data, int nbits) 133 | { 134 | // Set IR carrier frequency 135 | enableIROut(36); 136 | 137 | // Header 138 | mark(RC6_HDR_MARK); 139 | space(RC6_HDR_SPACE); 140 | 141 | // Start bit 142 | mark(RC6_T1); 143 | space(RC6_T1); 144 | 145 | // Data 146 | for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) { 147 | // The fourth bit we send is a "double width trailer bit" 148 | int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ; 149 | if (data & mask) { 150 | mark(t); 151 | space(t); 152 | } else { 153 | space(t); 154 | mark(t); 155 | } 156 | } 157 | 158 | space(0); // Always end with the LED off 159 | } 160 | #endif 161 | 162 | //+============================================================================= 163 | #if DECODE_RC6 164 | bool IRrecv::decodeRC6 (decode_results *results) 165 | { 166 | int nbits; 167 | long data = 0; 168 | int used = 0; 169 | int offset = 1; // Skip first space 170 | 171 | if (results->rawlen < MIN_RC6_SAMPLES) return false ; 172 | 173 | // Initial mark 174 | if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ; 175 | if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ; 176 | 177 | // Get start bit (1) 178 | if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ; 179 | if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ; 180 | 181 | for (nbits = 0; offset < results->rawlen; nbits++) { 182 | int levelA, levelB; // Next two levels 183 | 184 | levelA = getRClevel(results, &offset, &used, RC6_T1); 185 | if (nbits == 3) { 186 | // T bit is double wide; make sure second half matches 187 | if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false; 188 | } 189 | 190 | levelB = getRClevel(results, &offset, &used, RC6_T1); 191 | if (nbits == 3) { 192 | // T bit is double wide; make sure second half matches 193 | if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false; 194 | } 195 | 196 | if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5 197 | else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ... 198 | else return false ; // Error 199 | } 200 | 201 | // Success 202 | results->bits = nbits; 203 | results->value = data; 204 | results->decode_type = RC6; 205 | return true; 206 | } 207 | #endif 208 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Samsung.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // SSSS AAA MMM SSSS U U N N GGGG 6 | // S A A M M M S U U NN N G 7 | // SSS AAAAA M M M SSS U U N N N G GG 8 | // S A A M M S U U N NN G G 9 | // SSSS A A M M SSSS UUU N N GGG 10 | //============================================================================== 11 | 12 | #define SAMSUNG_BITS 32 13 | #define SAMSUNG_HDR_MARK 5000 14 | #define SAMSUNG_HDR_SPACE 5000 15 | #define SAMSUNG_BIT_MARK 560 16 | #define SAMSUNG_ONE_SPACE 1600 17 | #define SAMSUNG_ZERO_SPACE 560 18 | #define SAMSUNG_RPT_SPACE 2250 19 | 20 | //+============================================================================= 21 | #if SEND_SAMSUNG 22 | void IRsend::sendSAMSUNG (unsigned long data, int nbits) 23 | { 24 | // Set IR carrier frequency 25 | enableIROut(38); 26 | 27 | // Header 28 | mark(SAMSUNG_HDR_MARK); 29 | space(SAMSUNG_HDR_SPACE); 30 | 31 | // Data 32 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 33 | if (data & mask) { 34 | mark(SAMSUNG_BIT_MARK); 35 | space(SAMSUNG_ONE_SPACE); 36 | } else { 37 | mark(SAMSUNG_BIT_MARK); 38 | space(SAMSUNG_ZERO_SPACE); 39 | } 40 | } 41 | 42 | // Footer 43 | mark(SAMSUNG_BIT_MARK); 44 | space(0); // Always end with the LED off 45 | } 46 | #endif 47 | 48 | //+============================================================================= 49 | // SAMSUNGs have a repeat only 4 items long 50 | // 51 | #if DECODE_SAMSUNG 52 | bool IRrecv::decodeSAMSUNG (decode_results *results) 53 | { 54 | long data = 0; 55 | int offset = 1; // Skip first space 56 | 57 | // Initial mark 58 | if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ; 59 | offset++; 60 | 61 | // Check for repeat 62 | if ( (irparams.rawlen == 4) 63 | && MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) 64 | && MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK) 65 | ) { 66 | results->bits = 0; 67 | results->value = REPEAT; 68 | results->decode_type = SAMSUNG; 69 | return true; 70 | } 71 | if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4) return false ; 72 | 73 | // Initial space 74 | if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE)) return false ; 75 | 76 | for (int i = 0; i < SAMSUNG_BITS; i++) { 77 | if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; 78 | 79 | if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ; 80 | else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data = (data << 1) | 0 ; 81 | else return false ; 82 | offset++; 83 | } 84 | 85 | // Success 86 | results->bits = SAMSUNG_BITS; 87 | results->value = data; 88 | results->decode_type = SAMSUNG; 89 | return true; 90 | } 91 | #endif 92 | 93 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Sanyo.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // SSSS AAA N N Y Y OOO 6 | // S A A NN N Y Y O O 7 | // SSS AAAAA N N N Y O O 8 | // S A A N NN Y O O 9 | // SSSS A A N N Y OOO 10 | //============================================================================== 11 | 12 | // I think this is a Sanyo decoder: Serial = SA 8650B 13 | // Looks like Sony except for timings, 48 chars of data and time/space different 14 | 15 | #define SANYO_BITS 12 16 | #define SANYO_HDR_MARK 3500 // seen range 3500 17 | #define SANYO_HDR_SPACE 950 // seen 950 18 | #define SANYO_ONE_MARK 2400 // seen 2400 19 | #define SANYO_ZERO_MARK 700 // seen 700 20 | #define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround 21 | #define SANYO_RPT_LENGTH 45000 22 | 23 | //+============================================================================= 24 | #if DECODE_SANYO 25 | bool IRrecv::decodeSanyo (decode_results *results) 26 | { 27 | long data = 0; 28 | int offset = 0; // Skip first space <-- CHECK THIS! 29 | 30 | if (irparams.rawlen < (2 * SANYO_BITS) + 2) return false ; 31 | 32 | #if 0 33 | // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay 34 | Serial.print("IR Gap: "); 35 | Serial.println( results->rawbuf[offset]); 36 | Serial.println( "test against:"); 37 | Serial.println(results->rawbuf[offset]); 38 | #endif 39 | 40 | // Initial space 41 | if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { 42 | //Serial.print("IR Gap found: "); 43 | results->bits = 0; 44 | results->value = REPEAT; 45 | results->decode_type = SANYO; 46 | return true; 47 | } 48 | offset++; 49 | 50 | // Initial mark 51 | if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; 52 | 53 | // Skip Second Mark 54 | if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; 55 | 56 | while (offset + 1 < irparams.rawlen) { 57 | if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE)) break ; 58 | 59 | if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ; 60 | else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data = (data << 1) | 0 ; 61 | else return false ; 62 | offset++; 63 | } 64 | 65 | // Success 66 | results->bits = (offset - 1) / 2; 67 | if (results->bits < 12) { 68 | results->bits = 0; 69 | return false; 70 | } 71 | 72 | results->value = data; 73 | results->decode_type = SANYO; 74 | return true; 75 | } 76 | #endif 77 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Sharp.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // SSSS H H AAA RRRR PPPP 6 | // S H H A A R R P P 7 | // SSS HHHHH AAAAA RRRR PPPP 8 | // S H H A A R R P 9 | // SSSS H H A A R R P 10 | //============================================================================== 11 | 12 | // Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand 13 | // 14 | // The send function has the necessary repeat built in because of the need to 15 | // invert the signal. 16 | // 17 | // Sharp protocol documentation: 18 | // http://www.sbprojects.com/knowledge/ir/sharp.htm 19 | // 20 | // Here is the LIRC file I found that seems to match the remote codes from the 21 | // oscilloscope: 22 | // Sharp LCD TV: 23 | // http://lirc.sourceforge.net/remotes/sharp/GA538WJSA 24 | 25 | #define SHARP_BITS 15 26 | #define SHARP_BIT_MARK 245 27 | #define SHARP_ONE_SPACE 1805 28 | #define SHARP_ZERO_SPACE 795 29 | #define SHARP_GAP 600000 30 | #define SHARP_RPT_SPACE 3000 31 | 32 | #define SHARP_TOGGLE_MASK 0x3FF 33 | 34 | //+============================================================================= 35 | #if SEND_SHARP 36 | void IRsend::sendSharpRaw (unsigned long data, int nbits) 37 | { 38 | enableIROut(38); 39 | 40 | // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission 41 | // much more reliable. That's the exact behaviour of CD-S6470 remote control. 42 | for (int n = 0; n < 3; n++) { 43 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 44 | if (data & mask) { 45 | mark(SHARP_BIT_MARK); 46 | space(SHARP_ONE_SPACE); 47 | } else { 48 | mark(SHARP_BIT_MARK); 49 | space(SHARP_ZERO_SPACE); 50 | } 51 | } 52 | 53 | mark(SHARP_BIT_MARK); 54 | space(SHARP_ZERO_SPACE); 55 | delay(40); 56 | 57 | data = data ^ SHARP_TOGGLE_MASK; 58 | } 59 | } 60 | #endif 61 | 62 | //+============================================================================= 63 | // Sharp send compatible with data obtained through decodeSharp() 64 | // ^^^^^^^^^^^^^ FUNCTION MISSING! 65 | // 66 | #if SEND_SHARP 67 | void IRsend::sendSharp (unsigned int address, unsigned int command) 68 | { 69 | sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS); 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Sony.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // SSSS OOO N N Y Y 6 | // S O O NN N Y Y 7 | // SSS O O N N N Y 8 | // S O O N NN Y 9 | // SSSS OOO N N Y 10 | //============================================================================== 11 | 12 | #define SONY_BITS 12 13 | #define SONY_HDR_MARK 2400 14 | #define SONY_HDR_SPACE 600 15 | #define SONY_ONE_MARK 1200 16 | #define SONY_ZERO_MARK 600 17 | #define SONY_RPT_LENGTH 45000 18 | #define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround 19 | 20 | //+============================================================================= 21 | #if SEND_SONY 22 | void IRsend::sendSony (unsigned long data, int nbits) 23 | { 24 | // Set IR carrier frequency 25 | enableIROut(40); 26 | 27 | // Header 28 | mark(SONY_HDR_MARK); 29 | space(SONY_HDR_SPACE); 30 | 31 | // Data 32 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 33 | if (data & mask) { 34 | mark(SONY_ONE_MARK); 35 | space(SONY_HDR_SPACE); 36 | } else { 37 | mark(SONY_ZERO_MARK); 38 | space(SONY_HDR_SPACE); 39 | } 40 | } 41 | 42 | // We will have ended with LED off 43 | } 44 | #endif 45 | 46 | //+============================================================================= 47 | #if DECODE_SONY 48 | bool IRrecv::decodeSony (decode_results *results) 49 | { 50 | long data = 0; 51 | int offset = 0; // Dont skip first space, check its size 52 | 53 | if (irparams.rawlen < (2 * SONY_BITS) + 2) return false ; 54 | 55 | // Some Sony's deliver repeats fast after first 56 | // unfortunately can't spot difference from of repeat from two fast clicks 57 | if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) { 58 | // Serial.print("IR Gap found: "); 59 | results->bits = 0; 60 | results->value = REPEAT; 61 | 62 | # ifdef DECODE_SANYO 63 | results->decode_type = SANYO; 64 | # else 65 | results->decode_type = UNKNOWN; 66 | # endif 67 | 68 | return true; 69 | } 70 | offset++; 71 | 72 | // Initial mark 73 | if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK)) return false ; 74 | 75 | while (offset + 1 < irparams.rawlen) { 76 | if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE)) break ; 77 | 78 | if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) data = (data << 1) | 1 ; 79 | else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data = (data << 1) | 0 ; 80 | else return false ; 81 | offset++; 82 | } 83 | 84 | // Success 85 | results->bits = (offset - 1) / 2; 86 | if (results->bits < 12) { 87 | results->bits = 0; 88 | return false; 89 | } 90 | results->value = data; 91 | results->decode_type = SONY; 92 | return true; 93 | } 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Template.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu 3 | 4 | Our fantasy protocol is a standard protocol, so we can use this standard 5 | template without too much work. Some protocols are quite unique and will require 6 | considerably more work in this file! It is way beyond the scope of this text to 7 | explain how to reverse engineer "unusual" IR protocols. But, unless you own an 8 | oscilloscope, the starting point is probably to use the rawDump.ino sketch and 9 | try to spot the pattern! 10 | 11 | Before you start, make sure the IR library is working OK: 12 | # Open up the Arduino IDE 13 | # Load up the rawDump.ino example sketch 14 | # Run it 15 | 16 | Now we can start to add our new protocol... 17 | 18 | 1. Copy this file to : ir_Shuzu.cpp 19 | 20 | 2. Replace all occurrences of "Shuzu" with the name of your protocol. 21 | 22 | 3. Tweak the #defines to suit your protocol. 23 | 24 | 4. If you're lucky, tweaking the #defines will make the default send() function 25 | work. 26 | 27 | 5. Again, if you're lucky, tweaking the #defines will have made the default 28 | decode() function work. 29 | 30 | You have written the code to support your new protocol! 31 | 32 | Now you must do a few things to add it to the IRremote system: 33 | 34 | 1. Open IRremote.h and make the following changes: 35 | REMEMEBER to change occurences of "SHUZU" with the name of your protocol 36 | 37 | A. At the top, in the section "Supported Protocols", add: 38 | #define DECODE_SHUZU 1 39 | #define SEND_SHUZU 1 40 | 41 | B. In the section "enumerated list of all supported formats", add: 42 | SHUZU, 43 | to the end of the list (notice there is a comma after the protocol name) 44 | 45 | C. Further down in "Main class for receiving IR", add: 46 | //...................................................................... 47 | #if DECODE_SHUZU 48 | bool decodeShuzu (decode_results *results) ; 49 | #endif 50 | 51 | D. Further down in "Main class for sending IR", add: 52 | //...................................................................... 53 | #if SEND_SHUZU 54 | void sendShuzu (unsigned long data, int nbits) ; 55 | #endif 56 | 57 | E. Save your changes and close the file 58 | 59 | 2. Now open irRecv.cpp and make the following change: 60 | 61 | A. In the function IRrecv::decode(), add: 62 | #ifdef DECODE_NEC 63 | DBG_PRINTLN("Attempting Shuzu decode"); 64 | if (decodeShuzu(results)) return true ; 65 | #endif 66 | 67 | B. Save your changes and close the file 68 | 69 | You will probably want to add your new protocol to the example sketch 70 | 71 | 3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino 72 | 73 | A. In the encoding() function, add: 74 | case SHUZU: Serial.print("SHUZU"); break ; 75 | 76 | Now open the Arduino IDE, load up the rawDump.ino sketch, and run it. 77 | Hopefully it will compile and upload. 78 | If it doesn't, you've done something wrong. Check your work. 79 | If you can't get it to work - seek help from somewhere. 80 | 81 | If you get this far, I will assume you have successfully added your new protocol 82 | There is one last thing to do. 83 | 84 | 1. Delete this giant instructional comment. 85 | 86 | 2. Send a copy of your work to us so we can include it in the library and 87 | others may benefit from your hard work and maybe even write a song about how 88 | great you are for helping them! :) 89 | 90 | Regards, 91 | BlueChip 92 | */ 93 | 94 | #include "IRremote.h" 95 | #include "IRremoteInt.h" 96 | 97 | //============================================================================== 98 | // 99 | // 100 | // S H U Z U 101 | // 102 | // 103 | //============================================================================== 104 | 105 | #define BITS 32 // The number of bits in the command 106 | 107 | #define HDR_MARK 1000 // The length of the Header:Mark 108 | #define HDR_SPACE 2000 // The lenght of the Header:Space 109 | 110 | #define BIT_MARK 3000 // The length of a Bit:Mark 111 | #define ONE_SPACE 4000 // The length of a Bit:Space for 1's 112 | #define ZERO_SPACE 5000 // The length of a Bit:Space for 0's 113 | 114 | #define OTHER 1234 // Other things you may need to define 115 | 116 | //+============================================================================= 117 | // 118 | #if SEND_SHUZU 119 | void IRsend::sendShuzu (unsigned long data, int nbits) 120 | { 121 | // Set IR carrier frequency 122 | enableIROut(38); 123 | 124 | // Header 125 | mark (HDR_MARK); 126 | space(HDR_SPACE); 127 | 128 | // Data 129 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 130 | if (data & mask) { 131 | mark (BIT_MARK); 132 | space(ONE_SPACE); 133 | } else { 134 | mark (BIT_MARK); 135 | space(ZERO_SPACE); 136 | } 137 | } 138 | 139 | // Footer 140 | mark(BIT_MARK); 141 | space(0); // Always end with the LED off 142 | } 143 | #endif 144 | 145 | //+============================================================================= 146 | // 147 | #if DECODE_SHUZU 148 | bool IRrecv::decodeShuzu (decode_results *results) 149 | { 150 | unsigned long data = 0; // Somewhere to build our code 151 | int offset = 1; // Skip the Gap reading 152 | 153 | // Check we have the right amount of data 154 | if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; 155 | 156 | // Check initial Mark+Space match 157 | if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; 158 | if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; 159 | 160 | // Read the bits in 161 | for (int i = 0; i < SHUZU_BITS; i++) { 162 | // Each bit looks like: MARK + SPACE_1 -> 1 163 | // or : MARK + SPACE_0 -> 0 164 | if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; 165 | 166 | // IR data is big-endian, so we shuffle it in from the right: 167 | if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; 168 | else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; 169 | else return false ; 170 | offset++; 171 | } 172 | 173 | // Success 174 | results->bits = BITS; 175 | results->value = data; 176 | results->decode_type = SHUZU; 177 | return true; 178 | } 179 | #endif 180 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/ir_Whynter.cpp: -------------------------------------------------------------------------------- 1 | #include "IRremote.h" 2 | #include "IRremoteInt.h" 3 | 4 | //============================================================================== 5 | // W W H H Y Y N N TTTTT EEEEE RRRRR 6 | // W W H H Y Y NN N T E R R 7 | // W W W HHHHH Y N N N T EEE RRRR 8 | // W W W H H Y N NN T E R R 9 | // WWW H H Y N N T EEEEE R R 10 | //============================================================================== 11 | 12 | #define WHYNTER_BITS 32 13 | #define WHYNTER_HDR_MARK 2850 14 | #define WHYNTER_HDR_SPACE 2850 15 | #define WHYNTER_BIT_MARK 750 16 | #define WHYNTER_ONE_MARK 750 17 | #define WHYNTER_ONE_SPACE 2150 18 | #define WHYNTER_ZERO_MARK 750 19 | #define WHYNTER_ZERO_SPACE 750 20 | 21 | //+============================================================================= 22 | #if SEND_WHYNTER 23 | void IRsend::sendWhynter (unsigned long data, int nbits) 24 | { 25 | // Set IR carrier frequency 26 | enableIROut(38); 27 | 28 | // Start 29 | mark(WHYNTER_ZERO_MARK); 30 | space(WHYNTER_ZERO_SPACE); 31 | 32 | // Header 33 | mark(WHYNTER_HDR_MARK); 34 | space(WHYNTER_HDR_SPACE); 35 | 36 | // Data 37 | for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 38 | if (data & mask) { 39 | mark(WHYNTER_ONE_MARK); 40 | space(WHYNTER_ONE_SPACE); 41 | } else { 42 | mark(WHYNTER_ZERO_MARK); 43 | space(WHYNTER_ZERO_SPACE); 44 | } 45 | } 46 | 47 | // Footer 48 | mark(WHYNTER_ZERO_MARK); 49 | space(WHYNTER_ZERO_SPACE); // Always end with the LED off 50 | } 51 | #endif 52 | 53 | //+============================================================================= 54 | #if DECODE_WHYNTER 55 | bool IRrecv::decodeWhynter (decode_results *results) 56 | { 57 | long data = 0; 58 | int offset = 1; // skip initial space 59 | 60 | // Check we have the right amount of data 61 | if (irparams.rawlen < (2 * WHYNTER_BITS) + 6) return false ; 62 | 63 | // Sequence begins with a bit mark and a zero space 64 | if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK )) return false ; 65 | if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false ; 66 | 67 | // header mark and space 68 | if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK )) return false ; 69 | if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE)) return false ; 70 | 71 | // data bits 72 | for (int i = 0; i < WHYNTER_BITS; i++) { 73 | if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false ; 74 | 75 | if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE )) data = (data << 1) | 1 ; 76 | else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) data = (data << 1) | 0 ; 77 | else return false ; 78 | offset++; 79 | } 80 | 81 | // trailing mark 82 | if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; 83 | 84 | // Success 85 | results->bits = WHYNTER_BITS; 86 | results->value = data; 87 | results->decode_type = WHYNTER; 88 | return true; 89 | } 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For IRremote 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | decode_results KEYWORD1 10 | IRrecv KEYWORD1 11 | IRsend KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | blink13 KEYWORD2 18 | decode KEYWORD2 19 | enableIRIn KEYWORD2 20 | resume KEYWORD2 21 | enableIROut KEYWORD2 22 | sendNEC KEYWORD2 23 | sendSony KEYWORD2 24 | sendSanyo KEYWORD2 25 | sendMitsubishi KEYWORD2 26 | sendRaw KEYWORD2 27 | sendRC5 KEYWORD2 28 | sendRC6 KEYWORD2 29 | sendDISH KEYWORD2 30 | sendSharp KEYWORD2 31 | sendSharpRaw KEYWORD2 32 | sendPanasonic KEYWORD2 33 | sendJVC KEYWORD2 34 | 35 | ####################################### 36 | # Constants (LITERAL1) 37 | ####################################### 38 | 39 | NEC LITERAL1 40 | SONY LITERAL1 41 | SANYO LITERAL1 42 | MITSUBISHI LITERAL1 43 | RC5 LITERAL1 44 | RC6 LITERAL1 45 | DISH LITERAL1 46 | SHARP LITERAL1 47 | PANASONIC LITERAL1 48 | JVC LITERAL1 49 | LG LITERAL1 50 | AIWA_RC_T501 LITERAL1 51 | UNKNOWN LITERAL1 52 | REPEAT LITERAL1 53 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IRremote", 3 | "keywords": "infrared, ir, remote", 4 | "description": "Send and receive infrared signals with multiple protocols", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/shirriff/Arduino-IRremote.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": "atmelavr" 12 | } 13 | -------------------------------------------------------------------------------- /urobot/Robot/IRremote/library.properties: -------------------------------------------------------------------------------- 1 | name=IRremote 2 | version=2.0.1 3 | author=shirriff 4 | maintainer=shirriff 5 | sentence=Send and receive infrared signals with multiple protocols 6 | paragraph=Send and receive infrared signals with multiple protocols 7 | category=Signal Input/Output 8 | url=https://github.com/shirriff/Arduino-IRremote.git 9 | architectures=* 10 | -------------------------------------------------------------------------------- /urobot/Robot/LED.cpp: -------------------------------------------------------------------------------- 1 | #include "LED.h" 2 | #include "Arduino.h" 3 | 4 | 5 | int blueLED = 0; 6 | int redLED = 1; 7 | int greenLED = 5; 8 | int irLED = 3; 9 | 10 | void setupLED(){ 11 | pinMode(blueLED, OUTPUT); 12 | pinMode(redLED, OUTPUT); 13 | pinMode (greenLED, OUTPUT); 14 | pinMode (irLED, OUTPUT); 15 | LEDsOff(); 16 | } 17 | 18 | void lightGreenLED(){ 19 | CLR(PORTD,5) ; 20 | } 21 | 22 | void lightBlueLED(){ 23 | CLR(PORTD,0); 24 | } 25 | 26 | void lightRedLED(){ 27 | CLR(PORTD,1); // turn the LED on by making the voltage LOW 28 | } 29 | 30 | void LEDsOff(){ 31 | SET(PORTD,5); //green off 32 | SET(PORTD,0); //blue off 33 | SET(PORTD,1); //red off 34 | } 35 | 36 | -------------------------------------------------------------------------------- /urobot/Robot/LED.h: -------------------------------------------------------------------------------- 1 | #ifndef LED 2 | #define LED 3 | #define CLR(x,y) (x&=(~(1< 2 | 3 | #include "Timer-master/Timer.h" 4 | #include "Timer-master/Event.h" 5 | #include "rosToInterface.hpp" 6 | 7 | #define CLR(x,y) (x&=(~(1<630) 77 | lightGreenLED(); 78 | if(batteryReading > 300 && batteryReading < 480) 79 | lightRedLED(); 80 | if(batteryReading > 480 && batteryReading < 640) lightBlueLED(); 81 | 82 | LEDsOff(); 83 | } 84 | 85 | void RCTimoutCB(){ 86 | movingLeft =0; 87 | movingRight =0; 88 | looseMotors(); 89 | } 90 | 91 | enum { 92 | nostate, 93 | linang, 94 | } state; 95 | 96 | // the setup function runs once when you press reset or power the board 97 | void setup() { 98 | serial.begin(2400); 99 | pinMode(A0,INPUT); 100 | pinMode(sensorPower,OUTPUT); 101 | digitalWrite(sensorPower,HIGH); 102 | irrecv.enableIRIn(); // Start the receiver 103 | // initialize digital pin 13 as an output. 104 | setupLED(); 105 | //motorLeft->setOnTimer(&motorLeftUpdate); 106 | batteryEvent = t.every(1000000, checkBatt); 107 | motorLeftEvent = t.every(speedLeft, motorLeftUpdate); 108 | motorRightEvent = t.every(speedRight, motorRightUpdate); 109 | RCTimout = t.after(100000,RCTimoutCB); 110 | 111 | state = nostate; 112 | } 113 | int savedLeft = 0; 114 | // the loop function runs over and over again forever 115 | 116 | 117 | size_t linangpointer; 118 | unsigned char linangbuffer[NumRobots]; 119 | 120 | void RunLinAng(){ 121 | lightRedLED(); 122 | 123 | const unsigned linang = linangbuffer[MyRobotNumber]; 124 | const int8_t lin = (linang & 0b11110000) >> 4; 125 | int8_t ang = linang & 0b00001111; 126 | 127 | if(ang & 0b00001000){ 128 | ang |= 0b11110000; 129 | } 130 | const float flin = abs(lin) / 127.0f; 131 | const float fang = abs(ang) / 127.0f; 132 | 133 | const int lvel = (minspeed - maxspeed)*(1-flin)*(1+fang) + maxspeed; 134 | const int rvel = (minspeed - maxspeed)*(1-flin)*(1-fang) + maxspeed; 135 | 136 | speedLeft = lvel; 137 | speedRight = rvel; 138 | 139 | t.stop(motorLeftEvent); 140 | t.stop(motorRightEvent); 141 | motorLeftEvent = t.every(speedLeft, motorLeftUpdate); 142 | motorRightEvent = t.every(speedRight, motorRightUpdate); 143 | movingLeft = 1; 144 | movingRight =1; 145 | 146 | dirLeft = 1; 147 | dirRight = 1; 148 | } 149 | 150 | 151 | void loop() { 152 | unsigned char ch; 153 | int n, i; 154 | 155 | 156 | n = serial.available() ; 157 | if (n > 0) { 158 | i = n ; 159 | while (i--) { 160 | ch = serial.read() ; 161 | switch (state){ 162 | case nostate: 163 | switch(ch){ 164 | case CmdLINANG: 165 | state = linang; 166 | linangpointer = 0; 167 | break; 168 | 169 | default: 170 | break; 171 | } 172 | break; 173 | 174 | case linang: 175 | linangbuffer[linangpointer++] = ch; 176 | if (linangpointer == NumRobots){ 177 | RunLinAng(); 178 | state = nostate; 179 | } 180 | break; 181 | 182 | default: 183 | break; 184 | } 185 | } 186 | } 187 | 188 | //delay(10); // wait for a second 189 | t.update(); 190 | 191 | 192 | } 193 | 194 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/Event.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * 19 | Code by Simon Monk 20 | http://www.simonmonk.org 21 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 22 | 23 | // For Arduino 1.0 and earlier 24 | #if defined(ARDUINO) && ARDUINO >= 100 25 | #include "Arduino.h" 26 | #else 27 | #include "WProgram.h" 28 | #endif 29 | 30 | #include "Event.h" 31 | 32 | Event::Event(void) 33 | { 34 | eventType = EVENT_NONE; 35 | } 36 | 37 | void Event::update(void) 38 | { 39 | unsigned long now = millis(); 40 | update(now); 41 | } 42 | 43 | void Event::update(unsigned long now) 44 | { 45 | if (now - lastEventTime >= period) 46 | { 47 | switch (eventType) 48 | { 49 | case EVENT_EVERY: 50 | (*callback)(); 51 | break; 52 | 53 | case EVENT_OSCILLATE: 54 | pinState = ! pinState; 55 | digitalWrite(pin, pinState); 56 | break; 57 | } 58 | lastEventTime = now; 59 | count++; 60 | } 61 | if (repeatCount > -1 && count >= repeatCount) 62 | { 63 | eventType = EVENT_NONE; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/Event.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * 19 | Code by Simon Monk 20 | http://www.simonmonk.org 21 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 22 | 23 | #ifndef Event_h 24 | #define Event_h 25 | 26 | #include 27 | 28 | #define EVENT_NONE 0 29 | #define EVENT_EVERY 1 30 | #define EVENT_OSCILLATE 2 31 | 32 | class Event 33 | { 34 | 35 | public: 36 | Event(void); 37 | void update(void); 38 | void update(unsigned long now); 39 | int8_t eventType; 40 | unsigned long period; 41 | int repeatCount; 42 | uint8_t pin; 43 | uint8_t pinState; 44 | void (*callback)(void); 45 | unsigned long lastEventTime; 46 | int count; 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 1.0 by Simon Monk 2 | Library as downloaded 02Feb2012 22:55 UTC from http://srmonk.blogspot.com/2012/01/arduino-timer-library.html 3 | 4 | 1.1 by Jack Christensen 5 | Changed data types of variables and functions: 6 | o event types and indexes changed from int to int8_t. 7 | o periods and durations changed from lon to unsigned long. 8 | o update() and stop() functions typed as void, since they return nothing. 9 | o pin numbers and pin values changed from int to uint8_t, this agrees with digitalWrite(). 10 | o added return values to Timer::pulse() and Timer::oscillate(uint8_t, unsigned long, uint8_t). 11 | o changed test in Event::update() to use subtraction to avoid rollover issues. 12 | o Updated keywords.txt file to include all functions. 13 | 14 | 1.2 by Damian Philipp 15 | o Added a range check to Timer::stop() to avoid memory corruption. 16 | o Added constants to : 17 | - NO_TIMER_AVAILABLE: Signals that while an event was to be queued, no free timer could be found. 18 | - TIMER_NOT_AN_EVENT: Can be used to flag a variable that *might* contain a timer ID as 19 | *not* containing a timer ID 20 | o Replaced a bunch of magic numbers in by the above constants 21 | o Added several comments 22 | o Added Timer::pulseImmediate(). pulseImmediate sets the pin to the specified value for the given 23 | duration. After the duration, the pin is set to !value. 24 | 25 | 1.3 by Jack Christensen 26 | o Added "blink2" example illustrating flashing two LEDs at different rates. 27 | o 19Oct2013: This is the last v1.x release. It will continue to be available on GitHub 28 | as a branch named v1.3. Future development will continue with Sandy Walsh's v2.0 which 29 | can pass context (timer ID, etc.) to the callback functions. -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/Timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * 19 | Code by Simon Monk 20 | http://www.simonmonk.org 21 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 22 | 23 | // For Arduino 1.0 and earlier 24 | #if defined(ARDUINO) && ARDUINO >= 100 25 | #include "Arduino.h" 26 | #else 27 | #include "WProgram.h" 28 | #endif 29 | 30 | #include "Timer.h" 31 | 32 | Timer::Timer(void) 33 | { 34 | } 35 | 36 | int8_t Timer::every(unsigned long period, void (*callback)(), int repeatCount) 37 | { 38 | int8_t i = findFreeEventIndex(); 39 | if (i == -1) return -1; 40 | 41 | _events[i].eventType = EVENT_EVERY; 42 | _events[i].period = period; 43 | _events[i].repeatCount = repeatCount; 44 | _events[i].callback = callback; 45 | _events[i].lastEventTime = micros(); 46 | _events[i].count = 0; 47 | return i; 48 | } 49 | 50 | int8_t Timer::every(unsigned long period, void (*callback)()) 51 | { 52 | return every(period, callback, -1); // - means forever 53 | } 54 | 55 | int8_t Timer::after(unsigned long period, void (*callback)()) 56 | { 57 | return every(period, callback, 1); 58 | } 59 | 60 | int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount) 61 | { 62 | int8_t i = findFreeEventIndex(); 63 | if (i == NO_TIMER_AVAILABLE) return NO_TIMER_AVAILABLE; 64 | 65 | _events[i].eventType = EVENT_OSCILLATE; 66 | _events[i].pin = pin; 67 | _events[i].period = period; 68 | _events[i].pinState = startingValue; 69 | digitalWrite(pin, startingValue); 70 | _events[i].repeatCount = repeatCount * 2; // full cycles not transitions 71 | _events[i].lastEventTime = micros(); 72 | _events[i].count = 0; 73 | return i; 74 | } 75 | 76 | int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue) 77 | { 78 | return oscillate(pin, period, startingValue, -1); // forever 79 | } 80 | 81 | /** 82 | * This method will generate a pulse of !startingValue, occuring period after the 83 | * call of this method and lasting for period. The Pin will be left in !startingValue. 84 | */ 85 | int8_t Timer::pulse(uint8_t pin, unsigned long period, uint8_t startingValue) 86 | { 87 | return oscillate(pin, period, startingValue, 1); // once 88 | } 89 | 90 | /** 91 | * This method will generate a pulse of startingValue, starting immediately and of 92 | * length period. The pin will be left in the !startingValue state 93 | */ 94 | int8_t Timer::pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue) 95 | { 96 | int8_t id(oscillate(pin, period, pulseValue, 1)); 97 | // now fix the repeat count 98 | if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { 99 | _events[id].repeatCount = 1; 100 | } 101 | return id; 102 | } 103 | 104 | 105 | void Timer::stop(int8_t id) 106 | { 107 | if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { 108 | _events[id].eventType = EVENT_NONE; 109 | } 110 | } 111 | 112 | void Timer::update(void) 113 | { 114 | unsigned long now = micros(); 115 | update(now); 116 | } 117 | 118 | void Timer::update(unsigned long now) 119 | { 120 | for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) 121 | { 122 | if (_events[i].eventType != EVENT_NONE) 123 | { 124 | _events[i].update(now); 125 | } 126 | } 127 | } 128 | int8_t Timer::findFreeEventIndex(void) 129 | { 130 | for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) 131 | { 132 | if (_events[i].eventType == EVENT_NONE) 133 | { 134 | return i; 135 | } 136 | } 137 | return NO_TIMER_AVAILABLE; 138 | } 139 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/Timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * 19 | Code by Simon Monk 20 | http://www.simonmonk.org 21 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 22 | 23 | #ifndef Timer_h 24 | #define Timer_h 25 | 26 | #include 27 | #include "Event.h" 28 | 29 | #define MAX_NUMBER_OF_EVENTS (10) 30 | 31 | #define TIMER_NOT_AN_EVENT (-2) 32 | #define NO_TIMER_AVAILABLE (-1) 33 | 34 | class Timer 35 | { 36 | 37 | public: 38 | Timer(void); 39 | 40 | int8_t every(unsigned long period, void (*callback)(void)); 41 | int8_t every(unsigned long period, void (*callback)(void), int repeatCount); 42 | int8_t after(unsigned long duration, void (*callback)(void)); 43 | int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue); 44 | int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount); 45 | 46 | /** 47 | * This method will generate a pulse of !startingValue, occuring period after the 48 | * call of this method and lasting for period. The Pin will be left in !startingValue. 49 | */ 50 | int8_t pulse(uint8_t pin, unsigned long period, uint8_t startingValue); 51 | 52 | /** 53 | * This method will generate a pulse of pulseValue, starting immediately and of 54 | * length period. The pin will be left in the !pulseValue state 55 | */ 56 | int8_t pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue); 57 | void stop(int8_t id); 58 | void update(void); 59 | void update(unsigned long now); 60 | 61 | protected: 62 | Event _events[MAX_NUMBER_OF_EVENTS]; 63 | int8_t findFreeEventIndex(void); 64 | 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/examples/blink2/blink2.ino: -------------------------------------------------------------------------------- 1 | //Flash two LEDs at different rates using Simon Monk's Timer library 2 | //http://www.doctormonk.com/2012/01/arduino-timer-library.html 3 | // 4 | //Jack Christensen 30Sep2013 5 | // 6 | //Beerware license: Free for any and all purposes, but if you find it 7 | //useful AND we actually meet someday, you can buy me a beer! 8 | 9 | #include "Timer.h" //http://github.com/JChristensen/Timer 10 | 11 | const int LED1 = 8; //connect one LED to this pin (with appropriate current-limiting resistor of course) 12 | const int LED2 = 9; //connect another LED to this pin (don't forget the resistor) 13 | const unsigned long PERIOD1 = 1000; //one second 14 | const unsigned long PERIOD2 = 10000; //ten seconds 15 | Timer t; //instantiate the timer object 16 | 17 | void setup(void) 18 | { 19 | pinMode(LED1, OUTPUT); 20 | pinMode(LED2, OUTPUT); 21 | t.oscillate(LED1, PERIOD1, HIGH); 22 | t.oscillate(LED2, PERIOD2, HIGH); 23 | } 24 | 25 | void loop(void) 26 | { 27 | t.update(); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/examples/kitchen_sink/kitchen_sink.pde: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | 3 | Timer t; 4 | 5 | int ledEvent; 6 | 7 | void setup() 8 | { 9 | Serial.begin(9600); 10 | int tickEvent = t.every(2000, doSomething); 11 | Serial.print("2 second tick started id="); 12 | Serial.println(tickEvent); 13 | 14 | pinMode(13, OUTPUT); 15 | ledEvent = t.oscillate(13, 50, HIGH); 16 | Serial.print("LED event started id="); 17 | Serial.println(ledEvent); 18 | 19 | int afterEvent = t.after(10000, doAfter); 20 | Serial.print("After event started id="); 21 | Serial.println(afterEvent); 22 | 23 | } 24 | 25 | void loop() 26 | { 27 | t.update(); 28 | } 29 | 30 | void doSomething() 31 | { 32 | Serial.print("2 second tick: millis()="); 33 | Serial.println(millis()); 34 | } 35 | 36 | 37 | void doAfter() 38 | { 39 | Serial.println("stop the led event"); 40 | t.stop(ledEvent); 41 | t.oscillate(13, 500, HIGH, 5); 42 | } 43 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/examples/pin_high_10_mins/pin_high_10_mins.pde: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | 3 | Timer t; 4 | int pin = 13; 5 | 6 | void setup() 7 | { 8 | pinMode(pin, OUTPUT); 9 | t.pulse(pin, 10 * 1000, HIGH); // 10 seconds 10 | // t.pulse(pin, 10 * 60 * 1000, HIGH); // 10 minutes 11 | } 12 | 13 | void loop() 14 | { 15 | t.update(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/examples/read_A0_flashLED/read_A0_flashLED.pde: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | 3 | Timer t; 4 | int pin = 13; 5 | 6 | void setup() 7 | { 8 | Serial.begin(9600); 9 | pinMode(pin, OUTPUT); 10 | t.oscillate(pin, 100, LOW); 11 | t.every(1000, takeReading); 12 | } 13 | 14 | void loop() 15 | { 16 | t.update(); 17 | } 18 | 19 | void takeReading() 20 | { 21 | Serial.println(analogRead(0)); 22 | } 23 | -------------------------------------------------------------------------------- /urobot/Robot/Timer-master/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Timer Library 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Timer KEYWORD1 10 | Event KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | 16 | every KEYWORD2 17 | after KEYWORD2 18 | oscillate KEYWORD2 19 | pulse KEYWORD2 20 | pulseImmediate KEYWORD2 21 | stop KEYWORD2 22 | update KEYWORD2 23 | findFreeEventIndex KEYWORD2 24 | 25 | ####################################### 26 | # Instances (KEYWORD2) 27 | ####################################### 28 | 29 | ####################################### 30 | # Constants (LITERAL1) 31 | ####################################### 32 | -------------------------------------------------------------------------------- /urobot/Robot/ir.cpp: -------------------------------------------------------------------------------- 1 | #include "ir.h" 2 | #include "Arduino.h" 3 | 4 | 5 | 6 | int translateIR(decode_results results) // takes action based on IR code received 7 | 8 | // describing KEYES Remote IR codes 9 | 10 | { 11 | static int latched = 1; 12 | 13 | switch(results.value) 14 | 15 | { 16 | 17 | case 0xFF6897: latched = 1; return 1;//Serial.println(" 1"); break; 18 | case 0xFF9867: latched = 2; return 2;//Serial.println(" 2"); break; 19 | case 0xFFB04F: latched = 3; return 3;//Serial.println(" 3"); break; 20 | case 0xFF30CF: latched = 4; return 4;//Serial.println(" 4"); break; 21 | case 0xFF18E7: latched = 5; return 5;//Serial.println(" 4"); break; 22 | case 0xFF7A85: latched = 6; return 6;//Serial.println(" 1"); break; 23 | case 0xFF10EF: latched = 7; return 7;//Serial.println(" 2"); break; 24 | case 0xFF38C7: latched = 8; return 8;//Serial.println(" 3"); break; 25 | case 0xFF5AA5: latched = 9; return 9;//Serial.println(" 4"); break; 26 | case 0xFF4AB5: latched = 0; return 0;//Serial.println(" 4"); break; 27 | case 0xFFFFFFFF: return latched; 28 | } 29 | 30 | 31 | } //END translateIR 32 | -------------------------------------------------------------------------------- /urobot/Robot/ir.h: -------------------------------------------------------------------------------- 1 | #ifndef IR 2 | #define IR 3 | #include "IRremote/IRremote.h" 4 | #include "IRremote/IRremoteInt.h" 5 | 6 | 7 | int translateIR(decode_results results); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /urobot/Robot/rosToInterface.hpp: -------------------------------------------------------------------------------- 1 | ../InterfaceArduino/rosToInterface.hpp -------------------------------------------------------------------------------- /urobot/Robot/stepper.cpp: -------------------------------------------------------------------------------- 1 | #include "stepper.h" 2 | #include "Arduino.h" 3 | 4 | 5 | 6 | void stepRight(int forward){ 7 | static int state = 0; 8 | if(forward == 1){ 9 | state++; 10 | if (state ==8) state =0; 11 | } 12 | else { 13 | if(state ==0) state = 7; 14 | else state--; 15 | } 16 | //state = state%8; 17 | 18 | switch(state){ 19 | case 0: 20 | SET(PORTD,7); 21 | SET(PORTB,0); 22 | CLR(PORTB,1); 23 | CLR(PORTB,2); 24 | break; 25 | 26 | case 1: 27 | SET(PORTD,7); 28 | SET(PORTB,0); 29 | SET(PORTB,1); 30 | SET(PORTB,2); 31 | break; 32 | case 2: 33 | CLR(PORTD,7); 34 | CLR(PORTB,0); 35 | SET(PORTB,1); 36 | SET(PORTB,2); 37 | break; 38 | case 3: 39 | CLR(PORTD,7); 40 | SET(PORTB,0); 41 | SET(PORTB,1); 42 | SET(PORTB,2); 43 | break; 44 | case 4: 45 | CLR(PORTD,7); 46 | SET(PORTB,0); 47 | CLR(PORTB,1); 48 | CLR(PORTB,2); 49 | break; 50 | case 5: 51 | CLR(PORTD,7); 52 | SET(PORTB,0); 53 | CLR(PORTB,1); 54 | SET(PORTB,2); 55 | break; 56 | case 6: 57 | CLR(PORTD,7); 58 | CLR(PORTB,0); 59 | CLR(PORTB,1); 60 | SET(PORTB,2); 61 | break; 62 | case 7: 63 | SET(PORTD,7); 64 | SET(PORTB,0); 65 | CLR(PORTB,1); 66 | SET(PORTB,2); 67 | break; 68 | } 69 | } 70 | 71 | void stepLeft(int forward){ 72 | static int state = 0; 73 | if(forward == 1){ 74 | state++; 75 | if (state ==8) state =0; 76 | } 77 | else { 78 | if(state ==0) state = 7; 79 | else state--; 80 | } 81 | 82 | switch(state){ 83 | case 0: 84 | SET(PORTC,0); 85 | SET(PORTC,2); 86 | CLR(PORTD,6); 87 | CLR(PORTD,2); 88 | break; 89 | 90 | case 1: 91 | SET(PORTC,0); 92 | SET(PORTC,2); 93 | SET(PORTD,6); 94 | SET(PORTD,2); 95 | break; 96 | case 2: 97 | CLR(PORTC,0); 98 | CLR(PORTC,2); 99 | SET(PORTD,6); 100 | SET(PORTD,2); 101 | break; 102 | case 3: 103 | CLR(PORTC,0); 104 | SET(PORTC,2); 105 | SET(PORTD,6); 106 | SET(PORTD,2); 107 | break; 108 | case 4: 109 | CLR(PORTC,0); 110 | SET(PORTC,2); 111 | CLR(PORTD,6); 112 | CLR(PORTD,2); 113 | break; 114 | case 5: 115 | CLR(PORTC,0); 116 | SET(PORTC,2); 117 | CLR(PORTD,6); 118 | SET(PORTD,2); 119 | break; 120 | case 6: 121 | CLR(PORTC,0); 122 | CLR(PORTC,2); 123 | CLR(PORTD,6); 124 | SET(PORTD,2); 125 | break; 126 | case 7: 127 | SET(PORTC,0); 128 | SET(PORTC,2); 129 | CLR(PORTD,6); 130 | SET(PORTD,2); 131 | break; 132 | } 133 | } 134 | 135 | void looseMotors(){ 136 | CLR(PORTC,0); 137 | CLR(PORTC,2); 138 | CLR(PORTD,6); 139 | CLR(PORTD,2); 140 | CLR(PORTD,7); 141 | CLR(PORTB,0); 142 | CLR(PORTB,1); 143 | CLR(PORTB,2); 144 | } 145 | 146 | void looseRight(){ 147 | CLR(PORTD,7); 148 | CLR(PORTB,0); 149 | CLR(PORTB,1); 150 | CLR(PORTB,2); 151 | } 152 | void looseLeft(){ 153 | CLR(PORTC,0); 154 | CLR(PORTC,2); 155 | CLR(PORTD,6); 156 | CLR(PORTD,2); 157 | } 158 | -------------------------------------------------------------------------------- /urobot/Robot/stepper.h: -------------------------------------------------------------------------------- 1 | #ifndef stepper 2 | #define stepper 3 | #define CLR(x,y) (x&=(~(1< 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /urobot/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | urobot 4 | 0.0.0 5 | The urobot package 6 | 7 | 8 | 9 | 10 | josh 11 | 12 | 13 | 14 | 15 | 16 | TODO 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | catkin 43 | roscpp 44 | rospy 45 | std_msgs 46 | roscpp 47 | rospy 48 | std_msgs 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /urobot/src/2016-06-13-192006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/2016-06-13-192006.jpg -------------------------------------------------------------------------------- /urobot/src/2016-06-13-192023.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/2016-06-13-192023.jpg -------------------------------------------------------------------------------- /urobot/src/2016-06-13-192037.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/2016-06-13-192037.jpg -------------------------------------------------------------------------------- /urobot/src/2016-06-13-192048.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/2016-06-13-192048.jpg -------------------------------------------------------------------------------- /urobot/src/RobotClass.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | #include "RobotClass.hpp" 20 | 21 | RobotClass::RobotClass(ros::NodeHandle nh, int ID,bool shouldListen){ 22 | myID = ID; 23 | std::stringstream robotName; 24 | robotName << "/robot"<< ID; 25 | 26 | std::stringstream LEDStatePubString; 27 | LEDStatePubString << robotName.str() << "/LEDState"; 28 | LEDstatePub = nh.subscribe(LEDStatePubString.str(),1,&RobotClass::LEDCB,this); 29 | 30 | std::stringstream twistPubString; 31 | twistPubString << robotName.str() << "/twist"; 32 | twistPub = nh.advertise(twistPubString.str(),1,this); 33 | //if(shouldListen) 34 | twistSub = nh.subscribe(twistPubString.str(),1,&RobotClass::twistCB,this); 35 | 36 | std::stringstream positionSubString; 37 | positionSubString << robotName.str() << "/position"; 38 | positionSub = nh.subscribe(positionSubString.str(),1,&RobotClass::positionCB,this); 39 | 40 | std::stringstream batterySubString; 41 | batterySubString << robotName.str() << "/battery"; 42 | batterySub = nh.subscribe(batterySubString.str(),1,&RobotClass::batteryCB,this); 43 | 44 | std::stringstream leftSensorSubString; 45 | leftSensorSubString << robotName.str() << "/leftSensor"; 46 | leftSensorSub = nh.subscribe(leftSensorSubString.str(),1,&RobotClass::leftSensorCB,this); 47 | 48 | std::stringstream rightSensorSubString; 49 | rightSensorSubString << robotName.str() << "/rightSensor"; 50 | rightSensorSub = nh.subscribe(rightSensorSubString.str(),1,&RobotClass::rightSensorCB,this); 51 | 52 | std::stringstream backSensorSubString; 53 | backSensorSubString << robotName.str() << "/backSensor"; 54 | backSensorSub = nh.subscribe(backSensorSubString.str(),1, &RobotClass::backSensorCB,this); 55 | } 56 | void RobotClass::rightSensorCB(const std_msgs::Int32ConstPtr &msg){ 57 | rightSensor = *msg; 58 | } 59 | 60 | void RobotClass::leftSensorCB(const std_msgs::Int32ConstPtr &msg){ 61 | leftSensor = *msg; 62 | } 63 | void RobotClass::backSensorCB(const std_msgs::Int32ConstPtr &msg){ 64 | backSensor = *msg; 65 | } 66 | void RobotClass::LEDCB(const std_msgs::Int32ConstPtr &msg){ 67 | LEDState = *msg; 68 | } 69 | 70 | void RobotClass::positionCB(const geometry_msgs::PointConstPtr &msg){ 71 | position = *msg; 72 | } 73 | 74 | void RobotClass::batteryCB(const std_msgs::Int32ConstPtr &msg){ 75 | battery = *msg; 76 | } 77 | void RobotClass::publishTwist(geometry_msgs::TwistStamped twist){ 78 | RobotClass::twistPub.publish(twist); 79 | } 80 | void RobotClass::twistCB(const geometry_msgs::TwistStampedConstPtr &msg){ 81 | twistIn = msg->twist; 82 | ROS_INFO("in class %d",this); 83 | } 84 | 85 | geometry_msgs::Twist RobotClass::getTwist(){ 86 | return twistIn; 87 | } 88 | 89 | void RobotClass::publishTF(cv::Point2f led, cv::Point2f head, ros::Time time){ 90 | static tf::TransformBroadcaster broad; 91 | tf::Transform transform; 92 | cv::Point2f middle = 0.55*led + 0.45*head; 93 | transform.setOrigin( tf::Vector3(middle.x, middle.y, 0.0) ); 94 | tf::Quaternion q; 95 | q.setRPY(0, 0, getAngle(led,head)); 96 | transform.setRotation(q); 97 | std::stringstream robotName; 98 | robotName << "robot"<< myID; 99 | std::string name = robotName.str(); 100 | broad.sendTransform(tf::StampedTransform(transform, time, "world", robotName.str())); 101 | 102 | } 103 | 104 | float RobotClass::getAngle(cv::Point2f led, cv::Point2f head){ 105 | const float PI = 3.14159f; 106 | 107 | float x = head.x-led.x; 108 | float y = head.y - led.y; 109 | 110 | // atan2 receives first Y second X 111 | double angle = atan2(y, x); 112 | if (angle < 0) angle += 2*PI; 113 | return angle; 114 | // 115 | 116 | 117 | 118 | } 119 | -------------------------------------------------------------------------------- /urobot/src/RobotClass.hpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | #ifndef ROBOT_CLASS_H 20 | #define ROBOT_CLASS_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | 33 | class RobotClass { 34 | public: 35 | 36 | 37 | 38 | //variables 39 | std_msgs::Int32 leftSensor; 40 | std_msgs::Int32 rightSensor; 41 | std_msgs::Int32 backSensor; 42 | std_msgs::Int32 battery; 43 | geometry_msgs::Point position; 44 | geometry_msgs::Twist twistIn; 45 | geometry_msgs::TwistStamped twistOut; 46 | std_msgs::Int32 LEDState; 47 | tf::TransformBroadcaster* br; 48 | int myID; 49 | 50 | 51 | 52 | 53 | //constructor 54 | RobotClass(ros::NodeHandle nh, int ID, bool shouldListen); 55 | 56 | //pub functions 57 | void publishTwist(geometry_msgs::TwistStamped twist); 58 | geometry_msgs::Twist getTwist(); 59 | 60 | void publishTF(cv::Point2f led, cv::Point2f head, ros::Time time); 61 | float getAngle(cv::Point2f led, cv::Point2f head); 62 | private: 63 | void rightSensorCB(const std_msgs::Int32ConstPtr &msg); 64 | void leftSensorCB(const std_msgs::Int32ConstPtr &msg); 65 | void backSensorCB(const std_msgs::Int32ConstPtr &msg); 66 | void LEDCB(const std_msgs::Int32ConstPtr &msg); 67 | void positionCB(const geometry_msgs::PointConstPtr &msg); 68 | void batteryCB(const std_msgs::Int32ConstPtr &msg); 69 | void twistCB(const geometry_msgs::TwistStampedConstPtr &msg); 70 | 71 | // subs and pubs for all robot specific topics. 72 | ros::Subscriber LEDstatePub; 73 | ros::Publisher twistPub; 74 | ros::Subscriber twistSub; 75 | ros::Subscriber positionSub; 76 | ros::Subscriber batterySub; 77 | ros::Subscriber leftSensorSub; 78 | ros::Subscriber rightSensorSub; 79 | ros::Subscriber backSensorSub; 80 | 81 | 82 | }; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /urobot/src/activity_node.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "RobotClass.hpp" 36 | #include "rosToInterface.hpp" 37 | 38 | using namespace std; 39 | 40 | 41 | // this struct should hold all the interfaces for a given robot, each node should initialise the ones that it needs to use. 42 | 43 | 44 | class activity_node{ 45 | 46 | ros::Subscriber isInitSub; 47 | ros::Subscriber joySub; 48 | ros::Publisher instructionPush; 49 | bool isInit= 0; 50 | vector robotInterface; 51 | int number_robots; 52 | ros::NodeHandle nh_; 53 | 54 | public: 55 | activity_node(int robotNum); 56 | void isInitCB(const std_msgs::BoolConstPtr& msg); 57 | void joyCB(const sensor_msgs::JoyConstPtr& msg); 58 | 59 | }; 60 | 61 | activity_node::activity_node(int robotNum){ 62 | number_robots = robotNum; 63 | ROS_INFO("there are %d robots in this activity",number_robots); 64 | //make a vector of the right size with pub/sub for all features. 65 | instructionPush = nh_.advertise("/instructionPush",1,this); 66 | joySub = nh_.subscribe("/joy",1,&activity_node::joyCB,this); 67 | isInitSub= nh_.subscribe("urobot_init_node/isInit", 1,&activity_node::isInitCB,this); 68 | //do launching of stuff here, find all the robots and give them names. When complete call the 'publishIsInit' function. This is best to hapen only once, so lauch this node last and have others wait for this signal. 69 | for(int i= 0; i < number_robots; i ++){ 70 | RobotClass* newRobot = new RobotClass(nh_,i,1); 71 | robotInterface.push_back(newRobot); 72 | } 73 | 74 | } 75 | 76 | //in here I expect there to be lots of string forming to subscribe to the right things. 77 | 78 | 79 | void activity_node::isInitCB(const std_msgs::BoolConstPtr& msg) 80 | { 81 | if (msg->data == true){ 82 | isInit =1; 83 | } 84 | 85 | //setup and launch the rest of the activity. 86 | } 87 | 88 | //here should do something nice to take controll of all the buttons. 89 | void activity_node::joyCB(const sensor_msgs::JoyConstPtr& msg){ 90 | static float oldLin = 0; 91 | static float oldAng = 0; 92 | geometry_msgs::Vector3 linear; 93 | linear.x = msg->axes.at(1); 94 | geometry_msgs::Vector3 angular; 95 | angular.z = msg->axes.at(0); 96 | if(oldLin!=linear.x || oldAng != angular.z){ 97 | for(int i = 0; i < robotInterface.size(); i++){ 98 | geometry_msgs::TwistStamped thisTwist; 99 | ROS_INFO("%d , %f",0,linear.x); 100 | ROS_INFO("%d , %f",1,angular.z ); 101 | thisTwist.twist.linear = linear; 102 | thisTwist.twist.angular = angular; 103 | thisTwist.header.stamp = msg->header.stamp; 104 | //robotInterface.at(i).twistOut = thisTwist; 105 | robotInterface.at(i)->publishTwist(thisTwist); 106 | ros::spinOnce(); 107 | } 108 | ros::spinOnce(); 109 | std_msgs::Int32 pushType; 110 | pushType.data =CmdLINANG; 111 | oldLin = linear.x; 112 | oldAng = angular.z; 113 | instructionPush.publish(pushType); 114 | } 115 | ros::spinOnce(); 116 | } 117 | 118 | 119 | int main(int argc, char** argv) { 120 | 121 | //ros setup 122 | ros::init(argc, argv, "activity_node"); 123 | activity_node AN(atoi(argv[1])); 124 | ros::spin(); 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /urobot/src/communication_node.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "RobotClass.hpp" 40 | #include "rosToInterface.hpp" 41 | 42 | using namespace std; 43 | 44 | 45 | 46 | 47 | class communication_node{ 48 | int fd; 49 | ros::Subscriber isInitSub; 50 | ros::Subscriber instructionPush; 51 | vector robotInterface; 52 | char *portname= "/dev/ttyACM0"; 53 | bool isInit= 0; 54 | int number_robots; 55 | ros::NodeHandle nh_; 56 | 57 | public: 58 | communication_node(int numRobot); 59 | void isInitCB(const std_msgs::BoolConstPtr& msg); 60 | void instructionPushCB(const std_msgs::Int32ConstPtr& msg); 61 | int set_interface_attribs (int fd, int speed, int parity); 62 | void set_blocking (int fd, int should_block); 63 | void sendInstruction(instructionPack thisInstruction); 64 | }; 65 | 66 | communication_node::communication_node(int numRobot){ 67 | fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); //setting up serial. 68 | if (fd < 0) 69 | { 70 | ROS_ERROR("error %d opening %s: %s", errno, portname, strerror (errno)); 71 | return; 72 | } 73 | set_interface_attribs (fd, B115200, 0); 74 | set_blocking (fd, 0); 75 | number_robots = numRobot; 76 | ROS_INFO("I will Communicate with %d robots",number_robots); 77 | isInitSub= nh_.subscribe("urobot_init_node/isInit", 1,&communication_node::isInitCB,this); 78 | instructionPush = nh_.subscribe("instructionPush",1,&communication_node::instructionPushCB,this); 79 | //setup and launch the rest of the activity. 80 | for(int i= 0; i < number_robots; i ++){ 81 | RobotClass* newRobot = new RobotClass(nh_,i,1); 82 | robotInterface.push_back(newRobot); 83 | } 84 | //do launching of stuff here, find all the robots and give them names. When complete call the 'publishIsInit' function. This is best to hapen only once, so lauch this node last and have others wait for this signal. 85 | } 86 | 87 | void communication_node::isInitCB(const std_msgs::BoolConstPtr& msg) 88 | { 89 | if (msg->data == true){ 90 | isInit =1; 91 | } 92 | 93 | 94 | } 95 | 96 | void communication_node::instructionPushCB(const std_msgs::Int32ConstPtr& msg) 97 | { 98 | ROS_INFO("pushing some data"); 99 | int instructionType = msg->data; 100 | uint8_t ID = rand(); 101 | switch (instructionType){ 102 | case CmdLINANG: 103 | for(int i = 0; i < robotInterface.size(); i ++){ 104 | 105 | 106 | instructionPack thisInstruction; 107 | thisInstruction.instructionType = (uint8_t)CmdLINANG; 108 | thisInstruction.instructionID = ID; 109 | //LinAng type has a 4bit signed lin and ang put into one 8bit type; giving 8 speeds of all F/B/L/R 110 | geometry_msgs::Twist thisTwist = robotInterface.at(i)->getTwist(); 111 | float lin = robotInterface.at(i)->twistIn.linear.x;// scale a linear normalised value up to 127; 112 | int8_t intLin = 16*(int8_t)lin; 113 | float ang = robotInterface.at(i)->twistIn.angular.z; 114 | int8_t intAng = 16*(int8_t)ang; 115 | intLin &= 0b11110000; 116 | intAng = intAng >> 4; 117 | intAng &= 0b00001111; 118 | int8_t result = intLin | intAng; 119 | thisInstruction.value1 = result; 120 | ///ARDUIO debug 121 | int8_t Alin = result & 0b11110000; 122 | int8_t Aang = result & 0b00001111; 123 | Alin = Alin >> 4; 124 | if(Aang & 0b00001000){ //extend the top bit to recover 2s comp. 125 | Aang = Aang | 0b11110000; 126 | } 127 | 128 | ///// 129 | int8_t ardLin =result & 0b11110000; 130 | int8_t ardAng; 131 | thisInstruction.robotID = i; 132 | ROS_INFO("hello some data %d, %f ,%f",result,robotInterface.at(i)->twistIn.linear.x,ang); 133 | communication_node::sendInstruction(thisInstruction); 134 | 135 | 136 | 137 | } 138 | } 139 | 140 | } 141 | 142 | void communication_node::sendInstruction(instructionPack thisInstruction){ 143 | instructionUnion myUnion; 144 | myUnion.pack = thisInstruction; 145 | write(fd,myUnion.bytes,sizeof(thisInstruction)); 146 | fsync(fd); 147 | 148 | } 149 | 150 | //The set_interface_attribs and set_blocking functions were liberated from user wallyk on stack overflow. http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c 151 | int communication_node::set_interface_attribs (int fd, int speed, int parity) 152 | { 153 | struct termios tty; 154 | memset (&tty, 0, sizeof tty); 155 | if (tcgetattr (fd, &tty) != 0) 156 | { 157 | ROS_ERROR("error %d from tcgetattr", errno); 158 | return -1; 159 | } 160 | 161 | cfsetospeed (&tty, speed); 162 | cfsetispeed (&tty, speed); 163 | 164 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars 165 | // disable IGNBRK for mismatched speed tests; otherwise receive break 166 | // as \000 chars 167 | tty.c_iflag &= ~IGNBRK; // disable break processing 168 | tty.c_lflag = 0; // no signaling chars, no echo, 169 | // no canonical processing 170 | tty.c_oflag = 0; // no remapping, no delays 171 | tty.c_cc[VMIN] = 0; // read doesn't block 172 | tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 173 | 174 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 175 | 176 | tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, 177 | // enable reading 178 | tty.c_cflag &= ~(PARENB | PARODD); // shut off parity 179 | tty.c_cflag |= parity; 180 | tty.c_cflag &= ~CSTOPB; 181 | tty.c_cflag &= ~CRTSCTS; 182 | 183 | if (tcsetattr (fd, TCSANOW, &tty) != 0) 184 | { 185 | ROS_ERROR("error %d from tcgetattr", errno); 186 | return -1; 187 | } 188 | return 0; 189 | } 190 | 191 | void communication_node::set_blocking (int fd, int should_block) 192 | { 193 | struct termios tty; 194 | memset (&tty, 0, sizeof tty); 195 | if (tcgetattr (fd, &tty) != 0) 196 | { 197 | ROS_ERROR("error %d from tcgetattr", errno); 198 | return; 199 | } 200 | 201 | tty.c_cc[VMIN] = should_block ? 1 : 0; 202 | tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 203 | 204 | if (tcsetattr (fd, TCSANOW, &tty) != 0) 205 | ROS_ERROR("error %d from tcgetattr", errno); 206 | } 207 | 208 | 209 | int main(int argc, char** argv) { 210 | 211 | //ros setup 212 | 213 | ros::init(argc, argv, "communication_node"); 214 | communication_node CN(atoi(argv[1])); 215 | ros::spin(); 216 | return 0; 217 | } 218 | -------------------------------------------------------------------------------- /urobot/src/niceLight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/niceLight.jpg -------------------------------------------------------------------------------- /urobot/src/rosToInterface.hpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | 19 | //this is to define structures ect for communicating over the serial from the ros system to the IR distribution board. 20 | 21 | 22 | //definitions for enumerations 23 | //#define RqstBATTERY 0 24 | //#define RqstRSENSOR 1 25 | //#define RqstLSENSOR 2 26 | //#define RqstBSENSOR 3 27 | 28 | //#define CmdLINEAR 4 29 | //#define CmdANGULAR 5 30 | //#define CmdLED 6 31 | //#define CmdSPECIAL 7 32 | //#define CmdLINANG 8 33 | 34 | #define ARDUINO_H 35 | #include 36 | #include 37 | #include 38 | #include //needed for memcpy 39 | 40 | enum instructType{ 41 | RqstBATTERY=0, 42 | RqstRSENSOR=1, 43 | RqstLSENSOR=2, 44 | RqstBSENSOR=3, 45 | 46 | CmdLINEAR=4, 47 | CmdANGULAR=5, 48 | CmdLED=6, 49 | CmdSPECIAL=7, 50 | CmdLINANG=8 51 | }; 52 | 53 | 54 | //one packet is sent over for each robot, as we do not know at any one time how many robots there are. The bandwidth is plenty to allow us to be verbose. 55 | struct instructionPack { 56 | uint8_t instructionType; //for the moment we are thinking this should alaways start with 1010. giving 16 options for instruction types. 57 | uint8_t instructionID; 58 | uint8_t robotID; 59 | uint8_t value1; 60 | }; 61 | 62 | union instructionUnion { 63 | instructionPack pack; 64 | char bytes[sizeof(instructionPack)]; 65 | }; 66 | -------------------------------------------------------------------------------- /urobot/src/urobot_init_node.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2016 "Joshua Elsdon," 2 | Micro Robots Project 3 | 4 | This file is part of Micro Robots. 5 | 6 | Micro Robots is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see .*/ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "RobotClass.hpp" 35 | 36 | 37 | 38 | using namespace std; 39 | 40 | 41 | // this struct should hold all the interfaces for a given robot, each node should initialise the ones that it needs to use. 42 | 43 | 44 | 45 | class init_node{ 46 | 47 | ros::Publisher isInitPub; 48 | vector robotInterface; 49 | int number_robots; 50 | ros::NodeHandle nh_; 51 | image_transport::ImageTransport it_; 52 | public: 53 | init_node(int numRobots); 54 | void publishIsInit(); 55 | }; 56 | 57 | init_node::init_node(int numRobots): it_(nh_){ 58 | number_robots = numRobots; 59 | ROS_INFO("I will initialise %d robots",number_robots); 60 | isInitPub = nh_.advertise("/isInit",1,this); 61 | 62 | //do launching of stuff here/////////////////////////////////////////////// 63 | for(int i= 0; i < number_robots; i ++){ 64 | RobotClass newRobot(nh_,i,0); 65 | robotInterface.push_back(newRobot); 66 | } 67 | 68 | 69 | 70 | //end launching stuff////////////////////////////////////////////////////// 71 | publishIsInit(); 72 | 73 | } 74 | void init_node::publishIsInit() 75 | { 76 | std_msgs::Bool initMsg; 77 | initMsg.data = true; 78 | isInitPub.publish(initMsg); 79 | } 80 | 81 | int main(int argc, char** argv) { 82 | 83 | //ros setup 84 | 85 | ros::init(argc, argv, "urobot_init_node"); 86 | init_node IN(atoi(argv[1])); 87 | ros::spin(); 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /urobot/src/wellLitbig.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/je310/microRobotsROS/6b2f850d82e368c9d12c4e6e0a7b547f16500bb5/urobot/src/wellLitbig.jpg --------------------------------------------------------------------------------