I have a project where, unfortunately, I cannot use directly the Arduino's SPI library, since the library's data structure must be in byte size.
In my case, I need to generate, at a given time t, a 4MHz, 50% duty-cycle PWM with exactly 22 pulses. The first 5 pulses need to be empty before acquiring the 2 bytes of data from the chip. This sums up to 21 pulses of PWM (see the image below). Note that the command is 00000 for reading since we can also program the chip. The full documentation of the chip can be found here: AS5134_Datasheet_v2-3[1].pdf (futureelectronics.com)
I was thinking of using ISR to count the number of clock pulses and stop the PWM generation after reaching a certain number of clock pulses. But it seems that my code does not work properly (I get only 15 pulses) and I do not get the exact number of pulses I want from the controller.
My question is the following. Once I reach x number of pulses, how can I stop immediately the PWM generation? Below is the code I am currently using in my project.
this looks like synchronous (i.e. with a clock) data transmission, not PWM
if the SPI feature of the Arduino doesn't work for you, can you bit bang 2 digital pins to achieve what you want?
select 2 digital I/O pins: one as clock the other as data.
start by configuring the data pin as an OUTPUT set to zero
toggle the clock pin first HIGH then LOW 5 times with a reasonable delay between each toggle
then configure the data pin as an INPUT (possibly INPUT_PULLUP)
again start toggling the clock pin first HIGH then LOW for the # of bits to read, reading the data pin after making the clock LOW and shifting that bit into some variable
there's not need for an interrupt i you control the clock pin
Yes. In between each byte of message, there is a pulse of delay, which does not fit my requirements. The packets are separated by one pulse; I have verified it through an oscilloscope.
However, if you look carefully at the figure in my question, you will see that I need a 22-bit continuous transmitted message, which is not a multiple of 8. So I cannot use SPI library. I think I should set things up manually.
Manually toggling the pins is a possibility, but I am not sure we can have a very fast sampling with this method. I need to produce a quite high frequency clock (4MHz), which must be quite precise according to the datasheet.
I have not yet implemented your idea, but how would you implement a clock whose frequency is close to the Arduino's internal clock frequency of 16MHz? I don't think delay() is appropriate in this case.
i don't believe there is a minimum clock frequency and i don't believe the clock needs to be symmetric.
there's probably a usec delay between just setting a bit HIGH and then LOW. there's a longer delay to read bits after setting the clock LOW. this can't possibly be close to the process clock speed
Post the full data sheet for this chip.
If it SPI, it is important to know which SPI mode. From the picture, it looks like SPI mode 0, however, the CS (enable) line appears to be inverted.
I agree with @gcjr that there is no lower bus speed to be observed and bit banging (manipulating the clock and data pins) will work. With Mode 0, you set the data pin as required for the bit you are transmitting then pulse the clock from low to high then to low and repeat with the next bit to be sent.
I guess it would work with the standard SPI library, If you need only 22 bits, you have to send 2 dummy bits at the beginning of an 3 byte transmission.
Edit.
There is an example of bit-banging a 40 bit SPI data stream to a shift register (chain) in reply #6 in the link below. It is a bit obscure because he is using direct port manipulation but this could be replaced by digitalWrite(). using an HV5812 with arduino - Page 1
I think the data are sent on the falling edge of the clock, so it's SPI_mode1, not sure though.
Got it. Bit banging seems to be the preferred solution, not using directly the internal clock of the Arduino.
The problem is the following. Sending the 5-bit message 00000 will activate the chip to send the 16-bit data right after. If we generate 3 dummy bits before sending the actual 5-bit command from the controller, we will send the 8-bit message "00000000". However, after 5 pulses, the controller will send already the data. So, we will have something like the image below.
I have the impression that everything will be somehow shifted. This delay will be propagated and will be difficult to be handled. This is why I prefer to generate manually every single clock pulse so that we are perfectly control data flow.
Device DS was added to the opening post. There is no minimum for clock speed in 3 wire configuration and 100kHz in 2 wire. So the whole post is pointless.
I don't understand "So if you can tell us without then having to kill us, please do."
We want to measure the rotor speed at 150,000 rpm, which is 2500 rps. We need a resolution of 1000 for each revolution, so it means that we have to sample the system at minimum 2.5 MHz. Having a clock speed at 4MHz without too much delay is required in our project.
You will have very little time left for processing the aquaired data. If I were trying this I would send the preamble in assembly and use HW SPI for the two data bytes. This will take like 50% of CPU time. Will the other 50% suffice for everything else? What do you plan to do with all the data?