LIN Protocol Transceiver Behaviour during the GotoSleep Command - microcontroller

I am using LIN Protocol for Parking Brake functionality. baud rate : 10.4Kbps
1) I am sending the go to sleep command in $3C frame, after 50ms sending 0v to NSLP to put LIN Transceiver into sleep Mode but it is taking 9s for
INHIBIT pin to go low from the trigger of $3C Frame. My understanding is once the NSLP goes to Zero, immediately INH Should go to low.
1) Is this the correct behaviour?
2) if some presses the Button (LIN Slave) during the 9s how the behaviour will be ?
3) Will LIN Slave send the wakeup pattern?
4) how INH pin will behave since it is already high?

When you are speaking about LIN transciever chip, you must specify its partnumber.
For example, I suggest that you are using NXP's TJA1020 http://www.nxp.com/documents/data_sheet/TJA1020.pdf
It have INH output pin with two states: active high, when chip in non-sleep mode, and high-impedance (Z-state), when chip in sleep mode.
Also, I suggest that there is no load on INH pin.
So, when you turn on sleep mode, INH discarged only through your multimeter (scope?), and it takes few seconds.

Related

how to use esp32 ulp interrupt pulse counter and periodic wake up deepsleep mode

I am trying to measure power usage using dds353 kWh meter. This meter has a pulse output. I am interested in using the esp32 since I can periodically send the data over the internet to nodered dashboard.I am also very interested in using the esp32 in low power mode and periodically wake up to send data over mqtt. I have tried out examples from github using espressif idf but I would not mind an arduino equivalent. I would like to do hardware interrupt which when one of the rtc gpio pin goes high a counter is incremented while a seperate timer interrupt run and occasionally wakes up the main xtensia cores which fetches data from the rtc and sends it over. I have looked at the pulse counter examples and with my limited knowledge can not tell if the interrupts are triggered when the ulp is in sleep mode or only when it is on. I would really be glad if someone would show me how to basically use the ulp for counting pulses even when it is sleep mode and periodically wake up the main cores. I am ok with IDF or arduino examples
If you want to count pulses while in deep sleep youuse the ULP. Code on the ULP continues to execute when the board wakes up and goes to normal power mode. So when it is awake, it will still run the counter on the ULP processor unless you stop the ULP periodic wake up timer, ULP will keep waking up and running while the main CPU is active.
As you gave already checked with this example , it should be pretty close to what you need. The only difference seems to be that the example is set to wake up after a given number of pulses, rather than a fixed amount of time. However it should be easy to change that, by enabling deep sleep wake up from timer.For the Arduino you could check Some additional info:
ULP doesn't have GPIO interrupts. So you use deep sleep wake stub (small piece of code which runs immediately after deep sleep, prior to loading application from flash into RAM) you can increment the pulse counter variable, and go to sleep again. This way you can get low power consumption (~5uA) between pulses and moderate power consumption while running the wake stub (around 13mA), for a very short time.
So its up to you to experiment with your specific scenario.
You can use Pulse Counter(PCNT) feature in ESP32 to count the number of pulse in background, Understanding by using same you can able to do some periodic wake-up and read the count.. Its also possible to configure event when number of counts reached certain threshold and had lot of options,
For get information and available Interfaces and API's for Pulse Counter(PCNT) please follow below link, https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html
Initially I faced lot of issue to make Pulse Counter(PCNT) work in Adrino IDE for ESP-32, After multiple attempt I make it working, And same sample code is uploaded in GitHub for reference. I have not use all the API's in the official documentation but but used few of them and are working..
I have created sample program for a water flow meter, there also we use to get pulse which needs to count to measure the water flow rate, understanding simile to kWh meter.
GitHub Sample code Path:- https://github.com/Embedded-Linux-Developement/Arduino_Sample_Programs/tree/main/ESP_32/Water_Flow_Pulse_counter_WithOut_Interrupt_Using_PCNT
I have not placing the code here, because its there in GitHub and not directly for the asked question, but simile one and can use it. Its a working code I tested in HW.
Hopes Its helpful,
Regards, Jerry James

SAM4S - Is DMA determinist in time ?

I'm using the DMA (described as PDC in the datasheet) of SAM4SD16C with USART 0 peripheral.
I've set a timer which generates a interrupt each ms. Each 5 ms a data transfert should be performed via DMA.
An other interrupt should occur when TXEMPTY flag is set.
To see when the transmission starts and ends I toggle an Ouptut and watch it on oscilloscope. And then I realized that the end of reception is varying in time by 20 µs (my main clock is 120MHz)... Which in my project is not acceptable. Meanwhile, the start of transmission is 100ns precise, so there is no problem concerning this point.
I'm wondering if there is a way to have a better control on DMA time transfer.
As discussed in comments above, the imprecision of End Of Reception instant is due to baudrate value. This imprecision is around the baudrate period and probably an additional bus idle time.

Use RF Receiver without transmitting all the time from RF Transmitter

I've been reading the input of this RF Receiver by connecting it's DATA pin to an Analog Pin from my Arduino and sending it to the Serial Monitor. If I don't transmit absolutely anything, it reads some noisy input. I already checked that the Analog Pin doesn't introduce any noise by placing a 10K resistor between it and ground. BUT when I do transmit, let's say, a constant ON-OFF pulse train with a delay of 100ms, It reads just as if there was no noise. If I look closely at the Serial Monitor I could notice that none of the zeros got disturbed at all, it's just plain zeroes and 700 (approx). So my conclusion is that the RF Receiver goes crazy if it doesn't detect anything. I've read that you are supposed to transmit some pulse train ALL the time, even if you don't want to transmit anything in particular in order to keep the Receiver at peace, and for it to not mess with your important data. My question is, is there any way to bypass this? The RF Transmitter side is going to be powered by battery, and I suppose that this constant pulse train would drain it pretty quickly. Thank you in advance.
That is normal, the receiver outputs noise.
Those very cheap RF transmitters and receivers have no chip on the RF board that takes care of the protocol (how the radio signal is modulated and how the data is translated to RF data). The Arduino has to do everything, the timing, the protocol, the detection of data, everything.
The transmitter can be turned on and off. That's why it is called ASK modulation (on and off).
The receiver has an automatic gain and receives everything. When nothing is transmitted the receiver increases the gain until it receives a lot of noise. When a digital input is used with an interrupt it could be thousand(s) interrupts per second of useless noise.
To make those work, you need a library that does the transmitting and receiving, including a protocol for the transmitted data. The best library is the VirtualWire/RadioHead. I suggest to use the RadioHead in RH_ASK mode. There are "ask" examples that show how to use the library.
The VirtualWire/RadioHead is really good in detecting a packet of data between the noise.
If you don't want to sacrifice your Arduino for the RF protocol, then you can buy transceiver modules. They have a chip on the RF board that takes care of transmitting and receiving.

Analog digital conversion with AD7091 on SPI

I am trying to use AD7091R-8 ADC chip with SPI.
Procedure for getting converted value is described inside Datasheet and says:
Reset chip
Bring CONVST line low for 600ns and then get it high.
For enabled channels inside Channels register (I have enabled last 3 chans) start clocking out data which is contained in 2 bytes.
So I bring CONVST line for 1ms then up and wait for 1 ms and start clocking out data by enabling CS then clocking 16bytes and then bring CS up.
In those 16bits that clocks out I should get inside first 3 bit channel id and I got it but only the first one. Other 2 frames are without channel id which gives assumption that something got bad.
Does chip after starting CONVST and clocking out data autoincrements ADC results or somehow ADC channel result should be addresed?
Could someone please give hint on how should data be retrived from this ADC after doing CONVST?
If you look at the diagram on page 36 of the datasheet (Channel sequencer), you will find your answer.
You need to do the following sequence:
Toggle CONVST
Tie CS low, write the channel register on SDI, ignore SDO, Tie CS high
Then for each channel that you want to read:
Toggle CONVST
Tie CS low, read operation of NOP regiter on SDI, next channel on SDO, Tie CS high

Interrupt works too fast on the Arduino

I know this sounds a bit funny :). But I am trying to eliminate possibilities:
On the Arduino Uno I have attached an interrupt triggered on HIGH to a routine which only increments a volatile defined long counter. This counter is displayed on an LCD screen.
If I connect a pulse generator with a frequency of 1 Hz at TTL levels, I would expect the counter to increase with about 1 per second. However this is not the case.
As the frequency is 1 Hz (duty cycle 50%) could it be possible that once the counter is incremented the IRS is exited (and clears the interrupt flag) BUT: the INT0 level is still HIGH so the ISR would be called again? At 1 Hz 50% duty, the HIGH would stay for 500 ms and at 16 mHz...
The processor at the heart of any Arduino has two different kinds of interrupts: “external”, and “pin change”. There are only two external interrupt pins on the ATmega168/328 (ie, in the Arduino Uno/Nano/Duemilanove), INT0 and INT1, and they are mapped to Arduino pins 2 and 3. These interrupts can be set to trigger on RISING or FALLING signal edges, or on low level. The triggers are interpreted by hardware, and the interrupt is very fast. The Arduino Mega has a few more external interrupt pins available.
So as commented: It triggers on an edge!
See more details on the Arduino Playground web page.
Two electrical reasons can explain why interrupt does not function as you need.
1- The pulse generator output and MCU input can have an impedance mismatch, which can cause ringing on the waveform edges. For example, if your function generator has a 50 ohm output capable of generating high frequencies you might see a problem driving a high impedance input like the Arduino at low frequency.
The name "pulse generator" makes me think this is a 50 ohm out device intended to make very short pulses with sharp edges. In such a case, you add a terminating resistor at the destination (load) to match the impedance of the source (pulse generator). For a 50 ohm output, 47 ohm would be close enough. If the output is 100 kohm, then place a matching resistor at the Arduino.
2- Just the opposite, the generator waveform edges may be so slow that the voltage passes through TTL 0 to 1 transition multiple times. If you have noise on your signal input, a slow edge could be causing multiple triggers. For example, if you are picking up some 60 Hz ripple from a power supply and grounding issues, your square wave edges won't be as square as you think.
In such cases hysteresis is a solution. There are many ways to de-glitch (debounce) in code. There is no answer that is right for all problems. A simple example would be that the ISR you require that the input reads high twice in a row for the edge to be accepted.

Resources