CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

AS5045 Hall Rotary with 18f46k22
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

AS5045 Hall Rotary with 18f46k22
PostPosted: Wed Jul 08, 2020 5:36 am     Reply with quote

Hello everyone.
I plan to make an angle measurement with the As5045 integrated.
In Datasheet, I created a code with the figure on page 15.
But it works very bad. I never see 0 to 360.
sometimes I measure between 150 and 3 degrees, sometimes between 270 and 130.
It is increasing and decreasing quite unstable in change. (No sensitivity)
I wonder what I'm doing wrong

Code:

void readAngle (){

   int1 index[12];
   int1 dummyIndex[6];
   unsigned int16 readValue=0;
   unsigned int16 dummyValue=0;
   unsigned int16 lastValue=0;
   
   output_high(_pinCS);
   output_high(_pinCLK);
   output_low(_pinCs);
   delay_ms(1);
   output_low(_pinCLK);
   
   for(int i =12;i>0;i--)   //12 bits angle value read
   {
      output_high(_pinCLK);
      output_low(_pinCLK);
      index[i-1] =input(_pinDO);

      if(index[i-1]==1)        bit_set(readValue,i-1); //12 bit value write
     
      else if(index[i-1]==0)   bit_clear(readValue,i-1);
   }

   for(int j =6;j>0;j--) //6bit other value read
   {
      output_high(_pinCLK);
      if(j != 1) output_low(_pinCLK);
     
      dummyIndex[j-1] =input(_pinDO);
     if(dummyIndex[j-1]==1)          bit_set(dummyValue,j-1); //6 bit value write     

      else if(dummyIndex[j-1]==0)    bit_clear(dummyValue,j-1);
         
   }
   lastValue=bubble_sort_filter(readValue,20);
   printf("Angle: %f",lastValue*0.08789);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 6:34 am     Reply with quote

This is an SPI interface. You don't need/want to be doing the clocking
yourself, use the #use SPI capability of the compiler. You also don't want to
be pausing for 1mSec after the CS. Have you got the mode pin high or low?.
The mode pin needs to be tied to either Vss or Vdd _before_ the supply is
applied. Pause needs to be 384uSec or 96uSec according to this.
Are you running off 3.3v or 5v?.
If you are running off 3.3v, then both the Vdd3v3 pin and the Vdd5v pin can
be connected to your supply. If you are running off 5v, then only the Vdd5v
pin goes to the supply, and the Vdd3v3 pin must be NC.
What PIC?.

So:
Code:

#use SPI(DI=_pinDO, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045)

   //at boot
   unsigned int32 val;
   float angle;
   output_high(_pinCs);

   //then to read from the chip
   output_low(_pinCs);
   delay_us(384); //change to 96 if mode is high
   val=spi_xfer(AS5045,0,17);
   output_high(_pinCs);

   angle = (val>>5)*0.08789;


The bottom 5 bits of val are the status bits.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 7:05 am     Reply with quote

Datasheet d used ssi interface expression instead of spi interface.
I didn't use the spi, thinking that the two are different from each other.

I connected the mode pin to vss with a resistance of 1k, not directly.
Although Datasheet has no such suggestion, appNote did so.
I remember I couldn't read the value when I connected it directly to vss.

I use with 5v. I use pic18f46k22.
Are you saying SPI and SSI are the same.
If so, can I use spi pins software? I don't want to print(pcb) again
You are very fast thanks


I tried the code. It works decisively.
I wonder why it ranges from 0 to 180.
Why 0 is not 360.
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 9:45 am     Reply with quote

SSI is Synchronous Serial Interface.
SPI is Serial Peripheral Interface.
They are both synhcronous serial interfaces, the only 'difference' is
that SPI is normally bi-directional, whereas SSI is normally only one
direction.
Using the 'software' SPI offered by CCS, the interface supports
unidirectional operation, so SSI as well as SPI.

Now on the 46K22, what CPU clock are you using?.
If you are running at one of the faster clock rates, your sequence of
setting and clearing the clock pin, will actually be happening faster than
the chip supports. This is a big advantage of using the #USE SPI, since
it will ensure the that clock rate does not exceed the maximum baud
specified.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 12:07 pm     Reply with quote

As seen in the code, I use 64mhz with the pll
N

Code:

#include <18F46k22.h>
#device ADC=16
#fuses NOWDT,NOBROWNOUT,PUT,NOWRT,NODEBUG,INTRC_IO, NOMCLR, NOPROTECT, NOWDT, NOLVP,PLLEN                 
#use delay(internal=64000000)
#use  rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,sda=PIN_c4,scl=PIN_c3,slow=400000,FORCE_hw)

#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)

#define _pinCS     pin_D2
#define _pinCLK    pin_D1
#define _pinDO     pin_D0
#define _pinMagIN  pin_D3
#define _pinMagDEC pin_D4
#define _pinPROG   pin_C2

#use SPI(DI=_pinDO, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045)

#include "Oled.c"
#include "As5045.c" 



   
   VOID main()
   {
      setup_oscillator(OSC_64MHZ , OSC_PLL_ON);

     
          //at boot
   unsigned int32 val;
   float angle;

      WHILE (TRUE)
      {


   output_high(_pinCs);

   //then to read from the chip
   output_low(_pinCs);
   delay_us(384); //change to 96 if mode is high
   val=spi_xfer(AS5045,0,17);
   output_high(_pinCs);

   angle = (val>>5)*0.08789; [b] // Angle Value :   0- 180 ???[/b]
}
     
      }
   
   
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 09, 2020 1:06 am     Reply with quote

Hello Ttelmah.
can I ask one more question?
I want to perform the reset according to the diagram shown on page 24.
I guess. I can accomplish this by sending the value of val in your code there.
Can I do this as follows;
Code:

#use SPI(DI=_pinDO, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045)
#use SPI(DI=_pinPROG, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045_PROG)
void only_at_first(){
    //Ttelmah's code
   //at boot
   unsigned int32 val;
   float angle;
   output_high(_pinCs);

   //then to read from the chip
   output_low(_pinCs);
   delay_us(384); //change to 96 if mode is high
   val=spi_xfer(AS5045,0,17);
   output_high(_pinCs);
   val = val >>5;   

   //the part I want to add
    unsigned int16 valProg=0;
    unsigned int8 dummy1=0;
    unsigned int8 dummy2=0;

    dummy1=make8(val,0);
    dummy2=make8(val,1);
    valProg  =make16(dummy2,dummy1);

    valprog  = valprog << 3;

    bit_Set(valProg,15); //because  counter clockwise
    bit_Set(valProg,2);   // pwm disable
   //***************
    output_low(_pinPROG);
    //the prog pin should be stepped to 7.5 volts for programming
    // I use pnp transistor, so prog Pinlow
   //***************
   output_low(_pinCs);
   output_high(_pinCs);

   delay_us(384);         //slow mode

   spi_xfer(AS5045_PROG, valProg, 16);

   output_low(_pinCs);

   output_low(_pinPROG);
   //When the programming was over, I made it passive again. I'm not sure about that
}




Prog pin is not directly connected, it is connected with pnp.
So should I apply a NOT to valProg value?


Last edited by ressas on Thu Jul 09, 2020 1:41 am; edited 3 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 09, 2020 1:15 am     Reply with quote

ressas wrote:

I connected the mode pin to vss with a resistance of 1k, not directly.

If the Mode pin is connected to Gnd, the power-up delay is 80ms.
This is listed on page 8 of the AS5045 data sheet.
You need to add a delay of 100ms (for safety margin) at the start of main().
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 09, 2020 8:19 am     Reply with quote

Thank you pcm programmer.
Can I get answers to the questions I asked above?
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Thu Jul 09, 2020 9:53 am     Reply with quote

All you need to do to reset the chip, is drop the prog line, and send
one clock bit. So:

spi_xfer(AS5045_PROG, 0, 1);

However though this is listed as the way to reset the chip after alignment
mode, after _programming_, it says a power on reset is _required_.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 3:13 am     Reply with quote

Thankyou Ttelmah. Very Happy
I am trying to add a transistor to the circuit for a hardware PUT.
But I could not understand why I read a value between 0-180, not 0-360. When the value I read multiplies by 2, the result improves. However, my sensitivity is reduced. How can I fix this?
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 4:48 am     Reply with quote

It's curious that you're getting 1/2 of what you want and that says '/2' to me..hmm 180 is 1/2 of 360, hmm >>6 not >>5 error ?? so I downloaded the datasheet.
The data from the device is consists of 12 bit position and 6 'status' bits, yet you only receive 17 bits and then >>5 which should be correct.
A simple test would be to read and display the raw data as position(0-4096) and then the 5 bits( as '1s and 0s' BEORE you compute the position in * (degrees). If you slowly move the magnet you should see the data increment.
As there are 6 status bit, I'd actually read all 18 bits(12+6) then process the data.
I quickly read the datasheet, but they do talk about the magnet placement being 'critical' though I suspect a software bug not hardware.

just something to try, it might help.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 5:55 am     Reply with quote

Actually I think it is just the way the sensor is done. Try switching to reading
18 bits not 17. If you look at figure 13, for the 17 bits of data, they send
18 clocks. The chip ignores the first clock. So though it is 17bit data, you
actually have to send 18 clocks. Only sending 17 clocks the result will be that
the value is shifted right by one bit.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 6:53 am     Reply with quote

Thankyou masters
This code was created with the help of Ttelmah pcm Programmer and temtronic.
Code:


#include <18F46k22.h>
#device ADC=16
#fuses NOWDT,NOBROWNOUT,PUT,NOWRT,NODEBUG,INTRC_IO, NOMCLR, NOPROTECT, NOWDT, NOLVP,PLLEN                 
                 
#use delay(internal=64000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,sda=PIN_c4,scl=PIN_c3,slow=400000,FORCE_hw)

#define _pinCS     pin_D2
#define _pinCLK    pin_D1
#define _pinDO     pin_D0
#define _pinMagIN  pin_D3
#define _pinMagDEC pin_D4
#define _pinPROG   pin_C2

#use SPI(DI=_pinDO, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045)

//#use SPI(DI=_pinPROG, CLK=_pinCLK, baud=1000000, bits=32, MODE=2, stream=AS5045_PROG)

     unsigned int32 val=0;
     float angle=0;
     float angle2=0;
     float zeroPoint = 0;
     Void as5045_read();

     float temp=0;
     float index1[10];
     float bubble_sort_filter_float(float data,unsigned int8 number);

   VOID main()
   { 
   
      setup_oscillator(OSC_64MHZ , OSC_PLL_ON);
      delay_ms(100);
     
    WHILE (TRUE)
      {
         as5045_read();

      }

    }
float bubble_sort_filter_float(float data,unsigned int8 number)


     
    //1.Filtre
     index1[0]=data;
     for(int a=9;a>0;a--)
     {
     index1[a]=index1[a-1];
     }
     
     for (int b=1; b<10; b++)
     {
        for(int c=0; c<9; c++)
        {
            if (index1[c] > index1[c+1])
            {
                temp = index1 [c];
                index1 [c] = index1 [c+1];
                index1 [c+1] = temp;
     }  }   }
            return index1[5];
}


Void as5045_read(){ 
     
   //at boot
   
   output_high(_pinCs);
   output_low(_pinCs);
   
   delay_us(384);
   val=spi_xfer(AS5045,0,18);

   output_high(_pinCs);
   
   angle = (val>>5)*0.08789;
   angle2=bubble_sort_filter_float(angle,10);
   zeroPoint= (angle2 - 144.22);  //software RST
   // 144.22 my zeropoint
   // I cant use prog pin RESET
   //spi_xfer(AS5045_PROG, 0, 1);
   printf("%f",zeroPoint)   
   
}   


While using it, I may have broken a couple of my AS5045 integrated.
Interestingly, although I could not read data from the digital part, I was able to read from the analog part (if the data was not correct).

Secondly, I did not use the pnp transistor correctly with the pic. Therefore, I could not reset with progpini. As on page 25, the PNP transistor is connected directly to the MCU. In real applications, resistance connection should be done, right?
I guess it would be more comfortable if it was programmed with 5V instead of 7.5V.
Finally, I have to check the feed of the integrated supply transistor for Power on reset. Hopefully it doesn't have to be a pnp transistor.
Thanka again and again.


Last edited by ressas on Fri Jul 10, 2020 11:39 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 7:46 am     Reply with quote

I would wonder about the warnings on page 22 about the programming
line and the capacitors needed on it.

Really there are two ways to work:
1) Never actually 'program' the chip. Instead use the option on Page 24
for what they call 'non permanent programming' (which is really just
'configuration', rather than programming, which can be done without the
need for the high voltage on the Prog pin). This to me looks the safer
way to work, unless you very carefully make a programming board that
has all the capacitors etc. Beware also that you need to be able to
deliver a lot of current on the 'programming' supply (150mA). If this
droops during 'programming' it's a fairly sure way of corrupting the chip.
2) Design a programmer, and program the chips once.

I suspect it'd be much safer and easier to just go with option 1, and
have your code 'configure' the chip to the required settings at boot, and
never actually 'program' it.
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 10, 2020 7:55 am     Reply with quote

Before you do any 'fancy math', you should just read the sensor and display the data. The 'low level' proceedure will confirm/deny that the sensor data is proper.
Have a simple 'read sensor- display data-delay 1 second-loop again' program.
Without turning magnet the reading should be stable, close to 000 for position.
Turn the magnet 90* CW. Now the reading should be close to 1024 and stable.
Turn to 180* CW, should be 2048 more or less, but stable(within 2-5 counts ??)
Turn to 270*CW, reading is 3072, +- and stable
Turn to almost 359* CW, reading should be 4000+-, and stable.

These few steps need to be done BEFORE doing any math calculations. This way you KNOW the sensor is functioning properly AND your 'driver code' ( basic access) to the sensor IS working as desired.
Once you do this THEN do the 'math'. If the math results are wrong, then there's something wrong with the math calculations.


Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group