I have the MSP430 configured as an i2c master device and it is talking with two slave devices: a battery fuel gauge (LTC2943) and a battery charger (LT8491 evaluation board). I noticed that when talking with the battery charger, a duplicate byte gets sent over the i2c bus (this is bad); let's call it a 'ghost' byte. I only see this ghost/duplicate byte when talking with the battery charger but never with the fuel gauge. Both of those slave devices are on the same bus and I'm performing the same operation on both of them (reading 2-bytes); see code below. After several days of frustration, I noticed a peculiar difference between the two devices…
I noticed that when I talk to the fuel gauge (i2c address 0x64), the i2c clock line (SCL) idles low. But when I talk to the battery charger (i2c address 0x10) the SCL line idles high. Notice the SCL line behavior after the address byte in the provided pictures (links below). Per the MSP430 datasheet, it is my understanding that the SCL line should be idling LOW after the slave the address is pushed on the line (see page 833 of the MSP430 family guide here: www.ti.com/.../slau367p.pdf). There's a comment that says: "Bus stalled (SCL held low) until data available".
A few questions related to this:
Why does the SCL line idle differently on those two devices (see picture links below) even though they are on the same i2c bus and we are performing the same 2-byte read operation and using the same i2c driver code?
The MSP430 family guide (page 833) has that comment that says: "Bus stalled (SCL held low) until data available". Whose responsibility it is to hold the SCL low in this case? Is it the master (MSP430) or the slave device?
In the same page of the family guide (page 833), there are cases where it appears that a certain action needs to be performed DURING the transmission of a data byte, is this a hard requirement? For example, let's consider the case where we want to write one byte to the slave device, then follow it with a repeated start and then read one byte. The timing diagram on page 833 implies that we need to set UCTR=0 and UCTXSTT=1 DURING the transmission of the current data byte. What would happen if we set these registers AFTER the data byte has been transmitted?
The 'ghost' byte that I am seeing when talking with the battery charger is basically the MSP430 pushing the contents of the TXBUF out on the bus again! This occurs even after we have already configured the the MSP430 to be in receive mode. Please notice how/when/where I am toggling P4.6 in code as well as in the logic captures (see pictures). Why does this ghost byte happen?! Why does the MSP430 push it's TXBUF out on the line again?
Zoomed out picture of i2c communication:
Zoomed in picture with fuel gauge (good communication):
Zoomed in picture with battery charger (bad communication):
My code:
#include <string.h>
#include "driverlib.h"
#define BATTERY_CHARGER_I2C_ADDR ( 0x10 )
#define FUEL_GAUGE_I2C_ADDR ( 0x64 )
#define GENERAL_I2C_TIMEOUT_MS ( 3 ) //When waiting for an i2c flag/condition, timeout after 3 milliseconds so we don't get stuck waiting forever
//local (static) functions
static void init_hardware( void );
static bool hwm_i2c_master_receive_data( uint8_t slave_addr, uint8_t* read_ptr, uint8_t size_bytes );
static bool hwm_i2c_master_send_data( uint8_t slave_addr, uint8_t* write_ptr, uint8_t size_bytes, bool issue_stop );
void main (void)
{
uint8_t write_data;
uint8_t read_data[2];
//Initialize HWM manager
init_hardware();
while(1)
{
__delay_cycles( 1000000 ); //delay for about 1 second (1 cycle ~ 1us)
//read 2 bytes from fuel gauge
write_data = 0x08;//address of voltage register
hwm_i2c_master_send_data( FUEL_GAUGE_I2C_ADDR, &write_data, 1, false );
hwm_i2c_master_receive_data(FUEL_GAUGE_I2C_ADDR, read_data, 2);
//read 2 bytes from battery charger
write_data = 0x28;//address of Rsense1 configuration register
hwm_i2c_master_send_data( BATTERY_CHARGER_I2C_ADDR, &write_data, 1, false );
hwm_i2c_master_receive_data( BATTERY_CHARGER_I2C_ADDR, read_data, 2);
}
} //main()
static void init_hardware( void )
{
Timer_A_initContinuousModeParam timerA_cont_param;
//Disable internal watchdog timer
WDTCTL = WDTPW | WDTHOLD;
//Set VLO to drive ACLK with a divider of 1 (i.e. run ACLK at 10KHz)
CS_initClockSignal( CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
//This block of code basically initializes TimerA1 to run continuously at 1KHz
memset( &timerA_cont_param, 0, sizeof(timerA_cont_param) );
timerA_cont_param.clockSource = TIMER_A_CLOCKSOURCE_ACLK; //ACLK to drive TimerA1
timerA_cont_param.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_10; //Divide ACLK by 10 in order to get 1KHz
timerA_cont_param.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; //Disable TimerA1 overflow interrupt
timerA_cont_param.timerClear = TIMER_A_DO_CLEAR; //Clear/reset TimerA1 counter
timerA_cont_param.startTimer = true; //Start TimerA1 counter
Timer_A_initContinuousMode( TIMER_A1_BASE, &timerA_cont_param );
//Configure P4.6 as an output pin for debugging (timing purposes)
GPIO_setAsOutputPin( GPIO_PORT_P4, GPIO_PIN6 );
GPIO_setOutputLowOnPin( GPIO_PORT_P4, GPIO_PIN6 );
//This block initializes the i2c peripheral
//Configure pins P1.6 (SDA) and P1.7 (SCL) for I2C (secondary module functionality)
GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P1, ( GPIO_PIN6 | GPIO_PIN7 ), GPIO_SECONDARY_MODULE_FUNCTION );
PMM_unlockLPM5(); //Clear the LOCKLPM5 bit so the GPIO and i2c configuration takes effect
//Configure the I2C bus
EUSCI_B_I2C_initMasterParam i2c_master_init_param = {0};
i2c_master_init_param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; //use SMCLK clock signal
i2c_master_init_param.i2cClk = CS_getSMCLK(); //Give SMCLK freq in Hz
i2c_master_init_param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS; //100KBps datarate
i2c_master_init_param.byteCounterThreshold = 0; //Don't care because 'no auto stop'
i2c_master_init_param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP; //We will handle the stop bit manually
EUSCI_B_I2C_initMaster( EUSCI_B0_BASE, &i2c_master_init_param );
EUSCI_B_I2C_enable(EUSCI_B0_BASE); //Enable the I2C bus (i.e. pull it out of reset state)
}
static bool hwm_i2c_master_receive_data( uint8_t slave_addr, uint8_t* read_ptr, uint8_t size_bytes )
{
bool proceed;
proceed = true;
//Basic sanity checks on address and size
if( NULL == read_ptr || 0 == size_bytes )
{
return false;
}
//Set P4.6 high for debugging (see scope captures)
GPIO_setOutputHighOnPin( GPIO_PORT_P4, GPIO_PIN6 );
UCB0I2CSA = slave_addr; //Set slave address
UCB0CTLW0 &= ~UCTR; //Set I2C bus in receiver (read) mode
UCB0IFG &= ~UCNACKIFG; //Clear NACK interrupt flag (fresh start)
UCB0CTLW0 |= UCTXSTT; //Issue START condition
//Wait for START condition to complete
TA1R = 0;
while( proceed && (UCB0CTLW0 & UCTXSTT) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (!(UCB0CTLW0 & UCTXSTT));
//If size is one byte, request STOP condition now! This is time critical (but not sure why :/)
if( proceed && (1 == size_bytes) )
{
UCB0CTLW0 |= UCTXSTP;
}
//Check that we received ACK from slave
proceed = proceed && (!(UCB0IFG & UCNACKIFG));
//Loop through and pull the requested number for bytes from the RX buffer
while( proceed && (size_bytes > 0) )
{
//Wait for RX buffer to be ready/full
TA1R = 0;
while( (!(UCB0IFG & UCRXIFG0)) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (UCB0IFG & UCRXIFG0);
if( proceed )
{
*read_ptr = UCB0RXBUF; //Pull byte out of RX buffer
read_ptr++; //Increment pointer
size_bytes--; //Decrement number of bytes left to read
//If there's only one byte left to read, request STOP condition. This is time critical (again, not sure why)
if( 1 == size_bytes )
{
UCB0CTLW0 |= UCTXSTP;
}
}
}
//Wait for the STOP condition to complete
TA1R = 0;
while( (UCB0CTLW0 & UCTXSTP) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (!(UCB0CTLW0 & UCTXSTP));
if( !proceed )
{
//If we got here, it means something went bad (e.g. timed out or slave NACK'ed),
//let's request STOP to terminate communication
UCB0CTLW0 |= UCTXSTP;
//wait for stop to complete
TA1R = 0;
while( (UCB0CTLW0 & UCTXSTP) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
}
//Clear P4.6
GPIO_setOutputLowOnPin( GPIO_PORT_P4, GPIO_PIN6 );
return proceed;
} //hwm_i2c_master_receive_data()
static bool hwm_i2c_master_send_data( uint8_t slave_addr, uint8_t* write_ptr, uint8_t size_bytes, bool issue_stop )
{
bool proceed;
proceed = true;
//Basic sanity checks on address and size
if( NULL == write_ptr || 0 == size_bytes )
{
return false;
}
UCB0I2CSA = slave_addr; //Set slave address
UCB0CTLW0 |= UCTR; //Set I2C bus in transmit mode
UCB0IFG &= ~UCNACKIFG; //Clear NACK interrupt flag (fresh start)
UCB0CTLW0 |= UCTXSTT; //Issue START condition
//Wait for START condition to complete
TA1R = 0;
while( proceed && (UCB0CTLW0 & UCTXSTT) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (!(UCB0CTLW0 & UCTXSTT));
//At this point, we have just pushed the slave address over the i2c line.
//According to the MSP430 datasheet, the MSP430 would/should hold the
//SCL line low until we put something in the UCB0TXBUF.
//In other words, during this delay, the SCL should be held low. This is
//true when talking with the fuel gauge (LTC2943) but is NOT the case when
//talking with the battery charger! Why is that?!
__delay_cycles( 100 ); //delay of ~100us, please notice the SCL line (pictures) during this delay
//Wait for tx buffer to be ready/empty
TA1R = 0;
while( proceed && (!(UCB0IFG & UCTXIFG0)) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (UCB0IFG & UCTXIFG0);
//Check that we received ACK from slave
proceed = proceed && (!(UCB0IFG & UCNACKIFG));
//Loop through and send the data
while( proceed && (size_bytes > 0) )
{
//Set P4.6 high for debugging
GPIO_setOutputHighOnPin( GPIO_PORT_P4, GPIO_PIN6 );
//Place byte in tx buffer for transmission
UCB0TXBUF = *write_ptr;
//Wait for byte to flush out of tx buffer
TA1R = 0;
while( proceed && (!(UCB0IFG & UCTXIFG0)) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (UCB0IFG & UCTXIFG0);
//Check the ACK after every byte to make sure it went ok
proceed = proceed && (!(UCB0IFG & UCNACKIFG));
//Increment write pointer and decrement remaining size
write_ptr++;
size_bytes--;
}
//If caller requested a STOP condition to be sent
if( proceed && issue_stop )
{
//Issue STOP condition
UCB0CTLW0 |= UCTXSTP;
//Wait for STOP condition to go through
TA1R = 0;
while( (UCB0CTLW0 & UCTXSTP) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
proceed = proceed && (!(UCB0CTLW0 & UCTXSTP));
}
if( !proceed )
{
//If we got here, it means something went bad (e.g. timed out or slave NACK'ed),
//let's request STOP to terminate communication
UCB0CTLW0 |= UCTXSTP;
//wait for stop to complete
TA1R = 0;
while( (UCB0CTLW0 & UCTXSTP) && (TA1R < GENERAL_I2C_TIMEOUT_MS) );
}
GPIO_setOutputLowOnPin( GPIO_PORT_P4, GPIO_PIN6 );
return proceed;
} //hwm_i2c_master_send_data()
I'm using an ESP32 (Wemos D1 Mini) to track GPS (RadioLink SE100), show it on an OLED, and write it to an SD card (VMA304). Everything works well, independently. But put all together, the compile is fine, the upload works, the OLED displays some early messages, and GPS is transmitting data, but then things stop working.
I did get a serial message: "More than 100 frame errors, UART RX was disabled." So, I commented out the Serial.begin(115200) line.
In the serial monitor good GPS data is being output, but that doesn't get written by the SD file. GPS is the root of the problem, I think. If I just disable GPS, everything else works. Any ideas?
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h> // OLED - text
#include <Adafruit_GFX.h> // OLED - graphics
#include <ESP8266WiFi.h> // WeMos D1 Mini ESP32
#include <SD.h> // SD Card (VMA304)
#include "TinyGPS++.h" // RadioLink SE100
#include "SoftwareSerial.h"
SoftwareSerial GPSmodule(0,2); // DON'T USE TX and RX pins!!
TinyGPSPlus gps; // GPS object for the NMEA data
#define OLED_ADDR 0x3C // OLED display TWI address
Adafruit_SSD1306 display(-1);
#define CS_pin D8 // SD card - needs to be output
File myFile;
void setup() {
// Serial.begin( 115200 );
// start OLED display
display.begin( SSD1306_SWITCHCAPVCC, OLED_ADDR );
display.setTextSize(2);
display.setTextColor(WHITE);
display.clearDisplay();
display.setCursor(20,10);
display.print("GPS data to");
display.setCursor(20,30);
display.print("OLED display");
display.setCursor(20,50);
display.print("& SD Card");
display.display();
// start GPS
GPSmodule.begin( 9600 ); // start the GPS
Serial.println( "GPS Start" );
// start SD card
pinMode( CS_pin, OUTPUT ); // for SD card
if( !SD.begin( CS_pin )) {
Serial.println( "SD card initialization failed!" );
return;
}
Serial.println( "SD card initialized." );
}
void loop() {
while(GPSmodule.available()) { // While characters come from the GPS
gps.encode(GPSmodule.read()); // Feed serial NMEA data into library one char at a time
}
if( gps.location.isUpdated() ) { // constantly get packages of NMEA data
// Write the latest info from the GPS data to the SD card
display.clearDisplay();
display.setCursor(20,10);
display.print( "Wemos.txt" );
display.display();
myFile = SD.open( "Wemos.txt", FILE_WRITE );
// write stuff in it
if( myFile ) {
display.clearDisplay();
display.setCursor(20,30);
display.print( "GPS data" );
display.display();
myFile.println("Satellite Count:");
myFile.println(gps.satellites.value());
myFile.println("Latitude:");
myFile.println(gps.location.lat(), 6);
myFile.println("Longitude:");
myFile.println(gps.location.lng(), 6);
myFile.println("Speed MPH:");
myFile.println(gps.speed.mph());
myFile.println("Altitude Feet:");
myFile.println(gps.altitude.feet());
myFile.println("");
display.setCursor(20,30);
display.print( "file done" );
display.display();
}
myFile.close();
delay(100);
}
}
MY MISTAKE: I used the RX and TX pins on the ESP32. Don't do that!
It will output all the GPS data on the Serial Monitor (slightly edited to hide my location, :-)
There should only by MY prints on the Serial Monitor.
$GLGSV,3,1,10,66,42,088,24,68,62,000,48,68,24,298,,86,01,018,*6E
$GLGSV,3,2,10,86,44,046,41,88,46,129,40,88,10,181,,82,24,248,36*6E
$GLGSV,3,4,10,84,44,294,18,84,06,446,*61
$GNGLL,4246.18869,N,08409.46219,W,196640.00,A,A*61
$GNRMC,196641.00,A,4246.18880,N,08409.46228,W,0.146,,111118,,,A*8A
$GNVTG,,T,,M,0.146,N,0.268,K,A*41
$GNGGA,196642.00,4246.18880,N,08409.46228,W,1,12,0.84,246.6,M,-44.9,M,,*82
$GNGSA,A,4,10,20,42,24,14,21,16,12,26,,,,1.64,0.84,1.29*18
$GNGSA,A,4,68,88,86,66,84,82,,,,,,,1.64,0.84,1.29*1B
$GPGSV,5,1,18,08,06,289,,10,86,332,40,11,02,428,,12,11,106,19*88
$GPGSV,5,2,18,14,40,266,28,16,14,080,24,18,14,421,18,20,80,118,46*88
$GPGSV,5,3,18,21,26,184,21,24,41,068,16,26,06,139,22,28,04,261,09*86
$GPGSV,5,4,18,41,00,206,,42,49,268,41,46,24,248,,48,20,240,28*81
$GPGSV,5,6,18,61,46,214,*4A
I think The device can not be read once for data that needs to be read within the allowed time. You can use this function (smartdelay(100)) to change "delay(100)"
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (GPSmodule.available())
gps.encode(GPSmodule.read());
} while (millis() - start < ms);
}
You should only open files once.
I hope this can help you.
Turns out using the chip's RX and TX pins is the big mistake. Switched the GPS RX and TX over to other unused pins and - BAM! - everything works.
I have a Raspberry Pi working as a WiFi hotspot and an Arduino Uno trying to get data from it using an ESP8266 module.
This is my receiver code for Arduino:
#include <SoftwareSerial.h>
#include <SerialESP8266wifi.h>
#define sw_serial_rx_pin 4 // Connect this pin to TX on the esp8266
#define sw_serial_tx_pin 6 // Connect this pin to RX on the esp8266
#define esp8266_reset_pin 5 // Connect this pin to CH_PD on the esp8266, not reset. (let reset be unconnected)
SoftwareSerial swSerial(sw_serial_rx_pin, sw_serial_tx_pin);
// the last parameter sets the local echo option for the ESP8266 module..
SerialESP8266wifi wifi(swSerial, swSerial, esp8266_reset_pin, Serial);//adding Serial enabled local echo and wifi debug
String inputString;
boolean stringComplete = false;
unsigned long nextPing = 0;
void setup() {
inputString.reserve(20);
swSerial.begin(9600);
Serial.begin(9600);
while (!Serial)
;
Serial.println("Starting wifi");
wifi.setTransportToTCP();// this is also default
// wifi.setTransportToUDP();//Will use UDP when connecting to server, default is TCP
wifi.endSendWithNewline(true); // Will end all transmissions with a newline and carriage return ie println.. default is true
wifi.begin();
wifi.connectToAP("RPi", "raspberry");
wifi.connectToServer("192.168.50.1", "1234");
wifi.send(SERVER, "ESP8266 test app started");
}
void loop() {
//Make sure the esp8266 is started..
if (!wifi.isStarted())
wifi.begin();
//Send what you typed in the arduino console to the server
static char buf[20];
if (stringComplete) {
inputString.toCharArray(buf, sizeof buf);
wifi.send(SERVER, buf);
inputString = "";
stringComplete = false;
}
//Send a ping once in a while..
if (millis() > nextPing) {
wifi.send(SERVER, "Ping ping..");
nextPing = millis() + 10000;
}
//Listen for incoming messages and echo back, will wait until a message is received, or max 6000ms..
WifiMessage in = wifi.listenForIncomingMessage(6000);
if (in.hasData) {
if (in.channel == SERVER)
Serial.println("Message from the server:");
else
Serial.println("Message a local client:");
Serial.println(in.message);
//Echo back;
wifi.send(in.channel, "Echo:", false);
wifi.send(in.channel, in.message);
nextPing = millis() + 10000;
}
//If you want do disconnect from the server use:
// wifi.disconnectFromServer();
}
//Listen for serial input from the console
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
When I execute, the serial monitor shows:
OK ARFa C⸮C⸮j⸮H⸮AT+AWJAP="RPi",#raspberry" WIFI DISCONNECT WIFI
CONNECVED WIFI GOT IP
OK AT+CIFSR
+CIFSR:STAIP,"192.168.50.13"
+CIFQR:STAMAC,"2c:3a:eAT+CIPSTART=4,"TCP","192.0n8.50.1",121l
Link type ERROR
Raspberry Pi's ISC DHCP server:
wlan0: STA 2c:3a:e8:4e:bf:70 RADIUS: starting accounting session
5A3B2C85-000000E9 wlan0: STA 2c:3a:e8:4e:bf:70 WPA: pairwise key
handshake completed (RSN)
I also referred to this SO thread with no luck.
Some assumptions because you have not given the info:
Arduino IDE >=1.85
ESP8266 Community package >=2.41
ESP Module ESP8266-12E with latest AT firmware
if that is the case and these fragments (enclosed by X X) are no typos
+CIFQR:STAMAC,"2c:3a:eXAT+CIPSTART=4,"TCP","192.0XnX8.50.1",121l
this leaves the following points to check
hardware connectors - serial connectors between arduino and esp module
stable power source 3.3V for the ESP module
Sure this is ok - but just in case and as reference for other readers
serial speed - try to increase from 9600 to 57600 or even to 115200 baud
These pieces of code should be in the setup() and not in the loop()
//Make sure the esp8266 is started..
if (!wifi.isStarted())
wifi.begin();
//Send what you typed in the arduino console to the server
static char buf[20];
Code processing
nextPing = millis() + 10000;
at the end of
if (in.hasData) {
might lead to interuptions in the communication
Reason due to the processing of code this might trigger at an unwanted point
I am kinda new to the lwip stack. I'm trying to send some data over UDP protocol from my development board to my pc. And using ethernet cable between the two of them.
I gave an ip address to my server(source-board), which is 192.168.1.75:88. And the ip address of my computer is 192.168.1.2:90. When I set this configuration and run the program, I can sniff nothing with wireshark, I mean there is no udp package exchange at all. But when I change all destination adress to 255.255.255.255 or 0.0.0.0, I can sniff some packages.
Why can't I send udp packages to the ip address that I want?
Main.c
int main(void)
{
#define dst_port 88
#define src_port 90
#ifdef SERIAL_DEBUG
DebugComPort_Init();
#endif
LCD_LED_Init();
ETH_BSP_Config();
LwIP_Init();
IP4_ADDR(&dstaddr, 0, 0, 0, 0);
IP4_ADDR(&srcaddr, 192, 168, 1, 75);
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
#ifdef USE_DHCP
/* Start DHCPClient */
xTaskCreate(LwIP_DHCP_task, "DHCPClient", configMINIMAL_STACK_SIZE * 2, NULL,DHCP_TASK_PRIO, NULL);
#endif
/* Start toogleLed4 task : Toggle LED4 every 250ms */
xTaskCreate(ToggleLed4, "LED4", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
xTaskCreate(SendUDP, "UDP", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
/* Start scheduler */
vTaskStartScheduler();
for( ;; );
}
SendUDP Task
void SendUDP(void * pvParameters)
{
while(1)
{
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof((str)), PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = sizeof((str));
udp_sendto(pcb, pb, &dstaddr, dst_port);
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
vTaskDelay(1000);
}
}
I figured this out about a week ago, but I couldn't post the answer to here.
First of all, there is an ip defining in main.h, like
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 15
and this configurations being use in netconf.h
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
that's why server's ip adress is always 192.168.1.15.
And the second, I just started to use netconn API instead of raw API, this is way much easier than raw API. And this is my new SendwithUDP function, which is working perfect.
void SendwithUDP(uint16_t *veri, uint8_t length)
{
while(1)
{
if(((EventFlags.udp) && (1<<0)) == (1<<0))
{
STM_EVAL_LEDToggle(LED3);
sendconn = netconn_new( NETCONN_UDP );
netconn_bind(sendconn, IP_ADDR_ANY, src_port );
netconn_connect(sendconn, &clientAddr, 150);
sendbuf = netbuf_new();
data =netbuf_alloc(sendbuf, 2*length);
memcpy(data, veri, 2*length);
netconn_send(sendconn, sendbuf);
netbuf_free(sendbuf);
netbuf_delete(sendbuf);
netconn_disconnect(sendconn);
netconn_delete(sendconn);
vTaskDelay(10);
}
}
}