Introduction: Remote-Controlled 360-Degree RICOH THETA Camera With MESH Blocks
Create a simple wireless button to control a 360-Degree RICOH THETA camera using MESH blocks.
Step 1: Materials
Here's what you'll need to build your own 360 camera stick with a remote trigger.
- (x1) RICOH THETA (360-Degree Camera)
- (x1) MESH button
- (x1) Camera extension arm
- Velcro tape
- (x1) iPhone (or Android phone compatible with MESH app) with MESH app
As always, you can get MESH IoT blocks on Amazon at 10% off with discount code MAKERS00 as a thank you for checking out our Instructable and get more information about MESH IoT blocks at meshprj.com.
Step 2: Add a Remote Control to Camera Extension Arm
Use velcro tape to attach a MESH Button to the camera extension arm. Once MESH button is attached it, we will guide you through how to connect MESH Button to use it as a remote control for the RICOH THETA 360-degree camera.
Step 3: Create a Remote Control Recipe in the MESH App
You'll use visual programming in the MESH app to create a recipe that connects MESH Button and RICOH THETA.
Overview:
- Drag a Button tag and Speaker tag onto the canvas in the MESH app.
- Create a custom tag for RICOH THETA using MESH SDK. (See below for details)
Step 4: Launch MESH SDK to Connect MESH and RICOH THETA
You'll use the MESH SDK to connect MESH to RICOH THETA
- To get started, visit http://meshprj.com/sdk and click "start using the MESH SDK"
- MESH SDK reference and support can be found here: https://meshprj.com/sdk/doc/
Step 5: Create a New Tag for RICOH THETA in the MESH SDK
Once you've created an account for MESH SDK, you can then create a new custom tag RICOH THETA in the MESH app.
- In the MESH SDK, tap "Create New Tag" to create new custom tag
- Tap "New Function"
Step 6: Import Code to Create RICOH THETA Custom Tag
3. Import the following js into MESH SDK:
{"formatVersion":"1.0","tagData":{"name":"Take 360 photo","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAI3klEQVR4Xu1cV4gWMRCes3exV9QTRBFEBFEUewN7FxUFRcSuKBZs2HvDB1FE7Hp27L23BxV8sWBBVGzYPRV74VvdZeu/2Vx29/SfgXv5bzJJvi+ZTCbJpqSnp/8iltgQSGECYsNeq5gJiBd/JiBm/JkAJiBuBGKu/59eA27fvk2/fv0J4ipUqEA5c+aMGc7g1f8zBEyfPp0uXLhAX79+9e1l1qxZKVeuXLRy5UoqXbq0r36cCpmWAIzsAwcO0KJFizKMT/HixWn9+vWZcoZkSgI2bdpEq1atyjDwdgOFChWiDRs2UN68eZXbljWYqQh49OgR9e7d27UvWbJkoerVq1PPnj2pZs2anv199eoVbdu2jU6fPk3Pnz931evYsSMNHz5cFjOl5TINAStWrKCtW7c6OlexYkWC/y9TpoxUx9esWaO5H7tkz56dDh06RFgv4pRMQcCQIUPoxo0bFhzgt9etW6ctpirEy63t2LGDihQpoqIKKRuxE9CtWzd68eKFpfFz586l2rVrS3UoUaEvX75oLuz169cWte3bt1PRokWV1ydiMFYCunbtSi9fvjTamS1bNtq7dy/lzp1bpO2azq1bt6hy5crC+lCcOXMmnThxwlLm8OHDsURJsREwefJkOn/+vAECIpN9+/ZRSkqKJ5hXrlwhlPv8+bOnDkjEYr1w4cKEpCDENeug3pMnTwYiUoVyLAQ8ePCA+vTpY7QfC+LRo0c9+7N27VptPZCRI0eOUI4cOVyLLl++XIuYdClVqhRt3rxZphrpMrEQ0LhxY6PBiUbemzdvqFOnTtKd0wt26dKFsNC7Sb9+/ejevXvGvyZMmEDNmzfPcJ2iBiInYM6cOZbRjtFdvnx5R3uPHz9Os2bNEu2Hr16JEiVoy5YtrnrNmjWjHz9+GP+DK0rkCn0rC6AQKQHfvn2jFi1aGM0rV66cq2tBfD5//nzPbmC9wCitU6eOtj94+/atFsaeOXOGrl+/7lmucOHCtHPnTsf/ERV17tzZ+B2R2aBBgwLAKK8aKQELFiyggwcPGq3FKLdvhOAO4BbcpEqVKtrC6ZdKQCS1ZMkSVxuImLDps8vgwYPp5s2bkc+CSAkw+36M3tmzZzuAaNq0Kf38+dPx+7Jly6hq1arG7xjp2Dlj9GORRXqie/fulnLt2rWj9+/fO2xNmjSJUI9ZPnz4QG3btjV+mjdvHtWqVUt+aAuWjIyAa9eu0bBhw4xmIQzMkyePpZlIOZw6dcrR9P379xujHrMILko/B7ArY1eLSEaPfHr16kWPHz922MQ+APkls5h18T/7XkEQ00BqkREwdOhQi3+2A/39+3fX6AM+G74bgvUD64iImHfT5pmnl0V0ZR4Q+P3SpUs0btw4w7wbSSJ1B9GJjAAzCKNHj6bWrVtb2ukW68PnI1aH2EHEbnnp0qVUqVIlzWXBZdj3Ekg9ly1blj5+/Eht2rRx4OI228z17N69mwoWLBgEz8C6kRCAnWvLli2NxrnlXtxGqT4Cp06dqkU4EISH8P3FihVzdNYtna2DjNEON2gW7Lzz5ctn+c28btSvX1/LxIYpkRDw9OlTLQmmi33k2cNT6Om7UsTniNN1AfjIlOry8OFDzUUBSBxZYoE1S4MGDWjatGnaOgAfbxbYnThxouW3GTNmWFISbrNEJSGREHD16lUaNWqUJwFu4CBURMgIt4LNG8Q8Is+ePUtTpkzxxcK8mLrNMjvASE8j4vIaLL4VBlSIhADkW3RfjvbZO33x4kXHSNyzZw8VKFDA4vvNPtkNTK++6/XBDdoTefa2XL58mcaOHft/EYBNETZHEOxcN27caMHKnpnEP/UkmhloHSz47sWLFwuPNb2cW0hqJ8A+G/8LFyRDAHbMiHTcCAiaJ2ICJGaAHv8jfEQYCYHPb9SokXYmYD5L8JsKOgFNmjRxbOB4BhBp93/sByjIhNatW1fbvGETJys4oDl27JhWXGQRZhdkQhqjEykHjFxZGTNmDLVq1YpwjXHAgAEOMzwDPGYAkEIIitMyRD/Y9cqIDjBSDzjgsQsTkICA/PnzG9FT//796e7du4E40Am8f/8+9e3b17UsE5CAACA2YsQI6tChgwYe3AkO5kVk165dhKuIyBPZU8/m8kyADwEAC1GPvg7Al2NR9sqK4jRr4MCBxpEiTs6QafUSJkCAAICHXax5h4pLVrhT9OnTJw1sjHY9bQ197Hix+HqdG+iEMAGCBAAwHF9iU1etWrWEXqhHjx707NkzEU/lSItwGCoE2x8lEIE/uBikLt69exeg9B9VngEBZkBgdAUKMAFMQPifKpBJxgkMXiUqPAN4BvAMME+lpIyCEqUKlPiZBEbYBRFReno6tW/fPmysHfZxs8J8PR0KSTkD0PEgZ7yqmFq9ejWlpqZazCUtAbg1gdsTUYrbzbekJcB+dyhsIryuqictAQAcd/TtLxjDIsLr2mFSE2B/KBEW+Lh2jrukbpLUBAAQfOEkLS0tLOw1u4meICU9AQAILyjxkjIM0W/cedlmAv4i4/aCPqOEuN2GtttkAkyI4LEEHk1kVMx3g/xsMQE2hLBLxtsvHD3KCF7VjB8/XrgoE+AB1Z07dwgPNZ48eeILJo4u8QJn5MiRvrrsggJDRNpz0nPnzmlk4EsreJyBx3k1atSghg0ben6aQKQqngEiKIWowwSECK6IaSZABKUQdZiAEMEVMc0EiKAUog4TECK4IqaZABGUQtRhAkIEV8Q0E+CDEo4ucTM6keCzY7IfemUCfAgQObzH5wbq1asnMuAdOkwAEyA1cBIW8rsbGqRGngFB0PqrywR4gxbJxzqYACZAeN7yIsyLsPBgEVZkF/QfuSB8+03/eopXt/A90pIlSwoPELMiuyAp2NQVYgLUYSlliQmQgk1dISZAHZZSlpgAKdjUFWIC1GEpZYkJkIJNXSEmQB2WUpaYACnY1BViAtRhKWWJCZCCTV0hJkAdllKWmAAp2NQVYgLUYSlliQmQgk1dISZAHZZSlpgAKdjUFWIC1GEpZSlqAn4DHHf3qiUrqzcAAAAASUVORK5CYII=","description":"This software tag enables mesh to control Ricoh Theta S camera, such as taking pictures ","functions":[{"id":"function_0","name":"TakePicture","connector":{"inputs":[{"label":""}],"outputs":[{"label":""}]},"properties":[],"extension":{"initialize":"return {\n\truntimeValues : { sessionId: \"\" }\n}","receive":"","execute":"//Theta Endpoint URL(Default: 192.168.1.1)\nvar endPointURL = \"http://192.168.1.1\"\n\nvar startSessionJSONData = {\n\tname: \"camera.startSession\"\n} \n\najax( {\n\turl : endPointURL + \"/osc/commands/execute\",\n\ttype : \"post\",\n\tdata : JSON.stringify( startSessionJSONData),\n\tcontentType: \"application/json\",\n\tdataType: \"json\",\n\ttimeout : 5000,\n\tsuccess : function (contents) {\n\t\truntimeValues.sessionId = contents.results.sessionId;\n\t\tlog(\"Theta session started: \" + runtimeValues.sessionId);\n\t\tcheckCaptureMode(endPointURL);\n\t\ttakeThetaPicture(endPointURL);\n\t\tcloseThetaSession(endPointURL);\n\t\tcallbackSuccess( {\n\t\t\t\t\tresultType : \"continue\", \n\t\t\t\t\truntimeValues : runtimeValues\n\t\t});\n\t},\n\terror : function (XMLHttpRequest, textStatus, errorThrown) {\n\t\tlog(XMLHttpRequest + \" | \" + textStatus + \" | \" + errorThrown);\t\t\n\t\tcallbackSuccess({\n\t\t\tresultType: \"continue\"\n\t\t});\n\t}\n});\n\nfunction checkCaptureMode(endPointURL) {\n\tvar getOptionsJSONData = {\n\t\tname: \"camera.getOptions\",\n\t\tparameters: {\n\t\t\tsessionId: runtimeValues.sessionId,\n\t\t\toptionNames: [\"captureMode\"]\n\t\t}\n\t} \n\t\n\tajax( {\n\t\turl : endPointURL + \"/osc/commands/execute\",\n\t\ttype : \"post\",\n\t\tdata : JSON.stringify( getOptionsJSONData),\n\t\tcontentType: \"application/json\",\n\t\tdataType: \"json\",\n\t\ttimeout : 5000,\n\t\tsuccess : function (contents) {\n\t\t\tlog(\"CaptureMode: \" + JSON.stringify(contents.results.options.captureMode));\n\t\t\tif(contents.results.options.captureMode != \"image\"){\n\t\t\t\tlog(\"Please change capture mode to take photo\");\n\t\t\t\tcallbackSuccess({\n\t\t\t\t\tresultType: \"stop\"\n\t\t\t\t});\n\t\t\t};\t\n\t\t\tcallbackSuccess( {\n\t\t\t\t\tresultType : \"continue\"\n\t\t\t});\n\t\t},\n\t\terror : function (XMLHttpRequest, textStatus, errorThrown) {\n\t\t\tlog(\"Error:\" + textStatus + \" \" + errorThrown);\t\t\n\t\t\tcallbackSuccess({\n\t\t\t\tresultType: \"continue\"\n\t\t\t});\n\t\t}\n\t} );\n}\n\nfunction takeThetaPicture(endPointURL) {\n\tvar takePictureJSONData = {\n\t\tname: \"camera.takePicture\",\n\t\tparameters: {\n\t\t\tsessionId: runtimeValues.sessionId\n\t\t}\n\t} \n\n\tajax( {\n\t\turl : endPointURL + \"/osc/commands/execute\",\n\t\ttype : \"post\",\n\t\tdata : JSON.stringify( takePictureJSONData),\n\t\tcontentType: \"application/json\",\n\t\tdataType: \"json\",\n\t\ttimeout : 5000,\n\t\tsuccess : function (contents) {\n\t\t\t\tlog(\"Took picture\");\n\t\t},\n\t\terror : function (XMLHttpRequest, textStatus, errorThrown) {\n\t\t\tlog(\"Error:\" + textStatus + \" \" + errorThrown);\t\t\n\t\t\tcallbackSuccess({\n\t\t\t\tresultType: \"continue\"\n\t\t\t});\n\t\t}\n\t} );\n}\n\nfunction closeThetaSession(endPointURL) {\n\tvar closeSessionJSONData = {\n\t\tname: \"camera.closeSession\",\n\t\tparameters: {\n\t\t\tsessionId: runtimeValues.sessionId\n\t\t}\n\t} \n\n\tajax( {\n\t\turl : endPointURL + \"/osc/commands/execute\",\n\t\ttype : \"post\",\n\t\tdata : JSON.stringify( closeSessionJSONData),\n\t\tcontentType: \"application/json\",\n\t\tdataType: \"json\",\n\t\ttimeout : 5000,\n\t\tsuccess : function (contents) {\n\t\t\tlog(\"Theta session closed: \" + runtimeValues.sessionId);\n\t\t\t},\n\t\terror : function (XMLHttpRequest, textStatus, errorThrown) {\n\t\t\tlog(\"Error:\" + textStatus + \" \" + errorThrown);\t\t\n\t\t\tcallbackSuccess({\n\t\t\t\tresultType: \"continue\"\n\t\t\t});\n\t\t}\n\t} );\n}\n\nreturn {\n\tresultType : \"continue\"\n};","result":""}}]}}
This instructable referred the following.
Original code is written by handa on Qiita in Japan.
http://qiita.com/handa/items/6118a7e5e1bd58d1cc03 (Japanese)
Step 7: Sign Into MESH SDK on MESH App
Revisit the MESH app and sign into the the MESH SDK to access the new custom RICOH THETA tag that you created.
Step 8: Add the New RICOH THETA Tag to the Recipe.
Select the Custom Tag (ROCHO THETA Tag) That You Created
- Tap the "+" icon in the Custom section on the dashboard to add a custom tag.
- Select the RICOH THETA custom tag from the list. (The new tag will be added to the Custom section of the dashboard).
- Drag-and-drop RICOH THETA tag into the recipe on the canvas and connect the Button tag to the RICOH THETA tag and Speaker tag.
Test, run, and enjoy!