Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6996859
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T20:12:39+00:00 2026-05-27T20:12:39+00:00

I have an Arduino w/ GPS chip, processing NMEA strings w/ python. I have

  • 0

I have an Arduino w/ GPS chip, processing NMEA strings w/ python. I have a HTML file that I open and have auto refresh every x-seconds s.t. the marker updates, but I’d really like to be able to update the position information without doing a refresh. I know it can be done w/ drag and drop as demoed here: http://gmaps-samples-v3.googlecode.com/svn/trunk/draggable-markers/draggable-markers.html but I need to know how to replace that drag event and instead interface w/ python pushing out new coordinates. I need a way of getting my new coordinate information into the web page. Any help/suggestions would be greatly appreciated. The only class really applicable to this problem is the GoogleMap one. I’m not familiar w/ much web stuff, so the simpler the better.

what i have:

python -> opens webpage w/ autoreload
python -> writs over map.html plugging in new coords
map.html refreshes and picks up and displays new position

what i want:

python -> new position {{ }} marker moves to new coords

import  re
import  sys
import  copy
import  time
import  threading
import  Queue
import  serial
import  webbrowser
import  traceback
import  random
import  math
import  turtle
from    pprint         import pprint
from    collections    import OrderedDict

class MockIo(object):

    def __init__(self):
        pass

    def read(self,buff):
        lat = str(random.random())[2:6]
        lon = str(random.random())[2:6]
        return "$GPGGA,172307.000,3913.%s,N,07716.%s,W,2,10,0.8,199.9,M,-33.4,M,3.8,0000*46\r\n" % (lat,lon)

    def write(self,buff):
        pass

class GPSTurtle(object):

    def __init__(self, new_x = 0, new_y = 0):
        self.t = turtle.Turtle()
        self.x_coord = new_x
        self.y_coord = new_y

        self.diff_x  = 0
        self.diff_y  = 0
        self.heading = 0
        self.origin_x = 0
        self.origin_y = 0

    def initialize_origin(self, new_x, new_y):
        self.origin_x = self.origin_x - new_x
        self.origin_y = self.origin_y - new_y

    def __update_pos(self, new_x, new_y):
        new_x       += self.origin_x
        new_y       += self.origin_y
        new_x *= 20
        new_y *= 20
        self.diff_x  = new_x - self.x_coord
        self.diff_y  = new_y - self.y_coord
        if 0 == self.diff_x:
            if self.diff_y > 0:
                self.heading = 90
            elif self.diff_y < 0:
                self.heading = 270
        elif 0 == self.diff_y:
            if self.diff_x > 0:
                self.heading = 0
            elif self.diff_x < 0:
                self.heading = 180
        else:
            self.heading = math.degrees(math.atan(float(self.diff_y)/float(self.diff_x)))
            if self.diff_x < 0:
                self.heading += 180
            elif self.diff_y < 0:
                self.heading += 360

        self.set_pos(new_x, new_y)
        print self.diff_x,self.diff_y,self.heading,self.x_coord,self.y_coord

    def set_pos(self, new_x, new_y):
        self.x_coord = new_x
        self.y_coord = new_y

    def __draw(self):
        self.t.setheading(self.heading)
        self.t.pendown()
        self.t.goto(self.x_coord, self.y_coord)
        self.t.penup()

    def ungps(self, new_x, new_y):
        new_x = int(1000.0 * new_x)
        new_y = int(1000.0 * new_y)
        return (new_x, new_y)

    def update_and_draw(self, new_x, new_y):
        self.__update_pos(new_x, new_y)
        self.__draw()




class GPS(threading.Thread):

    def __init__(self, comport = 'COM15', baud = 4800):
        super(GPS, self).__init__()
        self.GOOD       = True
        self.gpgga_keys =   [
                                'message_id',
                                'utc_time',
                                'lattitude',
                                'n_s_ind',
                                'longitude',
                                'e_w_ind',
                                'pos_fix_ind',
                                'satellites',
                                'hdop',
                                'msl_altitude',
                                'units_1',
                                'geoid_sep',
                                'units_2',
                                # 'age_of_diff_corr', gps does not have this field by default
                                'diff_ref_station_id',
                                'checksum',
                            ]
        self.PSRF103    =   {
                                'name':'$PSRF103',
                                'msg':{'GGA':'00','GLL':'01','GSA':'02','GSV':'03','RMC':'04','VTG':'05'},
                                'mode':{'SetRate':'00','Query':'01'},
                                'rate':{'off':'00','min':'01','max':'255'},
                                'cksumEnable':{'disable':'00','enable':'01'},
                            }
        self.gps_msg_q  = Queue.Queue()
        self.gps_buff   = ""
        try:
            self.gps_com    = serial.Serial(   
                                                comport, 
                                                baud, 
                                                timeout = 1,
                                                parity  = serial.PARITY_NONE,
                                                rtscts  = 0,
                                                xonxoff = 0
                                            )
        except serial.serialutil.SerialException:
            print "Could not open com port, assuming simulation mode and setting"
            print "com object to MockIo"
            self.gps_com = MockIo()

    def enable_all(self):
        m  = self.PSRF103
        for msg in m['msg'].values():
            st = ','.join([m['name'],msg,m['mode']['Query'],m['rate']['on'],m['cksumEnable']['enable']])
            st = self.append_crc(st)
            self.send_msg(st)
        self.gps_com.read(4028)

    def disable_all(self):
        m  = self.PSRF103
        for msg in m['msg'].values():
            st = ','.join([m['name'],msg,m['mode']['Query'],m['rate']['off'],m['cksumEnable']['enable']])
            st = self.append_crc(st)
            self.send_msg(st)
        self.gps_com.read(4028)

    def append_crc(self,st):
        match     = re.compile("\$(.*)")
        crc        = 0

        if match.search(st):
            st = match.search(st).group(1)

        for letter in st:
            crc = crc ^ ord(letter)
        return "$%s*%0.2x\r\n" % (st,crc)

    def run(self):
        self.disable_all()
        while self.GOOD:
            self.send_GPGGA_req()
            time.sleep(2)

    def send_GPGGA_req(self):
        m  = self.PSRF103
        st = ','.join([m['name'],m['msg']['GGA'],m['mode']['Query'],m['rate']['off'],m['cksumEnable']['enable']])
        st = self.append_crc(st)
        self.send_msg(st)

    def parse_msg(self,st):
        '''
            SAMPLE GPGGA MSG
            "$GPGGA,172307.000,3913.7428,N,07716.7474,W,2,10,0.8,199.9,M,-33.4,M,3.8,0000*46\r\n"
        '''
        retVal = (False,None)
        st     = st.rstrip('\r\n')
        parse  = st.split(',')
        if st.startswith('$GPGGA') and len(self.gpgga_keys) == len(parse):
            retVal = (True, OrderedDict(zip(self.gpgga_keys,parse)))
        else:
            pass

        return retVal

    def send_msg(self, st):
        self.gps_com.write(st)
        self.gps_buff = ''.join([self.gps_buff,self.gps_com.read(1024)])
        buffsplit     = re.compile(r'.*?\r\n|.+')
        splt          = buffsplit.findall(self.gps_buff)
        if 0 < len(splt):
            if splt[-1].endswith('\r\n'):
                self.add_list_to_q(splt)
                self.gps_buff = ""
            else:
                self.add_list_to_q(splt[:-1])
                self.gps_buff = splt[-1]

    def add_list_to_q(self,list_):
        for item in list_:
            self.gps_msg_q.put(item,False)

    def get_item_from_q(self, block = True, timeout = 10):
        return self.gps_msg_q.get(block, timeout)

    def convert_lat_lon(self, lat, lon,ns,ew):
        lat = "%f" % (float(lat[:-7]) + (float(lat[-7:])/60.0))
        lon = "%f" % (float(lon[:-7]) + (float(lon[-7:])/60.0))
        if 'S' == ns:
            lat = str(float(lat) * -1.0)
        if 'W' == ew:
            lon = str(float(lon) * -1.0)
        return (lat,lon)




class GoogleMap(object):

    def __init__(self, path = 'map.html'):
        self.path = path
        self.map_html = '''
                            <!DOCTYPE html>
                            <html>
                            <head>
                            <meta http-equiv="refresh" content="5" /> 
                            <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
                            <style type="text/css">
                              html { height: 100% }   body { height: 100%; margin: 0px; padding: 0px }   #map_canvas { height: 100% } </style>
                            <script type="text/javascript"
                                   src="http://maps.google.com/maps/api/js?sensor=true">
                            </script>
                            <script type="text/javascript">
                               function initialize() {
                                   var lat = %s
                                   var lng = %s
                                   var latlng = new google.maps.LatLng(lat,lng);
                                   var myOptions = {
                                       zoom: 13,
                                       center: latlng,
                                       mapTypeId: google.maps.MapTypeId.ROADMAP
                                   };
                                   var map    = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
                                   var marker = new google.maps.Marker({position: latlng, map: map, title: %s });
                               }
                            </script>
                            </head>
                            <body onload="initialize()">
                              <div id="map_canvas" style="width:100%; height:100%"></div>
                            </body>
                            </html>
                        '''

    def write_map(self,lat = '39.229013',long = '-77.445735',marker = '""'):
        new_map_html = self.map_html % ( str(lat), str(long), str(marker).replace('"','') )
        with open(self.path, 'w') as f:
            f.write(new_map_html)

    def launch_browser(self):
        webbrowser.open_new_tab(self.path)



if __name__ == "__main__":
    map = GoogleMap('map.html')
    map.write_map()
    map.launch_browser()

    gps = GPS('COM15',4800)
    gps.start()

    t = GPSTurtle()
    first_update = True

    try:
        while True:
            try:
                st = gps.get_item_from_q(True,2)
                success,gpgga = gps.parse_msg(st)
                if success:
                    lat, lon = gps.convert_lat_lon( gpgga['lattitude'],
                                                    gpgga['longitude'],
                                                    gpgga['n_s_ind'],
                                                    gpgga['e_w_ind'])
                    la,ln = t.ungps(float(lat),float(lon))
                    if first_update:
                        t.initialize_origin(la,ln)
                        first_update = False
                    else:
                        t.update_and_draw(la,ln)

                    map.write_map(lat,lon,'ME!')
                    time.sleep(5)
            except Queue.Empty:
                # pass
                print "Q-Empty"
    except:
        gps.GOOD = False
        gps.join()
        print "\n\nEXITING PROGRAM\n\n"
        traceback.print_exc(file=sys.stdout)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T20:12:40+00:00Added an answer on May 27, 2026 at 8:12 pm

    Instead of doing refreshes, you could setup ajax short polling – essentially have your page check with an end point that returns the position of the marker every few seconds. Here’s a post talking about it and linking to a tutorial: Real-time data on webpage with jQuery

    Another alternative would be to setup a long poll – have the page keep an open connection with your server waiting for an update. The big up side is that your UI will get updated as soon as there is a change in coordinates. The big downside is that this puts a sizable load on your server, requiring it to keep the open connection. Scaling long polling is harder.

    This post summarizes both options well: Short-polling vs Long-polling for real time web applications?

    EDIT:

    Here’s a fairly crude example, but it should give you a simple framework to update the lat long continuously. Apologize in advance, since my experience is limited without using a webserver, I used the simplest one to setup that I can think of – google app engine SDK. It comes with a dev server that is super easy to install and run. Here’s the link to the SDK: http://code.google.com/appengine/downloads.html

    main.py:

    #!/usr/bin/env python
    
    import os
    
    from google.appengine.ext import webapp
    from google.appengine.ext.webapp import util
    from google.appengine.ext.webapp import template
    
    def doRender(handler, page, templatevalues=None):
        path = os.path.join(os.path.dirname(__file__), page)
        handler.response.out.write(template.render(path, templatevalues))
    
    class MainHandler(webapp.RequestHandler):
        def get(self):
            doRender(self, 'template/main.html')
    
    
    class AjaxHandler(webapp.RequestHandler):
        def get(self):
            self.response.out.write('{ "lat": "1", "long": "1"}')
    
    def main():
        application = webapp.WSGIApplication([('/', MainHandler),
                                              ('/data.js', AjaxHandler)],
                                             debug=True)
        util.run_wsgi_app(application)
    
    
    if __name__ == '__main__':
        main()
    

    app.yaml:

    application: ajaxtest
    version: 1
    runtime: python
    api_version: 1
    
    handlers:
    - url: /favicon\.ico
      static_files: favicon.ico
      upload: favicon\.ico
    
    - url: .*
      script: main.py
    

    main.html (put this in folder “template” under root folder of the project):

    <html>
    <head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    
    </head>
    <body>
    <button>Get JSON data</button>
    <div></div>
    <script type="text/javascript">
    var test = 1;
    
    function update(){
        $.getJSON("/data.js",function(data){
    
        var items = [];
          $.each(data, function(key, val){
            $("div").append(key + ":" + val + " ");
          });
        });
        }
    
    var t=setInterval("update()",1000);
    
    </script>
    </body>
    </html>
    

    For your purposes, modify the AjaxHandler to re-query the GPS coordinates. Also modify the $(“div”).append(key + “:” + val + ” “); to send an update to google maps for the coordinates of the marker.

    Let me know if this doesn’t help or if you have no luck with twisted. I’m off work today, so should be able to dedicate much more time. Good luck!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a Python script that writes data packets to an Arduino board through
I have an Arduino sending and receiving instructions with a Python script via a
I have the following code on my Arduino that constantly checks for a serial
I have few projects ideas that involve plugging a computer or an arduino to
I have a simple Arduino sketch that spans several files. There is a function
I have a Arduino app that needs to talk to my PC across the
I am fetching data from the following database: I have arduino-box that send that
I have an Arduino sketch that takes a timet and when that timet is
I have an Arduino sketch that takes a timet and when that timet is
I have some code I have in the Arduino environment that requires x (in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.