STM32439I-EVAL2 board problems with camera - camera

I am working with the STM32439I-EVAL2 board and my OV2640 camera is not functioning properly. I have been testing it with the MB1063 Demonstration example from the STM32CubeF4 software and when I try to use the camera it shows "Error while Initializing Camera Interface. Please, chech if the camera module is mounted" on the LCD daughter board, even though the camera module is mounted and connected to the board. Has anyone else had this problem and solved it? Any help would be much appreciated.

I found the answer to my question. If anyone else has this problem, put this code in STM32Cube_FW_F4_V1.1.0\Drivers\BSP\STM324x9I_EVAL\stm324x9i_eval_io.c
uint8_t BSP_IO_Init(void)
{
uint8_t ret = IO_ERROR;
/* Read ID and verify the IO expander is ready */
if(stmpe1600_io_drv.ReadID(IO_I2C_ADDRESS) == STMPE1600_ID)
{
/* Initialize the IO driver structure */
io_driver = &stmpe1600_io_drv;
ret = IO_OK;
}
if(ret == IO_OK)
{
io_driver->Init(IO_I2C_ADDRESS);
io_driver->Start(IO_I2C_ADDRESS, IO_PIN_ALL);
io_driver->Config(IO_I2C_ADDRESS,IO_PIN_0,IO_MODE_OUTPUT);
io_driver->Config(IO_I2C_ADDRESS,IO_PIN_2,IO_MODE_OUTPUT);
io_driver->WritePin(IO_I2C_ADDRESS,IO_PIN_0,1);
io_driver->WritePin(IO_I2C_ADDRESS,IO_PIN_2,0);
}
return ret;
}

Related

Raspberry Pi Pico locks up when I try to use interrupts

I'm trying to use encoders to track the movement of three wheels on a robot, but as soon as any of the motors move the robot "locks up", it stops responding to commands, stops printing to the serial monitor, and just keeps spinning its wheels until I turn it off. I cut out everything except just the code to track one encoder and tried turning the wheel by hand to sus out the problem, but it still locked up. And even more strangely, now it will start spinning one of the wheels even though I've removed any code that should have it do that, even by mistake.
I used the Arduino IDE to program the pico since I've got no familiarity with python, but I can't find any information or troubleshooting tips for using interrupts with the pico that don't assume you're using micropython.
Here's the simplified code I'm using to try to find the problem. All it's meant to do is keep track of how many steps the encoder has made and print that to the serial monitor every second. Ive tried removing the serial and having it light up LEDs instead but that didn't help.
int encA = 10;
int encB = 11;
int count = 0;
int timer = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(encA),readEncoder,RISING);
timer = millis();
}
void loop() {
// put your main code here, to run repeatedly:
if (timer - millis() > 5000) {
Serial.println(count);
timer = millis();
}
}
void readEncoder() {
int bVal = digitalRead(encB);
if (bVal == 0) {
count--;
}
else{
count++;
}
}
Does the mapping function digitalPinToInterrupt for the Pi Pico work?
Can you try just using the interrupt number that corresponds to the pi?
attachInterrupt(9,readEncoder,RISING); //Or the number 0-25 which maps to that pin
https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html
You have the wrong pin to encoder in your example (maybe you incorrectly copy and pasted)?
attachInterrupt(digitalPinToInterrupt(**encA**),readEncoder,RISING);
void readEncoder() {
int bVal = digitalRead(**encB**); ...}
There is similar code on GitHub that you could modify and try instead.
https://github.com/jumejume1/Arduino/blob/master/ROTARY_ENCODER/ROTARY_ENCODER.ino
It might help you find a solution.
Also,
https://www.arduino.cc/reference/en/libraries/rpi_pico_timerinterrupt/
The interrupt number corresponds to the pin (unless you have reassigned it or disabled it) so for pin 11 the code can be:
attachInterrupt(11, buttonPressed, RISING);
This works:
bool buttonPress = false;
unsigned long buttonTime = 0; // To prevent debounce
void setup() {
Serial.begin(9600);
pinMode(11, INPUT_PULLUP);
attachInterrupt(11, buttonPressed, RISING);
// can be CHANGE or LOW or RISING or FALLING or HIGH
}
void loop() {
if(buttonPress) {
Serial.println(F("Pressed"));
buttonPress= false;
} else {
Serial.println(F("Normal"));
}
delay(250);
}
void buttonPressed() {
//Set timer to work for your loop code time
if (millis() - buttonTime > 250) {
//button press ok
buttonPress= true;
}
buttonTime = millis();
}
See: https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html for disable, enable etc.

How to optimize the code for reading SPI through ARDUINO in SLAVE mode

Not important:
I am doing a project to integrate a bluetooth module into a car radio pioneer. I understand perfectly well that it's easier to buy a new one =) but it's not interesting. At the moment, the byproduct was an adapter on arduino of resistor buttons, which the pioneer did not understand. The same adapter also controls the bluetooth board, it can switch the track forward and backward (there is no button on the steering wheel for pause). Now I want the bluetooth to turn on only in AUX mode. But there is a problem, which mode can be understood only by reading the signal from the SPI bus of the commutation microcircuit. I was able to read this data using arduino nano. I do not have an analyzer, but it is not necessary that I would understand something additional with it.
Essence of the question:
Using the scientific poke method, I found sequences indicating the launch of a particular mode, for example:
10110011
1
111
1000000
I'm sure I'm doing it wrong, but in the meantime I get duplicate results. But, when I try to detect them using IF, the nano speed is not enough and the chip starts to pass data.
#include "SPI.h"
bool flag01, flag02, flag03, flag11, flag12, flag13, flag31, flag32, flag33;
void setup (void)
{
Serial.begin(9600);
pinMode(MISO, OUTPUT);
SPCR |= _BV(SPE);
SPI.attachInterrupt();
}
// Вызываем функцию обработки прерываний по вектору SPI
// STC - Serial Transfer Comlete
ISR(SPI_STC_vect)
{
// Получаем байт из регистра данных SPI
byte c = SPDR;
Serial.println(c, BIN);
if (c == 0b1) {
Serial.println("1 ok");
flag11 = true;
} else {
flag11 = false;
}
if (c == 0b11 && flag11) {
Serial.println("11 ok");
flag12 = true;
} else {
flag12 = false;
flag11 = false;
}
if (c == 0b1100000 && flag11 && flag12) {
Serial.println("1100000 ok");
flag13 = true;
} else {
flag13 = false;
flag12 = false;
flag11 = false;
}
}
void loop(void)
{}
I myself am scared to look at this code, but I cannot think of anything better. It seems like I heard about some kind of buffer, but I don't know how to screw it to this solution. After all, the data packets go with dropping the CS signal and I can’t figure out how to determine the beginning and end of the packet from the commands in order to write it to a buffer or array and only then go through it with a comparison.
I will be grateful if someone will tell me at least in which direction to move.
There is also esp8266, but there is a limitation on the size of a data packet of 32 bits in a slave mode and I do not know how to get around it correctly.
So, actually the question.
How can I optimize the code so that the arduino has time to process the data and I can catch the pattern?
Perhaps, if we implement reading of data of arbitrary length on esp8266, or at least fill them to the required length, it would help me. But I still can't figure it out with the spi.slave library.
First you should keep your ISR as short as possible, certainly don't use Serial print inside the ISR.
Secondly, if you don't know exactly how long the data is, then you need to have a buffer to capture the data and try to determine the data length first before you trying to analysis it.
volatile uint8_t byteCount = 0;
volatile bool dataReady = false;
byte data[32];
// SPI interrupt routine
ISR (SPI_STC_vect)
{
data[byteCount++] = SPDR;
dataReady = true;
}
void setup (void)
{
// your SPI and Serial setup code
}
void loop (void)
{
// for determine the data stream length
if (dataReady) {
Serial.println(byteCount);
dataReady = false;
}
}
Once you know how long the data stream is (let assumed it is 15-byte long), you can then change your sketch slightly to capture the data and analysis it.
volatile uint8_t byteCount = 0;
volatile bool dataReady = false;
byte data[32];
// SPI interrupt routine
ISR (SPI_STC_vect)
{
data[byteCount++] = SPDR;
if (byteCount == 15)
dataReady = true;
}
void loop (void)
{
if (dataReady) {
dataReady = false;
// do your analysis here
}
}

TI CC2650STK - how to control onboard LED through iOS app

I am using this code from this repository: https://git.ti.com/sensortag-ios-source-code-example/sensortag-ios-source-code-example
I am trying to turn on the red onboard LED of the CC2650STK when the object temperature sensor exceeds 30°C and turn it off when the temperature is below 30°C again.
I'm not even sure if my current approach is correct but I'm stuck here. Does somebody know what I'm doing wrong?
Thanks in advance!
I did not change the hardware's firmware
I have already added the following into the "calcValue" method in the 'sensorTagAmbientTemperatureService.m' file:
if (tObj >= 30.0){
uint8_t valueRedLedOn = 0x01;
NSData *data = [NSData dataWithBytes:&valueRedLedOn length:sizeof(valueRedLedOn)];
[self.btHandle writeValue:data toCharacteristic:TI_SENSORTAG_IO_CONFIG];
redLedOn = true;
}
else {
if(redLedOn == true){
uint8_t valueRedLedOff = 0x00;
NSData *data = [NSData dataWithBytes:&valueRedLedOff length:sizeof(valueRedLedOn)];
[self.btHandle writeValue:data toCharacteristic:TI_SENSORTAG_IO_CONFIG];
redLedOn = false;
}
}
but when the app is running and the temperature reaches 30°C, I get a SIGABRT error (also see the log output):
screenshot of error w code and log
repository with my changes
Thanks for your answers.
I got to fix it.
The problem was that I forgot to initialize the service and characteristic.
I added 'sensorTagIoService.h' and '.m' and initialized it like the other services.
(the values for LED on and off in my question seem to be wrong tho)

STML4 USB virtual com port

I have the nucleo board (nucleo-L4R5ZI) and want to write a code to be able to send data from a uC to a PC via the USB. I followed some tutorials, used STM32CubeMx, other solutions found across the Internet, but anyways I failed. I can open the vcp on the PC side (using Hterm, TeraTerm and Realterm), but cannot get any data.
I use Eclipse and the buildin debugger, which I flashed to JLink.
The main loop:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
HAL_Delay(10000);
uint8_t HiMsg[] = "0123456789987654321001234567899876543210\r\n";
while (1)
{
if( CDC_Transmit_FS(HiMsg, 20) == USBD_OK )
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7); // blue LED
}
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14); // red LED
HAL_Delay(1000);
}
}
After executing this function, the blue LED lights only once and never changes its state (does not blink). It means that the CDC_Transmit_FS(...) returns USBD_OK only once, and next calls give USBD_Busy.
The MX_USB_DEVICE_Init() looks as follow:
void MX_USB_DEVICE_Init(void)
{
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
USBD_Start(&hUsbDeviceFS);
USBD_CDC_Init (&hUsbDeviceFS, &USBD_CDC); // I need to init it somewhere so I think here is a good place
}
The CDC_Transmit_FS looks like that:
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
CDC_Init_FS();
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
CDC_Init_FS();
/* USER CODE END 7 */
return result;
}
Does anyone know how to make it running? What do I miss?
Best,
This part look suspicious:
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
CDC_Init_FS();
The call to CDC_Init_FS() probably kills the packet before it had a chance to be sent to the host.
SO... I found the solution!
I can confirm that the code above works (just remove the CDC_Init_FS)!
Acctully, it was a driver problem. for windows 10 you also need to install it despide what's written in the reference

Arduino Bluetooth connection gives me uploading error

İt's a simple basic thing in which i have my arduino connected to a HC-06 bluetooth. The point is to control switch on/off led pin with my phone. Here's the code :
int ledPin = 13;
int state = 0;
int flag = 0;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
}
void loop() {
if(Serial.available() >0) {
state = Serial.read();
flag = 0;
}
if(state == '0') {
digitalWrite(ledPin, LOW);
Serial.println("LED: off");
flag = 1;
}
}
else if (state == '1') {
Serial.println("LED: on");
flag = 1;
}
}
I don't think it might have much relevance. Whenever i try to upload the code it gives me the following error:
avrdude stk500_recv() programmer is not responding
avrdude stk500_getsync() attempt # of 10 not in sync resp=0x00
Any idea why and how i might solve it. Thnx in advance!Douglas
I guess that there is a conflict between the USB/Serial and HC06/Serial.
You can solve this issue by using the Software Serial library and connect the HC06 to other pins. You can find an example here on how to use the library.
Unplug the rx and tx pins and keep in power and ground while uploading. When these pins are connected it interferes with the program's ability to upload. If this is in fact the problem then once the program is uploaded you can reattach rx and tx. Now you should be able to properly pair to your device.
Please disconnect the Tx and RX pin from Arduino before uploading and connect it after uploading the code. Otherwise, it will show an error