Absolute encoder programming

chaymoss

Member
Hello everyone,
Currently, I'm trying to program PICAXE-28X2 BASE SHIELD to detect an angular position of the motor using an absolute encoder, you can find below my program that I used.
Code:
#picaxe 28X2
#terminal 115200
;symbol Miso = pinC.5; define input switch
symbol Sclk = C.0; define output pin
symbol Mosi = C.1; define output pin
symbol CS = C.4; define output pin
symbol Miso = b1;

main:   
high C.0; switch on output SCLK
high C.1; switch on output MOSI
low C.4 ; switch on output CHIP SELECT line low which is the default active state

readadc C.5,b1
sertxd("La position angulaire =",#b1,13,10)
PAUSE 1000

goto main
However the terminal displayed [00] time 78 per second, as you can see in the image down below :

24827

I think the problem is in the code that I'm using, so I need help to display the right angular positions in the terminal.
Thank you in advance.
 

Technoman

Senior Member
Hi,

Your device has a SPI interface, so the readadc instruction is not relevant. See hspisetup, hspiout, hspiin.
 

Aries

New Member
You have set the terminal speed to 115200. However, for sertxd, the terminal speed is effectively determined by the frequency of the Picaxe. For a 28X2, the default speed is 8MHz, with a terminal speed of 9600. At 16MHz, the speed would be 19200 - twice as fast. If you have an external resonator, you could get to 64MHz, with a speed of 76800. That is as fast as you can go with sertxd.

The sequence of nulls is a classic sympton of running the terminal at the wrong speed.

To change the Picaxe speed, use setfreq m16 (etc)
 

chaymoss

Member
Technoman, Aries, and PieM, thank you all for your help.

Well, I'm not really used to picaxe programming, so I need some enlightenment for how to create a new function in Picaxe Software.
Down below you'll find a function that I need to make in picaxe software :

C:
uint8_t spiWriteRead(uint8_t sendByte, uint8_t encoder, uint8_t releaseLine)
{
  //holder for the received over SPI
  uint8_t data;

  //set cs low, cs may already be low but there's no issue calling it again except for extra time
  setCSLine(encoder ,LOW);

  //There is a minimum time requirement after CS goes low before data can be clocked out of the encoder.
  //We will implement that time delay here, however the arduino is not the fastest device so the delay
  //is likely inherantly there already
  delayMicroseconds(3);

  //send the command
  data = SPI.transfer(sendByte);
  delayMicroseconds(3); //There is also a minimum time after clocking that CS should remain asserted before we release it
  setCSLine(encoder, releaseLine); //if releaseLine is high set it high else it stays low

  return data;
So, this function gets the absolute position from the AMT22 encoder using the SPI bus. The AMT22 position includes 2 checkbits to use for position verification. the 12-bit encoder transfer position via two bytes, giving 16-bits regardless of resolution. This function takes the pin number of the desired device as an input. Error values are returned as 0xFFFF. You can find the whole program by clicking here.

The parameters of the function are : sendByte (Unsigned Integers of 8 bits), encoder (Unsigned Integers of 8 bits) and releaseLine (Unsigned Integers of 8 bits)


I looked intensely in the manual 2 of picaxe, and I couldn't find a proper way to define functions that I already create.
GOSUB is a command that is used to call a sub-procedure.
I think I can also define a function by putting the NAME and : , but I don't think that I could define the function's parameters using this method, and to call it later in the program with the defined parameters.

Any advice can help me.
Thank you in advance.
 
Last edited:

inglewoodpete

Senior Member
Technoman, Aries, and PieM, thank you all for your help.

Well, I'm not really used to picaxe programming, so I need some enlightenment for how to create a new function in Picaxe Software.
Down below you'll find a function that I need to make in picaxe software :

<code removed>

So, this function gets the absolute position from the AMT22 encoder using the SPI bus. The AMT22 position includes 2 checkbits to use for position verification. the 12-bit encoder transfer position via two bytes, giving 16-bits regardless of resolution. This function takes the pin number of the desired device as an input. Error values are returned as 0xFFFF. You can find the whole program by clicking here.

The parameters of the function are : sendByte (Unsigned Integers of 8 bits), encoder (Unsigned Integers of 8 bits) and releaseLine (Unsigned Integers of 8 bits)


I looked intensely in the manual 2 of picaxe, and I couldn't find a proper way to define functions that I already create.
GOSUB is a command that is used to call a sub-procedure.
I think I can also define a function by putting the NAME and : , but I don't think that I could define the function's parameters using this method, and to call it later in the program with the defined parameters.

Any advice can help me.
Thank you in advance.
You will find the PICAXE to be light years ahead of a raw PIC (the code you quoted above). There are basically three commands to learn: hi2cSetup, hi2cIn and hi2cOut. Have a read of the Command Manual. Edit: I got my protocols mixed up. Please refer to post #9
 
Last edited:

chaymoss

Member
inglewoodpete thank you for your suggestion.
Reading Using I2C with PICAXE, I need to consider 3 i2c details :
*Slave address
*Address size
*Bus speed
However, I couldn't find Slave address in the sensor's datasheet. I only found the checksum formula, should I use it as a slave address?

24835

Also, to use i2c, I need to change the 6 connected pins of the sensor. You can find, down below, the I/O pin modes defined in my code :
Code:
symbol Miso = pinC.4; define input switch /Set the modes for the SPI IO
symbol Sclk = C.3; define output pin
symbol Mosi = C.5; define output pin
symbol cs = B.7; define output pin
According to 28X2 datasheet, hi2c sda in pin C.4 and hi2c scl in pin C.3, so how can I manage the new pins connection between picaxe base shield and the sensor.

24834
 
Last edited:

inglewoodpete

Senior Member
I had a quick read of the AMT22's data sheet and I can't see any reference to i2c communication. Perhaps that's why we both can't find an i2c address!

My apologies for my previous reply - it was late at night here. I got my wires (protocols?) crossed.

You are correct. SPI needs 4 communication + ground (0v) + device power wires connected.

On the 28X2 shield, 3 or the pins (SDO, SDI & SCK) are locked in, while CS/SS (Chip (slave) Select) can be configured on any output pin.

SDO (MOSI) Master-Out, Slave-In "hspi sdo" Shield pin 11 (S.11)
SDI (MISO) Master-In, Slave Out "hspi sdi", Shield pin 12 (S.12)
SCK SPI (Master) Clock Out "hspi sck", Shield pin 13 (S.13)

Have a read on hSPISetup, hSPIOut and hSPIIn in the command manual.

I have not used the AMT22 device, so can't help much there.
  • The data sheet specifies a 2Mbit/s transfer rate. The 28X2's default clock (processor) speed in 8MHz so, according to the hSPISetup command description, spifast should result in a SPI transfer rate of 2MHz (processor clock freq/4).
  • The PICAXE pin you choose for the chip select (CS/SS) function should be initialised to high before execution of the hSPISetup command. Immediately before using the hSPIOut or hSPIIn command, the CC/SS pin has to be be pulled low to get the AMT22 ready to receive clock pulses (and data if it is a write) and then restored to high when the transfer is complete.
The C code example you posted shows operation in full duplex SPI. The PICAXE can't send and receive data in the same command/transfer. Believe me, I've tried every trick that I know. I hope that the AMT22 chip can be used in half-duplex mode (Ie read or wite).

Sorry about the earlier confusion.
 
Last edited:

AllyCat

Senior Member
Hi,

I concur with post #2 (and now #9) that your chip uses an SPI bus NOT I2C. A problem with SPI is that it is not a single defined standard, you really need to read and understand the data sheet in detail. You may be able to find an appropriate (H)SPIOUT/SETUP mode to drive the chip, but the SHIFTOUT command reference may be a good starting point, including several program examples.

Unfortunately, there's no guarantee that the PICaxe can (easily) drive that chip; I believe there might be issues with the Hardware because it appears to be a Request-Reply protocol and the PICaxe SPI cannot do both at the same time. Also the PICaxe is intrinsically slow, particularly if "Bit Banging" a protocol. However, the X2s can calculate those Checkbits quite easily, for example with w2 = w1 AND $5555 : b0 = NOB w2 : IF bit0 = 0 THEN ok and then again with $AAAA .

Ah, just beaten by Pete.

Cheers, Alan.
 

chaymoss

Member
inglewoodpete, AllyCat, thank you for your answers.
So, I tried this code to send instructions MOSI and receive data MISO, however the terminal doesn't show anything.
You can find the code down below
Code:
#picaxe 28X2
#terminal 115200 ; Serial rates for UART

; * AMT22 Pin Connections
; * Vdd (5V):                Pin  1
; * SPI SCLK:                Pin  2
; * SPI MOSI:                Pin  3
; * GND:                     Pin  4
; * SPI MISO:                Pin  5
; * SPI Chip Select:         Pin  6


symbol Miso = pinC.4; define input switch /Set the modes for the SPI IO
symbol Sclk = C.3; define output pin
symbol Mosi = C.5; define output pin
symbol cs = B.7; define output pin

high B.7 ;Get the CS line high which is the default inactive state
init:    hspisetup spimode11e, spimedium    ; spi mode 1,1 
main:  
    symbol sendByte=b0
    symbol dat_a=b1
   
   
    low B.7
   
    hspiout (b0)
   
    hspiin (b1)
   
    high B.7
       
goto main
24837

When I tried the simulation, the program was stuck in line 29 as shown in the image down below :

24838

I need help please
Thank you in advance.
 
Last edited:

chaymoss

Member
Hemi345, thank you for your response.
Changing the baud rate and using the program down below :
Code:
#picaxe 28X2
#terminal 9600 ; Serial rates for UART

init:

symbol AMT22_NOP      =     0x00; SPI commands
symbol AMT22_RESET       =      0x60
symbol AMT22_ZERO       =       0x70

#define NEWLINE         0x0A; Define special ascii characters
#define TAB             0x09


#define RES12           12; We will use these define macro so we can write code once compatible with 12 or 14 bit encoders
#define RES14           14


symbol FALSE     = 0
symbol TRUE     = 1


symbol Miso = pinC.4; define input switch /Set the modes for the SPI IO
symbol Sclk = C.3; define output pin
symbol Mosi = C.5; define output pin
symbol cs = B.7; define output pin


high B.7 ;Get the CS line high which is the default inactive state
hspisetup spimode11e, spimedium    ; spi mode 1,1

main:  
    symbol dat_a=b0
    symbol encoder=b1
    symbol CurrentPosition=w4
    low cs                ; enable chip select
    pause 5
    hspiin (b0)            ; shift in the data
    pause 5
                    ; disable chip select
    hspiout (b0)
    high cs
    sertxd("La position angulaire =",#b0,13,10)

goto main
I'm still getting nothing from the sensor.
24841

And basically, the encoder has a switch for the program mode and the run mode as shown down below :

24843

So, when I'm programming the picaxe, I switch it to program mode, however when I switch it to run mode and spinning the encoder I get 255 value as shown in the terminal below:

24842

I'm sure that the problem is in the code.
Please, help me to overcome this problem asap.
Thank you in advance.
 
Last edited:

AllyCat

Senior Member
Hi,
Code:
#terminal 115200  ; Serial rates for UART   ****
;.......
main:
    symbol sendByte=b0    ;** This just defines a variable name, it doesn't set any values
    symbol dat_a=b1
      low B.7
    hspiout (b0)
    hspiin (b1)
    high B.7   
goto main
You were unlikely to receive much serial (UART) data at 115200 baud, particularly as your Program was NOT SENDING ANY DATA to the UART (with a SEROUT or SERTXD command). Also you had not set up a value to transmit via the SPI , or do anything with the data (b1) that you might (but probably won't) receive.

This is probably a case where you should NOT (yet) attempt to use the #terminal window but the DEBUG command (note that the "var" is not needed and it does nothing).

In your latest version of the code you appear to be attempting to receive data (HSPIIN) BEFORE transmitting a "Request command" (HSPOUT) which also is sent only AFTER the chip has been Disabled! You probably need to start with some much easier hardware to work with first, than this is.

Cheers, Alan.
 

chaymoss

Member
AllyCat, thank you for your suggetion (I'm wondering what do you mean by easier hardware).

Now, using the same program, when I turn the picaxe board back on after being off, and spinning the encoder, I get some values for a few seconds but then it displays zeros as shown below :

24844

I did try displaying the b0 using debug command, however, I've got nothing.

24845

How should I correct the code to overcome this problem?
Help please.
 

AllyCat

Senior Member
Hi,
(I'm wondering what do you mean by easier hardware).
Anything that you can understand how to use, from its Data Sheet. :)

For a "position encoder", a simple Analogue Potentiometer might be a good place to start to understand how to structure and test a Program. Even this will introduce the issue of working with values larger than one byte. ;)

I did try displaying the b0 using debug command, however, I've got nothing.
Did you replace the SERTXD command(s) with a DEBUG command? Did you look at the DEBUG HOT LINK that I gave you?

I get some values for a few seconds but then it displays zeros . .... How should I correct the code to overcome this problem?
Did the "numbers" bear any resemblance to how/when you turned the encoder? I doubt it, because the encoder doesn't appear to have been configured (with a valid HSPIOUT command) and you're only reading and displaying 8 bits (one byte), whilst it's a 12-14 bits (two bytes = one word) encoder. :(

Cheers, Alan.
 

inglewoodpete

Senior Member
And basically, the encoder has a switch for the program mode and the run mode as shown down below :

View attachment 24843

So, when I'm programming the picaxe, I switch it to program mode, however when I switch it to run mode and spinning the encoder I get 255 value as shown in the terminal below:

I'm sure that the problem is in the code.
Please, help me to overcome this problem asap.
Thank you in advance.
You must first use the PICAXE (or other microcontroller) to program the AMT22. The AMT22 is a "smart" device and must be configured to do what you want it to do. Once that has been done correctly, you can change the switch to "read" mode. This will allow the PICAXE (or other microcontroller) to read the sensor's position data.
 

AllyCat

Senior Member
Hi,
The AMT22 is a "smart" device and must be configured to do what you want it to do.
It appears that the device is normally pre-programmed so only needs to be set to "Program" mode for "configuration and firmware updates using the AMT Viewpoint™ software". Therefore, unless you have that software application (and data to load), then the switch should remain ALWAYS in the RUN position.

Reading the data sheet, it is clear that not only is the transmitted "Data" in the form of two bytes, but the "Request" command is also two bytes, so the Program(s) shown so far cannot be expected to work (except that as the Request command is $00 , $00 , then 16 clock pulses with static data may be sufficient). But we shouldn't need to tell you all this, it's not our job to search for fundamental details of an obscure, specialist component. How do you intend to use such a device anyway?

Cheers, Alan.
 

chaymoss

Member
AllyCat, inglewoodpete
thank you for your advices
Well, now I've got integers varies between 0 and 360°, I did nothing special just switching the program mode while uploading the program and switching it back to run mode, I also put it in the motor shaft for regulating its rotation. You can find down below the terminal display.

24846

However, the problem now is that the display of the values are so slow, you can find down below the code that I'm using to detect the angular position and control the motor.

Code:
#picaxe 28X2
#terminal 9600 ; Serial rates for UART

init:

symbol AMT22_NOP      =     0x00; SPI commands
symbol AMT22_RESET       =      0x60
symbol AMT22_ZERO       =       0x70

#define NEWLINE         0x0A; Define special ascii characters
#define TAB             0x09


#define RES12           12; We will use these define macro so we can write code once compatible with 12 or 14 bit encoders
#define RES14           14


symbol FALSE     = 0
symbol TRUE     = 1


symbol Miso = pinC.4; define input switch /Set the modes for the SPI IO
symbol Sclk = C.3; define output pin
symbol Mosi = C.5; define output pin
symbol cs = C.2; define output pin
 

high C.2 ;Get the CS line high which is the default inactive state

PWMOUT B.5, 199, 399    ; start pwm
high B.2; ENABLE the driver   
high B.0; Direction of the spinning
hspisetup spimode11e, spimedium    ; spi mode 1,1

main:   
    
;===============================Motor===================================================

    pwmduty B.5, 199        ; set pwm duty
    pause 50        ; pause 1 s
    pwmduty B.5,50        ; set pwm duty
    pause 50        ; pause 1 s
    
    
;===============================Absolute Encoder========================================

    symbol dat_a=w0
    symbol encoder=w1
    symbol CurrentPosition=w4
    low cs                ; enable chip select
    pause 5
    hspiin (w0)            ; shift in the data
    pause 5
                    ; disable chip select
    hspiout (w0)
    high cs
    sertxd("La position angulaire =",#w0,13,10)
    

    pause 1000
    
goto main
I tried debug, but it doesn't work.
I think I might need to program the sensor using other microcontroller to set zero SPI, or reset the encoder.

I really need help for accelerating the display.
Thank you in advance.
 

AllyCat

Senior Member
Hi,
Well, now I've got integers varies between 0 and 360°,
NO you have not. You are displaying "random" BYTE values between 0 and 255.

It does appear that the PICaxe SPI command documentation is rather poor (for novices), perhaps because it's in the section named "advanced-IO-interfacing". But the code you have shown cannot possibly convert 14-bit values from the Encoder to 0 - 360 degrees values (or revolutions). BTW are you using a 12-bit or a 14-bit version of the encoder, and single-turn or multi-turn?
Code:
#picaxe 28X2
main:
    pause 50        ; pause 1 s       ***** !
    pwmduty B.5,50        ; set pwm duty
    pause 50        ; pause 1 s       ***** !
; .....
    hspiin (w0)            ; shift in the data   **** Only receives a BYTE value
; ......
goto main
I tried debug, but it doesn't work. *******

I really need help for accelerating the display.
Of course DEBUG will work if you use it correctly (but it will slow down the loop speed) !

One reason for the slow response is the content of your main program loop shown above. Not helped that the comment PAUSE 1 s(econd) is obviously wrong. But the first thing to do is to read some "real" data, it's irrelevant how quickly you can produce "garbage" data. ;)

Cheers, Alan.
 

inglewoodpete

Senior Member
You can speed up the data transfer (It may not have a big impact on getting the overall response). The data sheet says 2Mbits/s and you are using 0.5Mbits/s. Change the hSPISetup command to "SPIFast", as I suggested in post #9.

What happens if you remove all of the Pause commands? Remember, nothing happens inside your circuit during a pause. You just sit and wait for something to happen.
 

Goeytex

Senior Member
@chaymoss

Perhaps you could describe your actual application?

What type of motor ? Brushed? Brushless ? Stepper? Geared Stepper?
How fast will the motor be turning ?
What is the motor attached to ?

Consider that @ 5000 RPM ... one motor shaft revolution takes 12000 microseconds....
So 1 degree of shaft rotation = 12000/ 360 = 33.33 microseconds @ 5000RPM

Depending upon motor speed and what type of motor control you expect, a Picaxe may not be able to process the sensor data fast enough to achieve good motor control.
 
Top