Using Rs485 and I2C display together - i2c

I am using rs485 to communicate between two Arduino nano. I have connected a 4 bit I2C display to one of the Arduino nano. When the nano receives data via Rs485 from the master nano, the data is displayed on the I2C display. But the issue is that I am only able to use one of those things i.e. if I am receiving data I am not able to display it on the I2C display and if I am displaying, then I am not able to receive the data.
Has someone tried doing it together?
Code for master nano
// rs485 master
void setup() {
Serial.begin(115200);
pinMode(2,OUTPUT); //DE/RE pin
}
int i;
String s = "s1b01n01";
void loop() {
digitalWrite(2,HIGH); // high for transmiting
for(i=0;i<=8;i++) {
Serial.print(s[i]);
}
digitalWrite(2,LOW);
}
Code for Slave nano
#include <TM1637Display.h>
#define CLK 4
#define DIO 16
#define ExtEnable 2 //DE/RE pin
TM1637Display display = TM1637Display(CLK, DIO); // Create display object of type TM1637Display:
const uint8_t data[] = {0xff, 0xff, 0xff, 0xff};// Create array that turns all segments on:
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00}; // Create array that turns all segments off:
int i = 0;
char add[8], c;
char address[] = {'s', '1', 'b', '0', '1', 'n', '0', '1'};
void setup() {
Serial.begin(115200);
pinMode(ExtEnable, OUTPUT); //DE/RE pin
display.clear();
delay(1000);
display.setBrightness(7); // Set the brightness:
}
void loop() {
digitalWrite(ExtEnable, LOW); // low for receiving
if (Serial.available()) {
c = Serial.read();
Serial.print(c);
add[i] = c;
i++;
digitalWrite(ExtEnable, HIGH);
//display.showNumberDec(3); //print on display
}
Serial.print("add");
Serial.println(add);
if(add == address) { // to check
display.showNumberDec(3); //print on display
}
}

Related

STM32 BSP Camera driver not writing to Camera Frame Buffer, ov2640 image sensor and 32F746G board

I am working on a university project to build a small IOT camera. I am using the 32F746GDISCOVERY board with the STM32F746NG MCU along with the ov2460 image sensor from WaveShare, and the B-CAMS-OMV board as an adaptor.
My code is based on an example for the STMF7508 Disco board, however, I have switched out the ov9655 BSP used in the example for the ov2460 BSP provided by STM.
Initially, I am attempting to display a continuous video feed on the LCD screen using the following data path:
Image Sensor → DCMI → DMA2 → Camera Frame buffer → DMA2 → LCD Frame buffer
I am able to communicate with the image sensor through I2C and successfully read the ID. When the image sensor is initialised, I am receiving frame event callbacks, however, no data is being written to the camera frame buffer. The DMA transfer between the camera frame buffer and the LCD frame buffer seems to be working fine.
I am pretty stumped as to why no data is being written to the camera Frame buffer and I have been working solidly on this problem over the last few weeks.
It looks like there is an issue with the DCMI DMA transfer. There could also be a problem in the configuration of the image sensor, however, this seems unlikely as I am receiving frame callbacks.
I was wondering if anyone had any experience with image sensors and STM32 MCUs and might be able to point me in the right direction.
I have attached my code below along with the CubeMX configurations I am using for DCMI and DMA2. The photo below shows a white screen on the LCD where the camera feed should be displayed as the camera frame buffer is memset to 255 upon initialisation.
camera.h
#ifndef INC_CAMERA_H_
#define INC_CAMERA_H_
#include "stm32f7xx_hal.h"
#include "stm32746g_discovery.h"
#include "stm32746g_discovery_sdram.h"
#include "stm32746g_discovery_camera.h"
#include "stdio.h"
#include "stdlib.h"
#include "LCD.h"
#include "string.h"
//#include "ov5460.h"
//#include "../../Drivers/BSP/Components/ov5640/ov5640.h"
//#include "../Drivers/BSP/Components/ov9665/ov9665.h"
#define CAMERA_FRAME_BUFFER 0xC0260000
//#define CAMERA_FRAME_BUFFER 0x60000000
#define LCD_FRAME_BUFFER 0xC0130000
//#define CAMERA_I2C_ADDRESS (uint16_t)0x60
void I2C_CameraTest(void);
//void cameraTestLoop(void);
void statusTest(void);
void initialiseCapture(void);
//void DCMI_GetCaptureMode(void);
//void runCamera(void);
void BSP_CAMERA_LineEventCallback(void);
void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst);
#endif /* INC_CAMERA_H_ */
camera.c
#include "camera.h"
DMA2D_HandleTypeDef hdma2d_eval;
static TS_StateTypeDef TS_State;
uint32_t i, previous_mode = CONTINOUS_MODE;
uint32_t *ptrLcd;
uint8_t status = CAMERA_OK;
uint8_t *cam_fb;
uint32_t cam_fb_size;
void LCD_init(void) {
BSP_LCD_Init();
BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
uint32_t *ptrLcd;
/* Init LCD screen buffer */
ptrLcd = (uint32_t*)(LCD_FRAME_BUFFER);
for (int i=0; i<(BSP_LCD_GetXSize()*BSP_LCD_GetYSize()); i++)
{
ptrLcd[i]=0;
}
BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FRAME_BUFFER);
//BSP_LCD_LayerRgb565Init(LTDC_ACTIVE_LAYER, LCD_FRAME_BUFFER);
/* Set LCD Foreground Layer */
BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER);
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
/* Clear the LCD */
BSP_LCD_Clear(LCD_COLOR_BLACK);
BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
BSP_LCD_FillRect(340, 80, 80, 30);
BSP_LCD_FillRect(340, 150, 80, 30);
BSP_LCD_DrawRect(8, 8, 322, 242);
BSP_LCD_DrawRect(9, 9, 321, 241);
BSP_LCD_SetFont(&Font12);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_SetBackColor(LCD_COLOR_BLUE);
BSP_LCD_DisplayStringAt(345, 90, (uint8_t *)"CONTINUOUS", LEFT_MODE);
BSP_LCD_DisplayStringAt(345, 160, (uint8_t *)" SNAPSHOT", LEFT_MODE);
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
printf("done screen\n");
}
void I2C_CameraTest(void) {
uint16_t CameraID = 0;
printf("\nHello World\n");
//uint16_t ov5640_ReadID(uint16_t DeviceAddr)
//CameraID = ov5640_ReadID(CAMERA_I2C_ADDRESS);
CameraID = ov2640_ReadID(CAMERA_I2C_ADDRESS);
printf("\n%i\n", CameraID);
}
void cameraTestLoop(void) {
while(1) {
I2C_CameraTest();
HAL_Delay(500);
}
}
void initialiseCapture(void) {
status = BSP_CAMERA_Init(RESOLUTION_R320x240);
if(status != CAMERA_OK)
{
BSP_LCD_SetFont(&Font16);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_FillRect(10, 10, 320, 240);
BSP_LCD_SetTextColor(LCD_COLOR_RED);
BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"CAMERA sensor is unpluged", LEFT_MODE);
BSP_LCD_DisplayStringAt(20, 120, (uint8_t *)"Plug the OV2640 sensor ", LEFT_MODE);
BSP_LCD_DisplayStringAt(20, 140, (uint8_t *)"on P1 camera connector ", LEFT_MODE);
BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"And restart the program ", LEFT_MODE);
}
else
{
// cam_fb_size = 320*240*2; // Resolution * color depth; RGB565=16bit=2byte
//
// cam_fb = (uint8_t *) malloc(cam_fb_size);
memset(CAMERA_FRAME_BUFFER, 255, cam_fb_size);
BSP_CAMERA_Init(RESOLUTION_R320x240);
BSP_CAMERA_ContinuousStart((uint8_t *)CAMERA_FRAME_BUFFER);
}
}
void BSP_CAMERA_LineEventCallback(void)
{
static uint32_t tmp, tmp2, counter;
if(240 > counter)
{
LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_FRAME_BUFFER + tmp), (uint32_t *)(LCD_FRAME_BUFFER + 0x4B28 + tmp2));
tmp = tmp + 320*sizeof(uint16_t);
tmp2 = tmp2 + (480) * sizeof(uint32_t);
counter++;
}
else
{
tmp = 0;
tmp2 = 0;
counter = 0;
}
}
/**
* #brief Converts a line to an ARGB8888 pixel format.
* #param pSrc Pointer to source buffer
* #param pDst Output color
* #param xSize Buffer width
* #param ColorMode Input color mode
* #retval None
*/
//void BSP_CAMERA_FrameEventCallback(void) {}
void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{
/* Enable DMA2D clock */
//__HAL_RCC_DMA2D_CLK_ENABLE();
/* Configure the DMA2D Mode, Color Mode and output offset */
hdma2d_eval.Init.Mode = DMA2D_M2M_PFC;
hdma2d_eval.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
//hdma2d_eval.Init.ColorMode = DMA2D_OUTPUT_RGB565;
hdma2d_eval.Init.OutputOffset = 0;
/* Foreground Configuration */
hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
hdma2d_eval.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
hdma2d_eval.LayerCfg[1].InputOffset = 0;
hdma2d_eval.Instance = DMA2D;
/* DMA2D Initialization */
if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
{
if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
{
if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, 320, 1) == HAL_OK)
{
/* Polling For DMA transfer */
// printf("polling for DMA transfer!");
HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
}
}
}
else
{
/* FatFs Initialization Error */
printf("/nFatFs Initialization Error/n");
while(1);
}
}
I have atempting to write to the camera frame buffer using the STM BSP Camera Driver, however I am ont recieving any data

Raspberry Pi send data more than 1 byte (e.g. integer 1920) to Arduino by USB cable (serial)

Currently, my project is to get a x coordination , cX value, from a webcam connected to raspberry pi 3B+, and send it to Arduino Uno. I successfully do the action when the integer is in range 0 to 255. Can I modify my code and send a larger integer, say up to 1920 to Arduino?
Here is part of my python code on raspi side:
import serial
import struct
while True:
...
cX = 248 //I want to send a larger number
print (cX)
ser.write(struct.pack('>H', cX))
...
Here is part of my c code on Arduino:
int cX = 0;
void setup()
{
...
Serial.begin(9600);
...
}
void loop()
{
if (Serial.available())
{
cX = Serial.read();
if (cX == 248)
{
//do something
}
}
}
Any help would be greatly appreciated
Try this on the Arduino side:
unsigned int cX = 0;
byte buffer[2] = {0};
size_t len = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available())
{
len = Serial.readBytes(buffer, 2);
if (len == 2)
{
cX = (((int)buffer[0]) << 8) | buffer[1];
if (cX == 1920)
{
//do something
}
}
}
}
On the Python side, I don't know in detail, but from what I could see on the documentation, with the argument >H you should be sending an unsigned short (2 bytes size), big-endian, so it should work.

I2c communication stm32f3 how can i solve?

i want to read touch activity from the touchscreen.If i touch, i want to led blink. Some my definitions in below code but generally i want to get my activity with i2c
Some definitions:
uint8_t deviceaddr;
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len);
static const int I2C_TIMEOUT = 65536;
unsigned char i2c_buffer[256];
uint32_t res;
This is my i2c read code:
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len)
{ //uint8_t deviceaddr ,0x00,(uint8_t *)&buf, sizeof(buf)
uint32_t timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if ((timeout--) == 0)
return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr << 1, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET)
{
if ((timeout--) == 0)
return 0;
}
}
This is my settings
void configure_interrupt_pins()
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/*ENABLE CLOCK FOR GPIOX*/
RCC_APB1PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
// ENABLE CLOCK FOR SYSCFG
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//SET PIN AS INPUT
// init_pin(EX_NCVIC_PORT, EX_NCVIC_Pin, GPIO_MODE_INPUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
//TELL THE SYSTEM THAT YOU WILL USE PXX FOR EXTI_LineX
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex);
//CONFIGIRATION of exti
EXTI_InitStruct.EXTI_Line = EXTI_Linex; //pxx connect to line x
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //enable interrupt
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //interrupt mode
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //triggers on rising and failing edge
EXTI_Init(&EXTI_InitStruct); //add to exti
//CONFIGURATION of nvic
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
This is my interrupt
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus((EXTI_Line0) != RESET))
{
res = touch_i2c_read(0x42, 0x00, i2c_buffer, 22);
printf("deneme");
if (!res)
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
But my code not working. Stm32 dont understand touch activity how can i solve this.
Edit i change line 1 every external interupts but i have res value 0 how can i fix this it must be different 0
Using a while() loop in an interrupt will cause problems, because the controller will never exit the loop. Try to use your i2c read Function in main() (with other words, a not-interrupt-context) and look if it works there.
I solved this error.
I hadn't any signal pb7 and pb6 so i changed codes as below:
// enable APB1 peripheral clock for I2C1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// enable clock for SCL and SDA pins
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
And then,
Device adress of the FT6236 was mising. it is not include at datasheet so i used debugging. I found the device adress which is the (0x32). And than my code working succesfully.

i2c-0 Device Driver not detected

I am a beginner in Embedded Linux. I am working on Hitex LPC4350 Eval Board. I have written a code to blink LEDs in my Board using I2C.
I could find the device driver present:
/dev # ls
console kmem null pts sample ttyS0 ttyS2 zero
i2c-0 mem ptmx random tty ttyS1 urandom
When i try to load my module - I get the message:
/mnt/blinkled/app # ./blinkled
/dev/i2c-0 : No such device or address
I have the i2c nod:
nod /dev/i2c-0 0777 0 0 c 89 0
Am I missing something ?
I tried various options given but of no use.
Please help me.
Edit:
The I2C pins are connected to a I2C Expander PCA9673 and the I2C Address is 0x48
Here is my code :
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
// I2C Linux device handle
int g_i2cFile;
// open the Linux device
void pca9673_i2c_open(void)
{
g_i2cFile = open("/dev/i2c-0", O_RDWR);
if (g_i2cFile < 0) {
perror("/dev/i2c-0 ");
exit(1);
}
}
// close the Linux device
void pca9673_i2c_close(void)
{
close(g_i2cFile);
}
// set the I2C slave address for all subsequent I2C device transfers
void pca9673_i2c_setaddress(int address)
{
if (ioctl(g_i2cFile, I2C_SLAVE, address) < 0) {
perror("/dev/i2c-0 Set Address");
exit(1);
}
}
void pca9673_i2c_outputdata(u_int8_t* data, int numbytes)
{
if (write(g_i2cFile, data, numbytes) != numbytes) {
perror("/dev/i2c-0 output data");
}
}
void pca9673_i2c_inputdata(u_int8_t* data, int numbytes)
{
if (read(g_i2cFile, data, numbytes) != numbytes) {
perror("/dev/i2c-0 input data");
}
}
int main(int argc, char **argv)
{
u_int8_t buffer[2];
// open Linux I2C device
pca9673_i2c_open();
// set address of the PCA9673
pca9673_i2c_setaddress(0x48);
// set 16 pin IO directions
buffer[0] = 0x00; // p0 to p7 output
buffer[1] = 0xFF; // p10 to p17 output
pca9673_i2c_outputdata(buffer, 2);
// glow LED
buffer[0] = 0x05; // p0 to p7 output
pca9673_i2c_outputdata(buffer, 1);
while (1) {
}
// close Linux I2C device
pca9673_i2c_close();
return 0;
}

Get Xbee response from Serial and send to a browser

I am trying to do some experiments with Arduino, Ethernet Shield and Xbee Shield.
I demonstrate my set up board like this:
Group 1: Arduino Uno + Xbee shield : broadcast the signal
Group 2: Arduino Uno + Xbee shield + Ethernet shield: receive the signal from
group 1, get the signal strength from AT command and print it into the browser.
The problem here is I can't get the result after sending to the Serial my ATDB command, actually, I am not sure it did worked as I expected.
Here is the code that I used to retrieve the signal strength.
int data;
void setup()
{
Serial.begin(9600);
}
void receiver_checker(){
delay(1200);
Serial.print("+++");
delay(1200);
bool bOK = false;
while (Serial.available() > 0) {
Serial.write(Serial.read());
bOK = true;
}
if(bOK)
{
Serial.println();
Serial.println("ATDB");
delay(100);
while (Serial.available() > 0) {
Serial.write(Serial.read());
}
Serial.println();
}
Serial.println();
}
void loop()
{
while(Serial.available() > 0){
data = Serial.read();
if(data == '1'){
// Broadcaster 1
//Serial.println("1------------------");
receiver_checker();
}
}
}
This part worked as I expected, it printed out in hex number the signal strength of the last package that it received.
Here is the code I combined the previous one and the server part from Web Server tutorial:
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xCA, 0xFE, 0x00, 0x00, 0x00, 0x02
};
IPAddress ip(1, 1, 1, 2);
int data;
int count = 0;
char result;
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
// Serial.print("server is at ");
// Serial.println(Ethernet.localIP());
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
// Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
data = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (data == '1') {
count += 1;
client.print("The number of times:");
client.print(count);
result = receiver_checker();
client.print("========================");
client.print(result);
client.print("========================");
}
}
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
char receiver_checker(){
char signal;
delay(1200);
Serial.print("+++");
delay(1200);
bool bOK = false;
while (Serial.available() > 0) {
Serial.write(Serial.read());
bOK = true;
}
if(bOK)
{
Serial.println();
Serial.println("ATDB");
delay(100);
while (Serial.available() > 0) {
signal = Serial.read();
}
Serial.println();
}
Serial.println();
return signal;
}
If there is another way to interact with the Xbee shield not go through Serial like I ask and get response directly, please let me know!
Your receiver_checker() function is reading characters back from the XBee module, and just returning the last character received, which is likely a carriage return or line feed.
Update the function to return an int, and replace your while (Serial.available() > 0) with the following:
signal = (int) strtoul(Serial.readString().c_str(), 0, 16);
That's for when the XBee returns a hexadecimal value. If it's returning a decimal value, change the 16 parameter to a 10.