I have been using ESP32 and writing code in Arduino. However, when I enable Bluetooth, GPIO4 and GPIO15 does not work to read analog inputs. I have connected IR LED's on both pins and reading analog signals. If Bluetooth code is not used, ESP32 is reading the analog signals and displaying it on serial monitor. If the below Bluetooth code is used, the reading is shown as 255 on both pins (reading 5v. Yes, they are 5v for now and will be level shifted to 3.3v).
Can someone please check and suggest a solution?
I have switched the sensors, removed them and whatever I do, the reading is the same when Bluetooth is read
Bluetooth code:
void init_bluetooth() {
ESP_BT.begin("EKA Robot"); //Name of your Bluetooth Signal
Serial.println("Bluetooth Device is Ready to Pair");
}
IR code:
// Read Infrared LED on GPIO4. Similar function exists to read GPIO15
int readIR() {
int sensorValue = analogRead(oaPinL);
delay(5);
sensorValue = map(sensorValue, 0, 4095, 0, 255);
return (sensorValue);
}
I expect to read the sensor values. However, all it shows is 255. Does it mean it is somehow pulled high?
There are two A/D converters in the ESP32 chip, ADC1 and ADC2. ADC2 pins can not be used when Wi-Fi or Bluetooth is used. Pins connected to ADC1 do work. These are GPIO32-36 and GPIO39.
Related
I've been working on a project where I use a PGA2310 volume control IC to set the volume of an audio signal. The chip's interface is supposedly SPI, but no matter how much I try, I just can't seem to get it right. The chip takes a 16 bit word over SPI that contains the left and right channel volume information.
I'm wondering if I am using the sdk all wrong and my code is whacked.
I guess my question is: Am I setting up and using the SPI functions correctly?
Here is my code
/**
* SPI interface for PGA2310 volume control ic
*/
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "pico/time.h"
const int CS = 0;
const int SDI = 1;
const int SCLK = 2;
const int LED_PIN16 = 16;
const int LED_PIN25 = 25;
uint16_t PGA2310();
uint16_t PGA2310() {
int baud = 1600000;
// SPI inistalization
spi_init(spi0, baud);
spi_set_format(spi0, 16, SPI_CPOL_0 , SPI_CPHA_0, SPI_MSB_FIRST);
// Sets SPI pins
gpio_set_function(CS, GPIO_FUNC_SPI);
gpio_set_function(SDI, GPIO_FUNC_SPI);
gpio_set_function(SCLK, GPIO_FUNC_SPI);
// Sets LED pins
gpio_init(LED_PIN16);
gpio_set_dir(LED_PIN16, GPIO_OUT);
gpio_init(LED_PIN25);
gpio_set_dir(LED_PIN25, GPIO_OUT);
// Data to send to chip. only sending first 8 bits for right channel.
// This is because I am currently just testing the output of the right channel
uint16_t high = 255;
uint16_t low = 100;
// Test by toggling between high and low volume states with LED indicators
while (true) {
gpio_put(LED_PIN25, 1);
spi_write16_blocking(spi0, &high, 1);
sleep_ms(2000);
gpio_put(LED_PIN25, 0);
spi_write16_blocking(spi0, &low, 1);
sleep_ms(2000);
}
}
I've tried a bunch of different methods that I found online for using SPI with the pico SDK. I've tried just sending 8 bits.
Let me know if more info is needed.
As explained in comments, SPI normally consists of 4 signals: /SS, SCLK, MOSI and MISO.
/SS = slave select, also known as chip select. Almost always active low.
SCLK = serial clock.
MOSI = Master Output Slave Input. The main data line. Your MCU seems to call this SDO (serial data out?).
MISO = Master Input Slave Output. Optional signal for duplex (two way) communication SPI. Your MCU seems to call this SDI (serial data input).
In this case the MCU is the master so you should be using MOSI/SDO. A MCU is almost always the master, except when communicating with other MCUs.
Additionally, always double check which CPOL and CPHA settings that the slave expects. Getting these wrong is a classic problem and can lead to subtle "clock skew" problems where everything works fine most of the time, then fail and give corrupt data intermittently.
The names you pick for variables/constants in C code do not have any effect on the hardware and they disappear as soon as the code is compiled. The most important thing is that you understand how the hardware works, read the documentation for the RP2040 SDK functions you are calling, and then pass the correct values to the RP2040 SDK functions.
The biggest problem is that you need to rethink every pin assignment. The RP2040 hardware SPI pin functions are defined in column F1 of the "GPIO Functions" section of the RP2040 datasheet. Here is an excerpt from that table:
This table tells us, for example, you cannot use pin 0 as the SPI0 CS function. If you assign that pin to be an SPI pin, it will be the SPI0 RX (data receiving) pin.
At a minimum, you need to pick one pin to be the SPI0 SCK pin and another to be the SPI0 TX pin, and you must connect those pins from the RP2040 to the equivalent pins on your device. Then you might also need to pick an RP2040 pin to control the CS pin on your device, if it has one. On the RP2040 side, this pin would be configured as a GPIO output pin and you would drive it low or high to enable your device. Refer to your device's datasheet for details about what signals it expects on its inputs and then use an oscilloscope to make sure you are generating compliant signals.
Another problem is that the spi_write16_blocking is probably modifying your high and low variables, so you will probably need to set those to the right values before each time that you use them. (So there is no point in having two different variables like that, just have one.)
I am trying to program a Microchip MCP4141 digital potentiometer with the STM32CUBEIDE development environment using a NUCLEO F334R8 board. I am sending a 16 bit command through the SPI communications port. When I send the command byte with the data byte, I cannot notice voltage variations between the P0A and P0W terminals of the MCP4141.
Could you help me find the programming error? Thanks
uint8_t data[2];
data[0]=0x00;
data[1]=0x0F;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, data, 2, 500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_SET);
Usually when an SPI peripheral does not work, the commands are not received by the slave chip. This can have multiple reasons:
Incorrect wiring (MOSI, MISO, CLK lines)
Incorrect SPI mode (clock phase, clock polarity) --> check SPI settings in CubeMX
Slave chip is in Reset because of incorrect/floating EN or RST Pin
Can you probe the data and clock lines? Do you see a signal being transmitted?
Alternatively, can you successfully read anything from the chips internal memory e.g. the status register?
For the past couple of days i have been trying to create a program which reads from a Tx of barcode scanner.
I have tried a bunch of different things such as different programs but also different scanners.
A sample program that i wrote is for example:
#include <SoftwareSerial.h>
SoftwareSerial mySerial (50, 51);
unsigned char incomingByte;
void setup ()
{
Serial.begin (9600);
mySerial.begin (9600);
Serial.println ("begin initial Serial!\n");
}
void loop ()
{
while(mySerial.available () > 0)
{
incomingByte=mySerial.read ();
Serial.print (incomingByte,HEX);
}
Serial.println ();
}
At this time i can not provide a proper connection diagram (will when i have a chance), but the arduino MEGA 2560 is connected with 3 wires to the barcode scanner, A Tx (pin 50), Rx (pin 51) and GND
background info on transmitted data:
startbit: 0x02
stopbit: 0x03
Ultimate goal:
Scanner scans barcode, arduino reads the datastream and sends a output when it recognizes a code.
How do i achieve the ultimate goal?
Thanks in advance!
Arduino 2560 pin 50 and 51 are TTL level signals. You need to provide a RS-232 driver to invert and level shift the signal.
An example driver is MAX232CPE.
http://www.surplus-electronics-sales.com/index.php?main_page=product_info&cPath=15&products_id=828&gclid=CJv7vNWim8oCFYOEaQodSjQDFQ
Also, softwareserial supports an option to invert the logic level. From the Arduino page:
inverse_logic: is used to invert the sense of incoming bits (the default is normal logic). If set, SoftwareSerial treats a LOW (0 volts on the pin, normally) on the Rx pin as a 1-bit (the idle state) and a HIGH (5 volts on the pin, normally) as a 0-bit. It also affects the way that it writes to the Tx pin. Default value is false.
Warning: You should not connect devices which output serial data outside the range that the Arduino can handle, normally 0V to 5V, for a board running at 5V, and 0V to 3.3V for a board running at 3.3V.
Arduino SoftwareSerial Reference page
I recently figured out how to reprogram the rfbees from seeedstudio. (a 3v3 xbee format rf module with onboard atmega168)
I want to port my existing DMX circuit to the rfbee.
I'm using a Max 485 chip to create dmx signals using this circuit http://fritzing.org/projects/arduino-to-dmx-converter/
This works perfectly on my arduino mega at 5v, however I've uploaded the same sketch to the rfbee but not getting any luck.
I realize the rfbee's pins only output 3v3 logic and the max485 is supposed to be 5v.
However, the 5v pin on the mega can still run the Max485 even if it is brought down to approx 3 volts by using three 220ohm resistors as voltage divider. I can also apparently drive the max485 by holding the 5v arduino pin with one hand and touching the input pin of the Max 485. The chip also seems perfectly happy having its Vin connected to the Mega's 3v3 pin instead of 5v.
My question is this, is there an electrical difference between these last approaches versus the clean 3v3 I'd be getting from the rfbee?
I'm using identical code on both devices with an LED to verify heartbeat. As far as I'm aware the pin I'm using (pin 5) is a pwm pin on both devices, http://www.seeedstudio.com/wiki/index.php?title=RFbee_V1.1_-_Wireless_Arduino_compatible_node .
I'm at a bit of a loss to know to check next, I've tested the output on pin 5 of both devices with an led (no oscilloscope unfortunately), both showed the same brightness and that it was an oscillating signal.
Code posted below.
#include <DmxSimple.h>
const byte DMX_RGB_CHANNELS[]={2, 3, 4};
const byte DMX_OUT_PIN=5;
int led = 13;
void setup() {
pinMode(led, OUTPUT);
DmxSimple.usePin(DMX_OUT_PIN);
DmxSimple.maxChannel(6);
}
void loop() {
digitalWrite(led, HIGH);
DmxSimple.write(DMX_RGB_CHANNELS[0], 255);
DmxSimple.write(DMX_RGB_CHANNELS[1], 255);
DmxSimple.write(DMX_RGB_CHANNELS[2], 255);
delay(200);
digitalWrite(led, LOW);
DmxSimple.write(DMX_RGB_CHANNELS[0], 0);
DmxSimple.write(DMX_RGB_CHANNELS[1], 0);
DmxSimple.write(DMX_RGB_CHANNELS[2], 0);
delay(200);
}
Finally figured it out, for some reason the atmega was running at half speed therefore the DMX baud rate was wrong. I was able to change the clock speed from 16MHz to 8Mhz in the boards.txt of the arduino compiler. Works now and the Max485 and RFbee seem to be working fine off just two AA batteries. It's been a long week!
Any idea why my native C application can't reach higher baudrates than 38400?
I have exactly the same application which i successfully initialize to listen and transmit on 9600, 19200, 38400 baudes. However as soon as i set up for 57600 i get garabage out of the transmitter(receiver i don't know). I'm listening to it with a terminal so i see the garbage directly from pin header.
I use Raspbian and uart on Pin 14 and 15 of the GPIO header.
Is there any adjustment of some precission fraction which causes the problem?
Right now i just do this (and it works):
cfsetispeed(&options,B38400);
cfsetospeed(&options,B38400);
tcsetattr(uart0_filestream, TCSANOW, &options);
fcntl(uart0_filestream, F_SETFL,O_NDELAY);
TX part:
int a = write(uart0_filestream, StartOfTheMessage, Length);
Thank you.
Your UART wires do not support the higher baud rate.