Having problem with float numbers

Programmable Converter for RS-232 to CAN
Post Reply
sakho1
Posts: 1
Joined: Mon 15. May 2017, 09:22

Having problem with float numbers

Post by sakho1 » Mon 15. May 2017, 10:24

Hi,
I have to develop a software to control an balance using PCAN RS232. The balance can be remotely control by using ASCI character in my software. And after the balance having the commands , it will send the weigh as ASCI data, as can see in the picture.
I use PCAN view and then CANape to view the data after transforming the ASCI data. But the problem is the number sent by the balance is float and I don't how to transmit/receive that number in CAN trame and then display it in PCAN view and CANape.
NB: PCAN view version 4.1.1.463
OS Windows 7
In the table, B means Blank.

Code: Select all

#include "datatypes.h"
#include "can.h"
#include "can_user.h"
#include "hardware.h"
#include "crc_data.h"
#include "serial.h"
#include "ser_user.h"
#include "eeprom.h"
#include "systime.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

CANMsg_t TxMsg1;
CANMsg_t TxMsg2;
CANMsg_t TxMsg3;
CANMsg_t TxMsg4;
static u32_t      outbuf;

// identifier is needed by PCANFlash.exe -> do not delete
const b8_t Ident[] __attribute__ ((used)) = { "PCAN-RS-232"};


// info data for PCANFlash.exe
const crc_array_t  C2F_Array __attribute__((section(".C2F_Info"), used)) = {

	.Str = CRC_IDENT_STRING,
	.Version = 0x21,
	.Day = 5,
	.Month = 5,
	.Year = 6,
	.Mode = 1,

	// crc infos are patched during link time by flash.ld
	// crc value is patched by PCANFlash.exe
};

// variables for cyclic message transmission
static SYSTIME_t  LastCycleMsg;
static CANMsg_t  CycleMsg;
// variables for LED toggle
static u8_t LED_toggleCAN1;

b8_t serialDataRead[40] = {0};
//int digit = 0;
u8_t str_serial[40] = {0};
u8_t bytesRead = 0;
u8_t nbData = 0;


int i = 0;

//
u32_t dataSendCounter;
u8_t select;

u8_t nbChiffre = 0;
u8_t flag_negative = 0;

int Space = 0;
int Digit = 0;

s16_t tmp = 0;

u8_t flag_point = 0;
u8_t flag_invalide = 0;



// main_greeting()
// transmitt a message at module start
static void  main_greeting ( void)
{
	CANMsg_t  Msg;
	

	Msg.Id   = 0x123;
	Msg.Len  = 8;
	Msg.Type = CAN_MSG_STANDARD;
	
	// we will read 8 bytes from eeprom address 100h
	EEPROM_Read ( 0x100, &Msg.Data8[0], 8);
	
	// Send Msg
	CAN_UserWrite ( CAN_BUS1, &Msg);
}




// main()
// entry point from crt0.S
int  main ( void)
{
	
	// init hardware
	HW_Init();
	
	
	// init CAN
	CAN_UserInit();
	
	//
	SYSTIME_Init();
	
	// init serial
	SER_UserInit();
	
	
	// Set green LEDs for CAN1
	HW_SetLED ( HW_LED_CAN1, HW_LED_GREEN);
	
	
	// send the greeting message
	main_greeting();
	
	
	// main loop
	while ( 1)
	{
		CANMsg_t  RxMsg, TxMsg;
		//SYSTIME_t  timenow;

		// process messages from CAN1
		if ( CAN_UserRead ( CAN_BUS1, &RxMsg) != 0)
		{
			// message received from CAN1
			LED_toggleCAN1 ^= 1;

			if ( LED_toggleCAN1)
			{
				HW_SetLED ( HW_LED_CAN1, HW_LED_ORANGE);
			}
			
			else
			{
				HW_SetLED ( HW_LED_CAN1, HW_LED_GREEN);
			}
			
			
			// catch ID 00000250h to send on serial as ascii
			
			if ( RxMsg.Id == 0x250  &&  RxMsg.Type == CAN_MSG_STANDARD && RxMsg.Data8[0] == 0x77)
				{
				SER_ResetTX(SER_PORT1);
				SER_Write ( SER_PORT1, "w", 1);
				//select = 3 ;				
				}
			if(RxMsg.Id == 0x250  &&  RxMsg.Type == CAN_MSG_STANDARD && RxMsg.Data8[0] == 0x74)
				{
					SER_ResetTX(SER_PORT1);
					SER_Write ( SER_PORT1, "t", 1);
				}
			if(RxMsg.Id == 0x250  &&  RxMsg.Type == CAN_MSG_STANDARD && RxMsg.Data8[0] == 0x75)
				{
				outbuf = 1; // and write this with 
				HW_SetDOUT (&outbuf); // then the rightmost port is set (=Dout-0)
				}
			if(RxMsg.Id == 0x250  &&  RxMsg.Type == CAN_MSG_STANDARD && RxMsg.Data8[0] == 0x76)
				{
				outbuf = 0; // and write this with 
				HW_SetDOUT (&outbuf); // then the rightmost port is set (=Dout-1)
				}
			
			// catch ID 611h to send on serial as binary
			else if ( RxMsg.Id == 0x211  &&  RxMsg.Type == CAN_MSG_STANDARD)
			{
				SER_Write ( SER_PORT1, &RxMsg.Data8[0], RxMsg.Len);
			}
			
			// catch ID 48Ah from CAN1 to save new data to the eeprom
			else if ( RxMsg.Id == 0x48A  &&  RxMsg.Type == CAN_MSG_STANDARD)
			{
				// write new data to eeprom. Next power cycle will show a modified
				// greeting message.
				EEPROM_Write ( 0x100, &RxMsg.Data8[0], 8);
				
				EEPROM_FlushCache();
			}
			
			else
			{
				// copy message and modify
				TxMsg.Id   = RxMsg.Id + 2;
				TxMsg.Type = RxMsg.Type;
				TxMsg.Len  = RxMsg.Len;
				
				// copy data
				TxMsg.Data32[0] = RxMsg.Data32[0];
				TxMsg.Data32[1] = RxMsg.Data32[1];
				
				// overwrite byte 0
				TxMsg.Data8[0] = 0x55;
			
				// echo back the message   for debug
			//	CAN_UserWrite ( CAN_BUS1, &TxMsg);
			}
		//	if (SYSTIME_DIFF (dataSendCounter, SYSTIME_NOW) >= 10 ){
				
				switch(select){
					case 0:{
						TxMsg1.Id = 0x200;					//premiere parti du message
						TxMsg1.Type = CAN_MSG_STANDARD;
						TxMsg1.Len = 8;
						CAN_UserWrite ( CAN_BUS1, &TxMsg1);
						break;
						}
						
					case 1:{
						TxMsg2.Id = 0x201;					//deuxieme parti du message
						TxMsg2.Type = CAN_MSG_STANDARD;
						TxMsg2.Len = 8;
						CAN_UserWrite ( CAN_BUS1, &TxMsg2);
						break;
					}
					
					case 2:{
						TxMsg3.Id = 0x202;					//Nombre d'octet lu
						TxMsg3.Type = CAN_MSG_STANDARD;
						TxMsg3.Len = 2;
						CAN_UserWrite ( CAN_BUS1, &TxMsg3);
						break;
					}
					
					case 3:{
						
							TxMsg4.Id = 0x206;	// Balance 4
						TxMsg4.Type = CAN_MSG_STANDARD;
						TxMsg4.Len = 8;
						//TxMsg4.Data32[0] = poids;
						CAN_UserWrite ( CAN_BUS1, &TxMsg4);
						break;
					}
					
					default :{
						break;
							}
				}
				//select++; // seulement pour debug
				select = 3 ;
			
	
					SER_Read(SER_PORT1, &serialDataRead[0], 18, &bytesRead );
					nbData = bytesRead;
					for(i=0;i<=bytesRead;i++)
						{
						if(i<8){
							TxMsg1.Data8[i] = serialDataRead[i];
								}
						else if((i>7) && (i<16))
								{
							TxMsg2.Data8[i-8] = serialDataRead[i];
								}
						else	
								{
							TxMsg3.Data8[i-16] = serialDataRead[i];
								}
						str_serial[i]= serialDataRead[i];
						if (str_serial[i]== 0x2D)
								{
								flag_negative = 1;
								Space = 1;
								//Digit--;
								}
								else
								{
								//flag_negative = 0;
								}
								
						}
						for(i = 1; i <=18; i++)
						{
						if(serialDataRead[i] == 0X20 && Digit == 0)
						{
						Space ++;
						}
						if(serialDataRead[i] > 0x2F && serialDataRead[i] < 0x40)
						{
						Digit ++ ;
						}
						if(serialDataRead[i] == 0x2E)
						{
						flag_point = i ;
						}
						}
						
						
				switch(Digit){ 
				
				       case 5:
					   {
						tmp = 0;
					    tmp = (serialDataRead[Space+1]- 48)* 10000 ;	
					    tmp = tmp  + (serialDataRead[Space+2]- 48) * 1000;	
					    tmp = tmp  + (serialDataRead[Space+3]- 48) * 100;
						tmp = tmp  + (serialDataRead[Space+4]- 48) * 10;						
					    tmp = tmp  + (serialDataRead[Space+5]- 48) * 1;
					  	break;
					   }
					   case 4:
					   {
					   tmp =  0 ;	
					   tmp = tmp + ((serialDataRead[Space+1]- 48) * 1000 );	
					   tmp = tmp + (serialDataRead[Space+2]- 48) * 100;	
					   tmp = tmp + (serialDataRead[Space+3]- 48) * 10;	
					   tmp = tmp + (serialDataRead[Space+4]- 48) * 1;
					   break;
					   }
					   case 3:
					   {
					   tmp =  0 ;	
					   tmp = (serialDataRead[Space+1]- 48) * 100;	
					   tmp = tmp + (serialDataRead[Space+2]- 48) * 10;	
					   tmp = tmp + (serialDataRead[Space+3]- 48) * 1;
					   break;
					   }
					   case 2:
					   {	
					   tmp =  0;	
					   tmp = (serialDataRead[Space+1]- 48) * 10;	
					   tmp = tmp + (serialDataRead[Space+2]- 48) * 1;
					   break;
					   }
					   case 1:
					   {
					   tmp = 0;
					   tmp = (serialDataRead[Space+1]- 48);
					   break;
					   }
					   default:
							break;
				}
				TxMsg4.Data8[0]  = flag_negative;
				if(flag_negative == 1)
					   {
						tmp =  -tmp ;
						flag_negative = 0;
					   }
				//TxMsg4.Data8[0]  = flag_negative;
				TxMsg4.Data8[1]  = Digit;
                TxMsg4.Data8[2]  = Space;
				flag_invalide = serialDataRead[0];
				if ( (Space + Digit) != 10)
				{
				flag_invalide = 0x01;	
				}	
				if (Digit > 5 )
				{
				flag_invalide = 0x01;	
				}
				if ( flag_invalide == 0x20)
					{
					//TxMsg4.Data16[3] = tmp;
					}
				Space = 0;
				Digit = 0;
				for (i = 1 ;i <= 40; i++)
				{
				serialDataRead[i]= 0;
				str_serial[i]= 0 ;
				}
				 
		//	}
			
		}
		
	}
}
Attachments
weigh of object
weigh of object
balance.JPG (430.3 KiB) Viewed 5929 times
ASCI character sent by the balance (18 bytes)
ASCI character sent by the balance (18 bytes)
asci_charact.PNG (10.39 KiB) Viewed 5929 times

User avatar
PEAK-Support
Sales & Support
Sales & Support
Posts: 1646
Joined: Fri 10. Sep 2010, 19:34

Re: Having problem with float numbers

Post by PEAK-Support » Tue 16. May 2017, 18:07

Your problem is a C/C++ problem and have nothing to do with the CAN units from us.
Maybe you better post your problem in a C/C++ forum.
But it is not so hard - you are receiving a ASCII String via RS232 including a float number and copy it to the max. 8 Databytes (CAN Frame). Use a string to float conversion (see atof(..) and after that copy the content of the pointer(+4) to your databytes to post also 4 bytes of the float value over CAN. You also could simply send the ASCII Value - then you see the ASCII values on the CAN Bus (readable float like "12345.45")
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

Post Reply