Shop OBEX P1 Docs P2 Docs Learn Events
Beaten by the encoders — Parallax Forums

Beaten by the encoders

Hello

I started this project by connecting 2 linear encoders and downloaded 'quadrature encoder' from obex and everything work a treat first time.
I then created some spin to capture a position from each encoder at regular intervals, every 0.4mm. I store these in two sets of longs and once recording has ended it is written to a USB stick in a VDrive2. Getting all this to work was pretty tricky for a novice but it worked until I required a reference mark and needed to reverse the direction of one axis. The axis used to trigger the data capture. I got the reference marker working fine and reversed the direction of travel, all the results are negative but thats fine.

when I check the data the count for the reversed axis is not zeroing correctly, the first trigger should be at -4000 counts but data recorded is starting around -255000, resolution is 0.0001mm so its 25.5mm. I doubt that is relevant as sometimes it starts around -140000.

Really would appreciate some help with this.

Andy

Comments

  • T ChapT Chap Posts: 4,223
    edited 2015-10-05 22:29
    The encoder zero's on cog launch. Wherever the encoder(s) is when you launch, that is zero for all encoders. You should display the count of 0 position on launching so you know where you just started from. If you need to re-zero later but don't want to lose other programs running, you will have to stop the cog and restart it. Flip the encoder inputs to reverse the count direction.
  • Hello T Chap

    This morning I seem to have much bigger issues, I have stripped my capture loop down to very little as it did not seem to be waiting for the if statement at all.
    repeat until sample >= 800_000
          if counters[0] >= sample
            sample := sample + 4_000
            com6.str(delimiter)
            com6.dec(sample)
    

    variable sample is not changing in this loop, when I move the encoder and counters[0] is greater than sample my debug output shows a stream of 4000,4000,4000,4000 etc. If I pull the encoder back the loop stops.

    I changed the variable name from trigger to sample to see if it made a difference, that's how lost I am :(

    Andy
  • I just tried this
    sample := 4_000
        com6.dec(sample)
        sample := sample + 4_000
        com6.dec(sample)
        
    
    
        repeat until sample >= 800_000
          if counters[0] >= sample
            sample := sample + 4_000
            com6.str(delimiter)
            com6.dec(sample)
    

    now the output is

    40008000,4000,4000,4000,4000 etc

    confused me even more now...
  • Why not start with the simple stuff first, then move to more complex. Start with a repeat loop and a wait built in the loop with waitcnt(8_000_000 + cnt). Display the current encoder count. Move the encoder and you should see change. Once you can get that to work, then proceed. This is very simple stuff using the encoder. Launch the encoder, read the count and display it. You didn't post the updated code so it makes no sense to speculate on your code.
  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-10-06 13:55
    Use => instead of >=.

    x >= y does the same thing as x := x > y, in the same way that x += y does the same thing as x := x + y. The greater than or equal to operator in Spin is =>, and the less than or equal to operator is =<.
  • Thanks Electrodude I did have that wrong although I only wanted greater than to ensure it didn't miss any captures but it never did, runs so nice I get less than 20 microns of lag.

    TChap, that's exactly what I did, I started again with just the encoders counting. This is where I started originally and started building from there.

    This time everything worked just fine until writing the data to usb, this time instead of getting the delimiter written to usb it is writing the filename instead.

    4002test.csv-89
    8006test.csv-117
    1005test.csv-469 etc.

    I think the problem lies with the fact I'm running 'FullDuplexSerial' for human interfacing and the 'USBDrive' object is also running 'FullDuplexSerial' to write to the USB. Today I am going to take the elements of 'USBDrive' I am using and transplant them into my code so I can run two instances of 'FullDuplexSerial' and be in control of them.

    Cheers
    Andy
  • fader700fader700 Posts: 9
    edited 2015-10-07 11:07
    Ok changed things around a bit and now everything is working OK. Takes more than 5 minutes to write 1500 sets of coordinates but will live with that.

    What troubles me about the problems I have had is that I have not understood why, I have just found solutions. This means I learn nothing from my mistakes! Sometimes a change somewhere in the code can affect areas seemingly unconnected, I am taking this as an indicator that my code is not very robust.


    Thanks for your input.
    Andy
  • It is a good idea to put comments in your code for two reasons. 1. In the future when you look back at your code it helps remember what you were doing including your thought processes on how and why you were doing things. 2. It helps a reader on the forum take a quick glance and possibly spot issues without having to fully study the code. Most people are going to take a quick glance. If there are no comments, the reader will need to spend far more time trying to understand what is going on. As for speed, you can easily run the vdrive at 3x the speed you are at which looks like 9600. Depending on the cables you may get much faster than that. Study your code and see if there are delays that are slowing down the writes, for example are you displaying to the terminal information at the same time as writing to USB. There is a 4 port Full Duplex object, maybe several of them. This allows you to use one cog and get 4 serial ports. Assign one port to the vdrive, one to your serial terminal. When code seems to mysteriously get fixed, then there must have been a real cause and effect. If you have comments, you can also make notes of what result a certain line of code is producing. When you make changes to track down a problem, simply comment out a line, replace it with the tweaked line and put comments about a new result if there is one. As it is, you are trying to rely too much on memory. The more code you add, the more you are trying to maintain the entire code in a holographic image in the mind. If you review your code and add notes, it will likely reveal reasons why old code did not work correctly.
Sign In or Register to comment.