{"id":2895,"date":"2020-09-07T15:45:39","date_gmt":"2020-09-07T13:45:39","guid":{"rendered":"https:\/\/noscollections.ddns.net\/carrerago\/?p=2895"},"modified":"2020-09-07T15:45:39","modified_gmt":"2020-09-07T13:45:39","slug":"controler-sa-voiture-go-par-une-page-web","status":"publish","type":"post","link":"https:\/\/www.carrera-fun.com\/?p=2895","title":{"rendered":"Contr\u00f4ler sa voiture GO par une page web"},"content":{"rendered":"\n<p>Dans l&rsquo;article <a href=\"https:\/\/www.carrera-fun.com\/?p=2879\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.carrera-fun.com\/?p=2879<\/a> nous avons vu comment contr\u00f4ler une voiture \u00e0 partir d&rsquo;un mini ordinateur. Nous allons maintenant voir comment contr\u00f4ler la voiture \u00e0 partir d&rsquo;une page Internet.<\/p>\n\n\n\n<p>Ce n&rsquo;est pas vraiment tr\u00e8s difficile, il suffit d&rsquo;ajouter la fonction de serveur Web au script Python qui g\u00e8re d\u00e9j\u00e0 le pilotage de la Voiture.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"808\" height=\"291\" src=\"https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/webslot_04.png\" alt=\"\" class=\"wp-image-2901\" srcset=\"https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/webslot_04.png 808w, https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/webslot_04-300x108.png 300w, https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/webslot_04-768x277.png 768w, https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/webslot_04-600x216.png 600w\" sizes=\"auto, (max-width: 808px) 100vw, 808px\" \/><\/figure>\n\n\n\n<p>Une seul page web suffit pour contr\u00f4ler une voiture.  Il suffit d&rsquo;avoir une barre de s\u00e9lection avec un curseur. J&rsquo;ai trouv\u00e9 un script id\u00e9al sur ce site :   <a rel=\"noreferrer noopener\" href=\"https:\/\/www.w3schools.com\/howto\/howto_js_rangeslider.asp\" target=\"_blank\">https:\/\/www.w3schools.com\/howto\/howto_js_rangeslider.asp<\/a> . J&rsquo;ai adapt\u00e9 l&rsquo;image du curseur en mettant l&rsquo;image d&rsquo;une manette,c&rsquo;est plus sympa dans notre cas.<\/p>\n\n\n\n<p>Ci-dessous le code html.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;html>\n&lt;head>\n&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n&lt;style>\n.slidecontainer {\n  width: 100%;\n}\n\n.slider {\n  -webkit-appearance: none;\n  width: 100%;\n  height: 10px;\n  border-radius: 5px;\n  background: #d3d3d3;\n  outline: none;\n  opacity: 0.7;\n  -webkit-transition: .2s;\n  transition: opacity .2s;\n}\n\n.slider:hover {\n  opacity: 1;\n}\n\n.slider::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  appearance: none;\n  width: 23px;\n  height: 57px;\n  border: 0;\n  background: url('images\/manet_2.png');\n  cursor: pointer;\n}\n\n.slider::-moz-range-thumb {\n  width: 23px;\n  height: 57px;\n  border: 0;\n  background: url('manet_2.png');\n  cursor: pointer;\n}\n&lt;\/style>\n&lt;\/head>\n&lt;body>\n&lt;h1>Voiture 1 Controle&lt;\/h1>\n&lt;p>D\u00e9placer le curceur pour accelerer.&lt;\/p>\n&lt;div class=\"slidecontainer\">\n  &lt;input type=\"range\" min=\"0\" max=\"50\" value=\"0\" step=\"5\" class=\"slider\" id=\"myRange\">\n  &lt;p>Value: &lt;span id=\"demo\">&lt;\/span>&lt;\/p>\n&lt;\/div>\n\n&lt;script>\nvar slider = document.getElementById(\"myRange\");\nvar output = document.getElementById(\"demo\");\noutput.innerHTML = slider.value;\n\n         function flag(couleur){\n            var data_file = \"order\/?flag=\"+couleur;\n            var http_request = new XMLHttpRequest();\n            try{\n               http_request = new XMLHttpRequest();\n            }catch (e){\n               try{\n                  http_request = new ActiveXObject(\"Msxml2.XMLHTTP\");\t\t\n               }catch (e) {\t\n                  try{\n                     http_request = new ActiveXObject(\"Microsoft.XMLHTTP\");\n                  }catch (e){\n                     alert(\"Your browser broke!\");\n                     return false;\n                  }\t\t\t\n               }\n            }\t\t\n            http_request.onreadystatechange = function(){\n               if (http_request.readyState == 4  ){\n                  var jsonObj = JSON.parse(http_request.responseText);\n\t\t\t\t  var mavar=jsonObj.data_updated ;\n\t\t\t\t  mavar=mavar;\n                  document.getElementById(\"data\").innerHTML = mavar;\n\t\t\t\t\tif ( mavar==\"O\"){\n\t\t\t\t\t\tloadJSON_2();\n\t\t\t\t\t}\n               }\n            }\t\t\n            http_request.open(\"GET\", data_file, true);\n            http_request.send();\n\t\t }\nslider.oninput = function() {\n  output.innerHTML = this.value;\n  flag(this.value);\n}\n&lt;\/script>\n\n&lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p>Quelques infos :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;input type=\"range\" min=\"0\" max=\"50\" value=\"0\" step=\"5\" class=\"slider\" id=\"myRange\"><\/code><\/pre>\n\n\n\n<p>Min et max sont les valeurs min et max de la barre donc <strong>min <\/strong>doit toujours \u00eatre \u00e0 z\u00e9ro sinon vous pourrez pas vous arr\u00eater. <strong>Max <\/strong>peut \u00eatre mis \u00e0 100 pour aller au maximum de la puissance de la voiture, dans mon cas j&rsquo;ai brid\u00e9 la puissance \u00e0 50% . <strong>Step <\/strong>est la finesse de r\u00e9glage de la puissance. Le plus fin \u00e9tant 1.<\/p>\n\n\n\n<p>A chaque changement de valeur de la barre, le script envoie la nouvelle valeur \u00e0 cette adresse : order\/?flag=valeur<\/p>\n\n\n\n<p>Cot\u00e9 serveur sur le Raspberry Pi voici le script python.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python\nimport RPi.GPIO as GPIO\nimport time , datetime , json \n\nfrom bottle import route, run, template, static_file, request, post , get\nimport threading\n\nfrom math import *\n\nfrom tkinter import *\nfrom tkinter.messagebox import *\nfrom tkinter import ttk\nimport tkinter as tk\n#import bme280\n\nGPIO.setwarnings(False)\n\n@route('\/')\ndef index():\n    return template('www\/index.html')\n\n@route('\/index.html')\ndef index():\n    return template('www\/index.html')\n\n@route('\/player_1c.html')\ndef index():\n    return template('www\/player_1c.html')\n\n@route('\/order\/')\ndef index3():\n    global auto_order\n    global race_flag\n    flag=request.query.flag\n\n    if (flag!=\"\"):\n        \n        y=int(flag)\n        pwm1.ChangeDutyCycle(y)\n        valpwm.set(str(y))\n    \n    #data_update()\n    data_out=\"O\"\n    return data_out\n\n@route('\/images\/&lt;images>')\ndef server_static(images):\n    return static_file(images, root='www\/images')\n\ndef serveurweb():\n    run(host='0.0.0.0', port=8080)\n\nthreading.Thread(target=serveurweb).start()\n\nGPIO.setmode(GPIO.BOARD)\n# pin GPIO\npiste_1_pin_pwm = 37  # PIN 37\n\nGPIO.setup(piste_1_pin_pwm, GPIO.OUT)  # pin configur\u00e9e en sortie\npwm1 = GPIO.PWM(piste_1_pin_pwm, 50)  # pwm \u00e0 une fr\u00e9quence de 50 Hz\nrapport = 0       # rapport cyclique initial de 0%\npwm1.start(rapport) \n\ndef change_power(f):\n    #y=int(echelle.get())\n    y=int(f)\n    pwm1.ChangeDutyCycle(y)\n    valpwm.set(str(y))\n    #print (f)\n    \ndef bt_stop():\n    #remise a zero des relev\u00e9s\n    \n    pwm1.ChangeDutyCycle(0)\n\n## Interface Graphique\n## -------------------\nfenetre = Tk()\n# a parametrer dans .ini\nmenu_width=300\n\nfenetre.minsize(width=400, height=400)\nfenetre.maxsize(width=400, height=400)\nfenetre.wm_title(\"Web Speed - Serveur \")\n\n####\np = PanedWindow(fenetre, orient=HORIZONTAL)\np.pack(side=TOP, expand=Y, fill=BOTH, pady=2, padx=2)\n\nFrame1 = Frame(p, borderwidth=2, relief=GROOVE,width=300)\nFrame1.pack(side=LEFT, padx=2, pady=2)\n\nFrame_tortue = Frame(p, borderwidth=2, relief=GROOVE,width=650)\nFrame_tortue.pack(side=LEFT, padx=2, pady=2)\n\np.add(Frame1)\np.pack()\n\nnb = ttk.Notebook(Frame1)\n# adding Frames as pages for the ttk.Notebook \n# 1er onglet\n\nonglet1 = ttk.Frame(nb)\nnb.add(onglet1, text='Commandes')\n\nnb.pack(expand=1, fill=\"both\")\n\nlignes_droites = LabelFrame(onglet1, text=\"Control\", padx=2, pady=2,height=30)\nlignes_droites.pack(fill=\"both\", expand=\"yes\")\npa = PanedWindow(lignes_droites, orient=HORIZONTAL)\npa.pack(side=TOP, expand=Y, fill=BOTH, pady=1, padx=1)\npa.add(Button(fenetre, text=\"Stop\", wraplength=menu_width ,command=bt_stop))\n\nlignes_droites = LabelFrame(onglet1, text=\"Vitesse\", padx=2, pady=2,height=30)\nlignes_droites.pack(fill=\"both\", expand=\"yes\")\npa = PanedWindow(lignes_droites, orient=HORIZONTAL)\npa.pack(side=TOP, expand=Y, fill=BOTH, pady=1, padx=1)\n\nechelle=Scale(onglet1, orient='horizontal', from_=0, to=40,\n      resolution=1, tickinterval=20, length=350,\n      label='Voiture 1', command=change_power)\npa.add(echelle)\n\nfenetre.mainloop()\n<\/code><\/pre>\n\n\n\n<p>J&rsquo;ai gard\u00e9 une petite interface graphique pour que cot\u00e9 serveur (sur l&rsquo;\u00e9cran du Raspberry Pi on puisse contr\u00f4ler la voiture et l\u2019arr\u00eater en cas d&rsquo;urgence.<\/p>\n\n\n\n<p>Quelques infos sur le script :<\/p>\n\n\n\n<p>Lorsque l&rsquo;on re\u00e7oit une requ\u00eate dans le \u00ab\u00a0r\u00e9pertoire\u00a0\u00bb order, on v\u00e9rifie si il y a une variable et on l&rsquo;interpr\u00e8te pour r\u00e9cup\u00e9rer la valeur et l&rsquo;appliquer \u00e0 la puissance moteur le pwm.<\/p>\n\n\n\n<p>T\u00e9l\u00e9chargement du script python et ses \u00e9l\u00e9ments (html, images,&#8230;) :<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/pwm_web.zip\">pwm_web<\/a><a href=\"https:\/\/www.carrera-fun.com\/wp-content\/uploads\/2020\/08\/pwm_web.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p>Notez l&rsquo;adresse IP de votre Raspberry Pi pour saisir la saisir dans votre navigateur Internet. On utilise pas le port standard pour \u00e9viter tout conflit si votre Raspberry h\u00e9berge d\u00e9j\u00e0 un serveur web (dans notre script on utilise le port 8080).<\/p>\n\n\n\n<p>Adresse : http:\/\/IP_du_PI:8080\/player_1c.html<\/p>\n\n\n\n<p>Si vous souhaitez pouvoir contr\u00f4ler la voiture a partir d&rsquo;un appareil qui est ext\u00e9rieur \u00e0 votre r\u00e9seau (internet), il faut param\u00e9trer votre box pour laisser passer le trafic et le diriger vers le Raspberry.  Pour cela regarder les param\u00e8tres NAT de votre box.<\/p>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Piste Carrera GO pilot\u00e9 par une page web\" width=\"1110\" height=\"624\" src=\"https:\/\/www.youtube.com\/embed\/9jBSYeiE10Q?list=PL-Z-OdqEAzKf6E9WYQruGF_pEa0S1GIb1\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>La vid\u00e9o montre le contr\u00f4le de la voiture \u00e0 partir d&rsquo;un t\u00e9l\u00e9phone sur le r\u00e9seau 4G donc ext\u00e9rieur au r\u00e9seau. La voiture est brid\u00e9e \u00e0 50% afin d&rsquo;\u00e9viter les sorties de piste lors de la d\u00e9mo vid\u00e9o.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans l&rsquo;article https:\/\/www.carrera-fun.com\/?p=2879 nous avons vu comment contr\u00f4ler une voiture \u00e0 partir d&rsquo;un mini ordinateur. Nous allons maintenant voir comment contr\u00f4ler la voiture \u00e0 partir d&rsquo;une page Internet. Ce n&rsquo;est&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","footnotes":""},"categories":[17,18,46,55],"tags":[],"class_list":["post-2895","post","type-post","status-publish","format-standard","hentry","category-application","category-articles","category-tag_go","category-theme_alimentation"],"_links":{"self":[{"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=\/wp\/v2\/posts\/2895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2895"}],"version-history":[{"count":0,"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=\/wp\/v2\/posts\/2895\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.carrera-fun.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}