Issue in m touche capacitive sensing module of PIC - pic

I am trying to build simple capacitance measurement circuit using m-touch PIC16F707 micro controller.
I have initialized the CPS registers & DAC registers (for internal voltage reference) with below values.
Now the real issue is i am changing the capacitance but the CPS output (i.e. SR latch) digital signal output frequency is constant
could anybody help me whats the potential reason why output digital signal frequency is not getting changed with varying
capacitance?
note: initialized DACCON1 to 21 as internal reference voltage to comparator 1 non inverting input using internal DAC.
As per PIC user guide for m touche maintaining 2/3rd //Vdd (3.3v) FVR to comparator 1 non inverting input using internal DAC
Appreciate the kind help in advance!!
void init_CPSA(char CSchannel)
{
CPSAON=1;
CPSARM=1;
CPSARNG0=1;
CPSARNG1=1;
if(CSchannel<16)
CPSACON1=CSchannel;
else
CPSACON1=0;
}
void DAC_init()
{
DACEN=1;
DACLPS=1;
DACOE=1;
DACPSS1=1;
DACPSS0=0;
DACCON1=21;
}

Related

Esp32 Micropython Max31865 Spi connection and data read

I need to read temperature data with using MAX31865 SPI communication. First of all, I tried to read 4 byte data:
import machine
import ubinascii
spi = machine.SPI(1, baudrate=5000000, polarity=0, phase=0)
#baudrate controls the speed of the clock line in hertz.
#polarity controls the polarity of the clock line, i.e. if it's idle at a low or high level.
#phase controls the phase of the clock line, i.e. when data is read and written during a clock cycle
cs = machine.Pin(15, machine.Pin.OUT)
cs.off()
cs.on()
data = spi.read(4)
cs.off()
print(ubinascii.hexlify(data))
I tried many times with different codes but result is always similar b'00000000'.
I am using ESP32 WROOM.
I used this pins:
ESP32 : D12 - D14 - 3V3 - GND - D15
Max31865: SDO - CLK - VIN - GND - CS
I am new on micropython and esp32.
I don't know what should I do. Is there any suggestions , recommended tutorials or idea?
Short answer: see if you can use CircuitPython and its drivers for MAX31865.
Long answer: a bunch of stuff. I suspect you've been following the Adafruit tutorial for MAX31855, but its SPI interface is very different from the MAX31865.
Your SPI connection is missing the SDI pin. You have to connect it, as communication is bidirectional. Also, I suggest using the default SPI pinout on ESP32 side as described in the micropython documetation for ESP32.
The SPI startup looks to be missing stuff. Looking at the SPI documentation a call to machine.SPI() requires that you assign values to arguments sck, mosi, miso. Those would probably be the pins on ESP32 side where you've connected SCLK, SDI, SDO on MAX31865 (note mosi means "master out, slave in" and miso is "master in, slave out").
The chip select signal on the MAX is inverted (that's what the line above CS input in the datasheet means). You have to set it low to activate the chip and high to disable it.
You can't just read data out of the chip, it has a protocol you must follow. First you have to request a temperature-to-resistance conversion from the chip. The datasheet for your chip explains how to do that, the relevant info starts on page 13 (it's a bit difficult to read for a beginner, but try anyway as it's the authoritative source of information for this chip). On a high level, it works like this:
Write to Configuration register a value which initiates the conversion.
Wait for the conversion to complete.
Read from the RTD (Resistance-To-Digital) registers to get the conversion result.
Calculate the temperature value from the conversion result.
The code might be closer to this (not tested, and very likely to not work off the bat - but it should convey the idea):
import ubinascii, time
from machine import Pin, SPI
cs = Pin(15, Pin.OUT)
# Assuming you've rewired according to default SPI pinout
spi = machine.SPI(1, baudrate=100000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
# Enable chip
cs.off()
# Prime a 1-shot read by writing 0x40 to Configration register 0x00
spi.write(b'\x00\x40')
# Wait for conversion to complete (up to 66 ms)
time.sleep_ms(100)
# Select the RTD MSBs register (0x01) and read 1 byte from it
spi.write(b'\x01')
msb = spi.read(1)
# Select the RTD LSBs register (0x02) and read 1 byte from it
spi.write(b'\x02')
lsb = spi.read(1)
# Disable chip
cs.on()
# Join the 2 bytes
result = msb * 256 + lsb
print(ubinascii.hexlify(result))
Convert result to temperature according to section "Converting RTD Data Register
Values to Temperature" in datasheet.
Side note 1: here spi = machine.SPI(1, baudrate=5000000, polarity=0, phase=0) you've configured a baud rate of 5MHz which is the maximum for this chip. Depending on how you've connected your devices, it may not work. The SPI protocol is synchronous and driven by master device, so you can set any baud rate you want. Start with a much, much lower value, maybe 100KHz or so. Increase this after you've figured out how to talk to the chip.
Side note 2: if you want your conversion result faster than the 100ms sleep in my code, connect the DRDY line from MAX to ESP32 and wait for it to go low. This means the conversion is finished and you can read out the result immediately.

How to drive the DDS Compiler IP core from Xilinx

I completed Anton Potočniks' introductory guide to the red pitaya board and I am now able to send commands from the linux machine running on the SoC to its FPGA logic.
I would like to further modify the project so that I can control the phase of the signal that is being transmitted via the red pitayas' DAC. Some pins (from 7 down to 1) of the first GPIO port were still unused so I started setting them from within the OS and used the red pitaya's LEDs to confirm that they were being set without interfering with the functionality of Anton Potočnik's "high bandwidth averager".
I then set the DDS_compilers' to Phase Offset Programmability to "streaming" mode so that it can be configured on the fly using the bits that are currently controling the red pitaya's LEDs. I used some slices to connect my signals to the AXI4-Stream Constant IP core, which in turn drives the DDS compiler.
Unfortunately the DAC is just giving me a constant output of 500 mV.
I created a new project with a testbench for the DDS compiler, because synthesis takes a long time and doesn't give me much insight into what is happening.
Unfortunately all the output signals of the DDS compiler are undefined.
My question:
What am I doing wrong and how can I proceed to control DACs' phase?
EDIT1; here is my test bench
The IP core is configured as follows, so many of the control signals that I provided should not be required:
EDIT2; I changed declarations of the form m_axis_data_tready => '0' to m_axis_phase_tready => m_axis_phase_tready_signal. I also took a look at the wrapper file called dds_compiler_0.vhd and saw that it treats both m_axis_phase_tready and m_axis_data_tready as inputs.
My simulation results remained unchanged...
My new test bench can be found here.
EDIT3: Vivado was just giving me the old simulation results - creating a new testbench, deleting the file under <project_name>.sim/sim_1/behav/xsim/simulate.log and restarting vivado solved this problem.
I noticed that the wrapper file (dds_compiler_0.vhd) only has five ports:
aclk (in)
s_axis_phase_tvalid (in)
s_axis_phase_tdata (in)
m_axis_data_tvalid (out)
and m_axis_data_tdata (out)
So I removed all the unnecessary control signals and got a new simulation result, but I am still not recieving any useful output from the dds_compiler:
The corresponding testbench can be found here.
I also don't get any valid output when I include the control signals.
The corresponding testbench can be found here.
Looks like m_axis_data_tready is not connected. No data will come out unless that's asserted.

Specman E error: Argument to change|fall|rise has to be (short) scalar

I have an existing verification environment with simple ports of length LEN.
In addition, there are events,that occur when only one of the relevant port's bits rises:
// Port declaration:
port_a : inout simple_port of uint(bits:LEN) is instance;
port_b : inout simple_port of uint(bits:LEN) is instance;
...
// Events that use the ports for 1 monitor:
event event_a is rise (smp.port_a$[idx:idx])#clock;
event event_b is rise (smp.port_b$[idx:idx])#clock;
*** There are many monitors that every one has its own idx, event_a and event_b.
The problem is that I need to change LEN define to 64, and all events are now fail since Specman cannot define an event on bus of 64 bits (even though the events are actually "look" only on 1 bit..)
Do you have any idea how to workaround the issue? Thank you for any help.
Actually, this form of defining an event is not supported:
event event_a is rise (smp.port_a$[idx:idx])#clock;
as bit slice in not supported inside a rise Temporal expression. (it is also documented in the
‘Event’ chapter in the ‘e language referene’.
In a case where you are interested in only one bit of this 64 bit signal you can instead define this port as simple_port of bit
And put the bit slice in the hdl_path as follows:
idx:uint(bits:6);
keep idx==34; // the specific bit to this monitor.
port_a : in simple_port of bit is instance;
keep port_a.hdl_path()==read_only(append("signal_name[",idx,":",idx,"]"));
then define the event as :
event event_a is rise(port_a$)#sim;

QuartusII Synthesis: Enumerated type to State signals (encoding)

I am designing an FSM in SystemVerilog for synthesis through the QuartusII (14.1) tool to put on an Altera FPGA. I am using an enum declaration to make the code much more reasonable:
typedef enum logic [7:0] { CMD_INIT,
CMD_WAIT,
CMD_DECODE,
CMD_ILLEGAL,
CMD_CMD0,
... } cmd_st;
...
cmd_st cs, ncs;
...
Whenever Quartus synthesized this state machine, it seems to create a one-hot encoding despite the logic [7:0] part of the type. As in, when I got to add the states to SignalTap, I get all of the states as a signal 1-bit variable (cs.CMD_INIT, cs.CMD_WAIT, etc). While this is usually pretty useful, as I need to see a bunch of these states and some over values at once, I am running out of on-chip memory to contain all of these states (there are well over 8 of them; like 50+). So adding all of them to SignalTap takes ALOT of this memory; but if I could just put down the 8-bit value for cs, I would have plenty of space for other things.
I cant figure out how to get Quartus to NOT use the 1-hot encoding for the FSM. I have tried changing the settings (Settings->Compiler Settings->Advance Settings (Synthesis...)->State Machine Processing) to Minial Bits, User Encoding and Sequential, as well as added values for a few of the states:
typedef enum logic [7:0] { CMD_INIT = 8'd0,
CMD_WAIT = 8'd1,
CMD_DECODE = 8'd2,
CMD_ILLEGAL = 8'd3,
CMD_CMD0,
(Note, not all of them as there are a bunch of I might add even more in the middle)
Im not sure what else to do so that SignalTap sees only 8-bits for the states (which probably goes back to getting Quartus to synthesize this FSM as sequential rather than 1hot encoding)
You can use synthesis pragmas to guide Quartus to use a specific encoding scheme for the state variables. This page gives you details on how to encode state machines using "sequential" encoding thereby avoiding the default one-hot encoding.

CAN Bus Protocol Implementation

I want to learn and implement CAN BUS protocol. I have implemented UART,SPI,I2C and One Wire Bus protocol using MSP430 Launchpad in software. Now I want to learn about CAN Bus protocol. I have mBed LPC 1768 Cortex M3 Development board. mBed has Can Bus Library but I want to write my own library so that I can learn it in detail, i.e. the way I did for other communication protocols.
I am not able to find suitable resources to start with and the material appears to be scattered on net. Can any one guide how do i write and implement CAN Bus protocol with the development boards available with me.
Thanks
Developing CAN library is relatively easy as compared to I2C or SPI. This is because CAN Controller of your Cortex will take care of most of complex things.
To transmit the data, You have to write ID and Data in designated registers and set bit to transmit data.
This Application note from NXP can be very useful for you.
I would recommend you to implement following functions:
InitCAN - This should set specified Baud Rate of CAN.
SetFilters - Most CAN Controllers come with Acceptance Filters, So it's good to have that
SendData - Make sure you accept Parameters like ID_Type and RTRs etc.
RecieveData - This can be blocking or Interrupt based.
Before beginning, do read CAN Basics to understand. Application notes AN713 and AN754 from Microchip is a good source. Also Vector's site and Wikipedia Article.
Plus, You can always post your doubts here or on Electronics.StackExchange.com :)
Okay so this post is quite old but people may look at it again so:
First of all Can bus is not user friendly protocol like USART or IC2 at all so you have to be very precise about your can bit timing there are tools for that but I suggest you to calculate them by hand. For a microcontroller I would suggest STM32 and be away from PIC series in my opinion. If it's only CAN-BUS without higher level protocols such as SAE J1939, steps are pretty simple and straight forward:
1)Initialize Can
2)Put CAN to configuration mode and remember that you can set baudrate, mask and filters only in configuration mode!
3) Set the baud rate registers.
4) Set the mask and filters. If you need to receive all messages just simply set mask to 0x00. Then filter will be do not care.
5) Set the CAN to the normal or loopback mode. (loopback mode is used for debugging purposes mostly.)
Some remarkable points people try to implement can at the beginning may miss:
*** You need at least 2 working CAN nodes for successfull transmission. (of course with matching baud rate). So if you want to send some data via CAN with 1 node it will not be succesfull. Because your transmitter node will not receive ACK.
*** Most likely you will need a CAN tranciever. Do not forget to put a 100 ohm or similar value resistor between Tx and Rx pins of your tranciever.
I used the software canking to talk to a mcp25050 when I learned how to implement can protocol using an hcs12 dragonboard. It helped a lot because canking will initialize everything for you when u go on the bus and all you have to do is learn how to write and recieve. If you want to learn how to initialize the steps are:
Enables can bus by setting bit on CAN Control Register 1
Enable can initialization Control Register 0
wait until can bus is in initialization mode by checking control register 1 bit
Enables can bus by setting bit on CAN Control Register 1 again and set clock source - Ethier bus clock or eclock
set prescaler baudrate and Tq with Bus timing register
set sample time and prop_seg1, prop_seg2, and phase_seg
set acceptance id on Identifier acceptance register 0-3 or 0-7 - to set your can to recieve everything set those to 00 because when doing a compare the can bus does a ones complement compare with the id coming in
set Identifier mask register 0-3 or 0-7, if you want to not care about any of the bits set them all to FF
set identifier acceptance control register to 32 bit extended or 11 bit - i use 32
set Control Register 0 back to normal mode
wait until bus is normal mode by checking Control Register 1
after this you can start changing registers or reading data to do this you must select the empty can buffer, write your id to write or request data, and then input the address, mask, and value in the 3 transmitter registers if writing and then specify the dlc (3 if writing and 8-1 if reading). to transmit the id and data you then have to set the can transmit flag to equal the can Transmit buffer selection.
** depending on what id you use bit shifting can be tedious so if you are having a problem I would suggest debugging and looking at what your Transmit buffer selection registers are holding. I had this error because i did not shift correctly when i was sending messages to the mcp25050
If your MCU supports CAN Bus, you should start from the related datasheet.

Resources