I am trying to know the status of MCP3424, either it is connected or not to the master STM32 with defined address 0x68. The ADC module gets connected with the Arduino in same address but using STM32, I am not able to get connected with the following code:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if((HAL_I2C_IsDeviceReady(&hi2c1, 0x68 << 1, 100, 1000))==HAL_OK){
HAL_UART_Transmit(&huart2, "device connected\r\n", 10, 10);
}
else{
HAL_UART_Transmit(&huart2, "no device\r\n", 100, 10);
}
}
Is there any mistake that I have done in this code by chance or any other way there is to deal with MCP3424 ADC module specifically? Please suggest me.
I believe your problem lies with voltage levels: your STM32 functions with 3.3V, while MCP3424 is powered from 5V. Let's open the datasheet of the MCP3424, page 6:
High level input voltage is 0.7Vdd, which is 0.7V*5V=3.5V, which means your A/D can't detect "1" on the line. It sees the line as always "0", even when STM32 MCU outputs HIGH (3.3V).
Possible solutions:
Logic level conversion (various ways). A circuit between A/D IC and MCU to convert 3.3V levels into 5V levels. There are dedicated chips for that, there are also other approaches using resistors and mosfets. Something you may want to explore on electrical engineering stackexchange.
Check the datasheet of the MCU, find GPIO properties. It's very likely those I2C pins are in fact 5V-tolerant, meaning you can pull up I2C lines to 5V and still drive them with 3.3V STM32, and it will be within the spec of STM32 MCU. If that's the case, no extra circuit will be necessary.
Related
I have interfaced I2S mic (ICS-43434) with STM32f401RET6 board.
I have wired it correctly, now just trying to test the mic by passing the data through UART to my pc. Hoping someone can point me in the correct direction.
I have tried passing straight to the UART transmit. However I think I may need some datahandling - I am receiving from the UART, but sometimes just 0 or other times just gibberish which is not from the Mic as it still transmits even when i disconnect the mic.
I2S mic is receiving data in 24 bits in 32 bit frame, the last 8 bits are junk. The protocol is Big Endian, I am thinking that the HAL library handles this, however I am not completely sure.
uint16_t data;
while (1)
{
/*USER CODE END WHILE */
HAL_StatusTypeDef result= HAL_I2S_Receive(&hi2s1,&data,2,100);
HAL_UART_Transmit(&huart3,&data,2,100);
/*USER CODE BEGIN 3 */
}
/*USER CODE END 3 */
What did I miss?
I'm trying to run the code below on an ESP32 TTGO T-display running micropython from loboris. (It's esp32 pre-loaded with display drivers for TTGO Display) I have attached a GY-906 temp sensor through i2c for testing. i2c.scan() finds it without issue on 0x5a [80] like it is supposed to, but when I request temperature data, the response is always 0xFF instead of proper temperature readings.
When I run the exact same code on a WeMos D1 (only difference is the pin numbers) I get temperature data returned. I am attaching both logic analyzer screenshots hoping someone can tell me what I need to do differently. Both are directly wired from 3.3, gnd, and the 2 i2c pins.
Things I have tried: adding pull up resistors to SDA, SLC (10k, 1k, 100). Switching to different i2c pins. Result seems to be the same. What am I missing? Is there supposed to be a resistor somewhere I don't know about? Other hardware? The screenshots make me think that the GY906 is responding, just the wrong response value.
Main Code
import temp_sensor
Pin = machine.Pin
I2C = machine.I2C
i2c = machine.I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)
temp1 = temp_sensor.Temp.init(i2c)
print(temp1.read_object_temp())
time.sleep(1)
print(temp1.read_object_temp())
time.sleep(1)
print(temp1.read_object_temp())
time.sleep(1)
print(temp1.read_object_temp())
temp_sensor.py
import mlx90614 ##From https://github.com/mcauser/micropython-mlx90614
class Temp():
def init(i2c):
try:
sensor = mlx90614.MLX90614(i2c)
except:
print('couldnt connect to an i2c temp sensor')
sensor = False
else:
print('temp found')
#return sensor
finally:
return sensor
bad esp32 TTGO T-Display:
good 8266:
For anyone receiving 1037.55 responses from your gy-906 or MXL90614 sensor, that translates to 0xFF, 0xFF or all high (ones) from the sensor. This seems to happen when the sensor doesn't understand how to respond. (Thank you, #jasonharper for helping me understand this)
Here's how the math works:
The 0xFF, 0xFF in decimal is 65535.
The sensor resolution is 1/50 of
a degree which means you divide 65535 x 0.02 to convert to Kelvin, or
1310.7 (K)
Kelvin to Celsius (subtract 237.15) gets you 1037.55 C
Celsius to Fahrenheit gets you 1899.59 F
Bottom line, your sensor is hiccuping because it doesn't like the stop bit between the write and read, or you have a problem with your I2C bus, either the protocol is doing the request wrong or you have a cabling issue (length or wire gauge or connection, etc).
If it's the protocol like it was for me, see if anyone has updated the I2C system library recently and try a different version if possible.
I traced this issue down for days. Luckily I had a number of different MicroPython capable chips and was able to narrow it down to an old version of the machine.I2C library adding that stupid "stop" above.
I bought a $10 protocol analyzer on amazon to make that image above, and I tried loading the code on each of these: Wemos D1, HitLego ESP32S and TTGO T-Display. By trying the code on each, I was able to narrow it down to only the T-Display not working, which needed an custom old firmware version to get the ST7789 display working. The next step is to try to update and recompile the display library from loboris to work with the most recent Micropython firmware. If I make it work, I will reply below.
Is it possible to measure 3 specific resistor values by using GPIO / Without using a full ADC setup?
I have an alarm sensor that I want to hook up to my GPIO. This sensor has 3 specific resistors value, based on it's state:
1) Normal - 4k7
2) Alarm - 9k3
3) Tamper - infinite.
Due to long lines, I would prefer 12V power on one side.
I would like to be able to detect these states by 2 normal GPIO input pins.
Is that even possible? What would be the schematic needed for this?
Or is the only solution to use (external) ADC's?
I am thinking about a voltage diver with resistors and a 1N4148 diode to clip it to 3v3. But so far my results are unfruitfull.
Thanks.
The problem here is you have three levels to measure. If we had two we could use a simple resistor divider setup to make (say) the 4k7 and 9k3 outputs on the sensor to logic 0 (<=0.8V) or logic 1 (>=1.3V) on a single GPIO pin. We could do this on two GPIO pins if we had two "independent samples" of the sensor output rather than one.
Given the above it is possible to design some simple logic network to do the comparisons but as the other comment mentions you're off into the realms of electronics.
ADC is the simplest way to go if you want to stay in the software domain. The are other SBC devices e.g. ESP8266 which have onboard ADC functionality and built-in Wifi https://esp8266-projects.org/2015/03/internal-adc-esp8266/ or you can hook up an add-on ADC to the Rpi for example https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters
Good luck
I am using internal ADC temp sensor , in a low power device without the sensor in stop mode ,the uController consumes around 4 uA but when the temp sensor is on the consumption goes up to 8-9 uA
the problem is i can not turn the sensor OFF / i just measured the off current by setting it off from start by stmcube
i am searching for a code that can turn off the temp sensor
up until now i have tested these:
1-
HAL_ADC_Init(&hadc);
hadc.Lock=HAL_UNLOCKED;
__HAL_UNLOCK(&hadc);
HAL_ADCEx_DisableVREFINTTempSensor();
2-
ADC1->CR&=0X00000000;
ADC->CCR&=~(1<<23);
i prefer to work with HAL , it dose not seems to cut the Sensor power
Your ADC1->CR &= 0x00000000; line looks wrong to me, depending on the controller you're using.
There is usually a bit to disable the ADC which needs to be set, rather than writing all 0s. Try ADC1->CR = (0x01 << 1); instead. If you have the ST Micro written defines for your processor ADC1->CR = ADC_CR_ADDIS; should be the same but more readable. After disabling the ADC you will be able to turn off the TSEN bit of ADC->CCR.
I'm relatively new to the I2C protocol and I have to write a c++ library for a particular sensor I have. I'm using a raspberry pi to interface and wiringpi (the i2c component) to handle the low level communications. This is a pretty standard library (read8bits, read16bits, readbuffer, same for write, that support register operations) so all I need to do is the specific, more higher level, sensor operations and export the sensor data to the main project.
But I have a problem, this particular sensor is a 10DOF IMU sensor
(https://www.waveshare.com/product/10-DOF-IMU-Sensor-C.htm) - which provides temperature pressure accelerometer magnetormeter and gyroscope information - and I've managed to get the pressure and temperature sensor reporting just fine but the MPU component is just odd...
So the sensor registers two I2C addresses, one for the pressure/temperature and one for the accelerometer/magnetometer/gyroscope.
Waveshare has a C library which I am using to understand how the sensor works and, for some reason the library is writing to different addresses (different from the registered ones). This particular sensor registers two addresses, 0x77 and 0x68, which I check with i2cdetect but consulting the code it has a particular address for the gyroscope and accelerometer and a separate one for the magnetometer (0xD0, 0x18 again) which should be the same.
So is it normal to do read/writes on addresses other than the registered ones? Would that even work? What am I missing?
The MPU-9255 is actually 2 separate I2C devices, the accelerometer and gyro are accessed on I2C address 0x68 (or 0x69 depending on the logic level of the AD0 pin), the the magnetometer is accessed on I2C address 0x0C.
The accelerometer and gyro I2C address are covered in section 7.2 of the MPU-9255 product specification. The magnetometer I2C address is in section 4.11.
The values that you are seeing in the code (0xD0 and 0x18) are shifted by 1, which leaves room for the I2C read/write bit.
0x68 << 1 = 0xD0
0x0C << 1 = 0x18