pointer problems..

hi

I have a structure containing a byte array declared as uint8_t weight[9].

its an ascii string containing a weight in the format nnn.nnKg

I want to put it in a container for a serial.print command to start with but am having problems Serial.print( weight );

but loading my weight variable isnt working?? char* weight = mystruc->weight ;

Post code.

AWOL: Post code.

no its a mass value,

if im understanding correctly i want a char type pointer to point to my null terminated byte/uint8_t array of asciil values in order to pass to the serial print command. once i have the info in a form i can work with i will be doing other stuff too ;) the error generated is error: invalid conversion from 'const uint8_t*' to 'char*'

Post the complete code that you are using and describe the errors.

filk:

AWOL: Post code.

no its a mass value,

No, post [u]your[/u] code, otherwise we have no idea what you're talking about.

Sorry, new here and suffering from tunnel vision. im trying to modify the scales example from the USB host shield2.0 library.

the example compiled and loaded pre my edits..

the example interfaces with a set scales that output a byte stream which needs decoding.

MY scales output a stream of ascii characters

the original example uses this structure to capture the scale output struct ScaleEventData { uint8_t reportID; //must be 3 uint8_t status; uint8_t unit; int8_t exp; //scale factor for the weight uint16_t weight; // };

I have substituted my own structure

/* input data report */ struct ScaleEventData { uint8_t reportID; // scale ID uint8_t status; // Stability "S" stable "U" unstable uint8_t sError; // Scale Error "N" no error ???? no clue to what errors could be?? uint8_t wType[3]; // Weight Type "G/W" (Gross weight) expected value uint8_t weight[9]; // weight value

};

the data looks like this in a terminal emulator on the puter

Captured output via putty: 0UNG/W+ 84.55kg 0UNG/W+ 83.65kg 0UNG/W+ 83.05kg 0UNG/W+ 72.30kg 0UNG/W+ 64.15kg 0UNG/W+ 43.70kg 0UNG/W+ 23.05kg 0UNG/W+ 8.70kg 0UNG/W+ 7.85kg 0UNG/W+ 6.70kg

the crucial code in the doit all func is

     char buf[10];
      double weight = evt->weight * pow( 10, evt->exp );
      
         
                        
         Serial.print(F("Weight: "));
                Serial.print( weight );
                Serial.print(F(" "));
                Serial.println( UNITS[ evt->unit ]);

embeded in a huge switch statement handling error codes

i reduced it to

void ScaleEvents::OnScaleChanged(const ScaleEventData *evt)
{

      char* weight = evt->weight ;
      
         
                        
         Serial.print(F("Weight: "));
                Serial.print( weight );




}

but am getting the compile error invalid conversion from 'const uint8_t*' to 'char*'

this is all contained within .h and .cpp files in the project folder, the struture definition is in the .h file and the do-it function/method is in the cpp file..

it seemed like a good place to start getting my head into gear with it all ..

Please, quit the snippets and hand-waving. Post your code.

scale_rptparser.ccp

/* Parser for standard HID scale (usage page 0x8d) data input report (ID 3) */ 
#include "scale_rptparser.h"

const char* UNITS[13] = {
    "units",        // unknown unit
    "mg",           // milligram
    "g",            // gram
    "kg",           // kilogram
    "cd",           // carat
    "taels",        // lian
    "gr",           // grain
    "dwt",          // pennyweight
    "tonnes",       // metric tons
    "tons",         // avoir ton
    "ozt",          // troy ounce
    "oz",           // ounce
    "lbs"           // pound
};

ScaleReportParser::ScaleReportParser(ScaleEvents *evt) :
	scaleEvents(evt)
{}

void ScaleReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
	bool match = true;

	// Checking if there are changes in report since the method was last called
	for (uint8_t i=0; i<RPT_SCALE_LEN; i++) {
		if( buf[i] != oldScale[i] ) {
			match = false;
			break;
		}
  }
  	// Calling Game Pad event handler
	if (!match && scaleEvents) {
		scaleEvents->OnScaleChanged((const ScaleEventData*)buf);

		for (uint8_t i=0; i<RPT_SCALE_LEN; i++) oldScale[i] = buf[i];
	}
}

ScaleEvents::ScaleEvents( Max_LCD* pLCD ) :
	
	pLcd( pLCD )

{}

void ScaleEvents::LcdPrint( const char* str )
{
	
	while( *str ) {
		
		pLcd->write(	*str++ );
		
	}
}

void ScaleEvents::OnScaleChanged(const ScaleEventData *evt)
{
	
	pLcd->clear();
  pLcd->home();
  pLcd->setCursor(0,0);
	
		
      char* weight = evt->weight ;
      
      	
                        
      	Serial.print(F("Weight: "));
				Serial.print( weight );
				Serial.print(F(" "));
			
			
			
	
}

scale_rptparser.h

#if !defined(__SCALERPTPARSER_H__)
#define __SCALERPTPARSER_H__

#include <Max_LCD.h>
#include <hid.h>

/* Scale status constants */

#define STABLE 0x53        	//"S" for stable
#define UNSTABLE 0x55		// "U" Unstable



/* input data report */
struct ScaleEventData
{
  uint8_t reportID;	// scale ID - should be "A"
  uint8_t status;	// Stability "S" stable "U" unstable
  uint8_t sError;	// Scale Error "N" no error  ???? no clue to what errors could be??	
  uint8_t wType[3];	// Weight Type "G/W" (Gross weight) expected value
  uint8_t weight[9];	// weight value
  
};

class ScaleEvents
{
	
	Max_LCD*	pLcd;
	
	void LcdPrint( const char* str );
	
public:
	
	ScaleEvents( Max_LCD* pLCD );
	
	virtual void OnScaleChanged(const ScaleEventData *evt);
};

#define RPT_SCALE_LEN	sizeof(ScaleEventData)/sizeof(uint8_t)

class ScaleReportParser : public HIDReportParser
{
	ScaleEvents		*scaleEvents;

  uint8_t oldScale[RPT_SCALE_LEN];

public:
	ScaleReportParser(ScaleEvents *evt);

	virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __SCALERPTPARSER_H__

Myscales.ino

/* Digital Scale Output. Written for Stamps.com Model 510  */
/* 5lb Digital Scale; any HID scale with Usage page 0x8d should work */

#include <hid.h>
#include <hiduniversal.h>
#include <usbhub.h>

#include "scale_rptparser.h"
// Satisfy IDE, which only needs to see the include statment in the ino.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif

USB                                             Usb;
USBHub                                          Hub(&Usb);
HIDUniversal                                    Hid(&Usb);
Max_LCD                                       LCD(&Usb);
ScaleEvents                                  ScaleEvents(&LCD);
ScaleReportParser                            Scale(&ScaleEvents);

void setup()
{
  Serial.begin( 115200 );
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  Serial.println("Start");

  if (Usb.Init() == -1)
      Serial.println("OSC did not start.");

    // set up the LCD's number of rows and columns:
    LCD.begin(16, 2);
    LCD.clear();
    LCD.home();
    LCD.setCursor(0,0);
    LCD.write('R');

  delay( 200 );

  if (!Hid.SetReportParser(0, &Scale))
      ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );
}

void loop()
{
    Usb.Task();
}

Im running the arduino/sheild without a lcd so am only getting output from the serial monitor or will be attempting to once it compiles.

the original .h and ccp files are

/* Parser for standard HID scale (usage page 0x8d) data input report (ID 3) */ 
#include "scale_rptparser.h"

const char* UNITS[13] = {
    "units",        // unknown unit
    "mg",           // milligram
    "g",            // gram
    "kg",           // kilogram
    "cd",           // carat
    "taels",        // lian
    "gr",           // grain
    "dwt",          // pennyweight
    "tonnes",       // metric tons
    "tons",         // avoir ton
    "ozt",          // troy ounce
    "oz",           // ounce
    "lbs"           // pound
};

ScaleReportParser::ScaleReportParser(ScaleEvents *evt) :
	scaleEvents(evt)
{}

void ScaleReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
	bool match = true;

	// Checking if there are changes in report since the method was last called
	for (uint8_t i=0; i<RPT_SCALE_LEN; i++) {
		if( buf[i] != oldScale[i] ) {
			match = false;
			break;
		}
  }
  	// Calling Game Pad event handler
	if (!match && scaleEvents) {
		scaleEvents->OnScaleChanged((const ScaleEventData*)buf);

		for (uint8_t i=0; i<RPT_SCALE_LEN; i++) oldScale[i] = buf[i];
	}
}

ScaleEvents::ScaleEvents( Max_LCD* pLCD ) :
	
	pLcd( pLCD )

{}

void ScaleEvents::LcdPrint( const char* str )
{
	
	while( *str ) {
		
		pLcd->write(	*str++ );
		
	}
}

void ScaleEvents::OnScaleChanged(const ScaleEventData *evt)
{
	
	pLcd->clear();
  pLcd->home();
  pLcd->setCursor(0,0);
	
	if( evt->reportID != 3 ) {
		
		const char inv_report[]="Invalid report!";
		
		Serial.println(inv_report);
		LcdPrint(inv_report);
		
		return;
		
	}//if( evt->reportID != 3...
	
	switch( evt->status ) {
		
		case REPORT_FAULT: 
			Serial.println(F("Report fault"));
			break;
			
		case ZEROED:
			Serial.println(F("Scale zero set"));
			break;
			
		case WEIGHING: {
			
			const char progress[] = "Weighing...";
			Serial.println(progress);
			LcdPrint(progress);
			break;
		}
		
		case WEIGHT_VALID: {
			
			char buf[10];
      double weight = evt->weight * pow( 10, evt->exp );
      
      	
                        
      	Serial.print(F("Weight: "));
				Serial.print( weight );
				Serial.print(F(" "));
				Serial.println( UNITS[ evt->unit ]);
				
				LcdPrint("Weight: ");
				dtostrf( weight, 4, 2, buf );
				LcdPrint( buf ); 
				LcdPrint( UNITS[ evt->unit ]);
			
			break;
			
		}//case WEIGHT_VALID...
			
		case WEIGHT_NEGATIVE: {
			
			const char negweight[] = "Negative weight";
			Serial.println(negweight);
			LcdPrint(negweight);
			break;
		}
			
		case OVERWEIGHT: {
		
			const char overweight[] = "Max.weight reached";
			Serial.println(overweight);
			LcdPrint( overweight );
			break;
		}
		
		case CALIBRATE_ME:
			
			Serial.println(F("Scale calibration required"));
			break;
			
		case ZERO_ME:
			
			Serial.println(F("Scale zeroing required"));
			break;
			
		default:
			
			Serial.print(F("Undefined status code: "));
			Serial.println( evt->status );
			break;	
			
	}//switch( evt->status...

}
#if !defined(__SCALERPTPARSER_H__)
#define __SCALERPTPARSER_H__

#include <Max_LCD.h>
#include <hid.h>

/* Scale status constants */
#define REPORT_FAULT 0x01
#define ZEROED 0x02
#define WEIGHING 0x03
#define WEIGHT_VALID 0x04
#define WEIGHT_NEGATIVE 0x05
#define OVERWEIGHT 0x06
#define CALIBRATE_ME 0x07
#define ZERO_ME 0x08

/* input data report */
struct ScaleEventData
{
  uint8_t reportID;	//must be 3
  uint8_t status;
  uint8_t unit;		
  int8_t exp;			//scale factor for the weight
  uint16_t weight;	//
};

class ScaleEvents
{
	
	Max_LCD*	pLcd;
	
	void LcdPrint( const char* str );
	
public:
	
	ScaleEvents( Max_LCD* pLCD );
	
	virtual void OnScaleChanged(const ScaleEventData *evt);
};

#define RPT_SCALE_LEN	sizeof(ScaleEventData)/sizeof(uint8_t)

class ScaleReportParser : public HIDReportParser
{
	ScaleEvents		*scaleEvents;

  uint8_t oldScale[RPT_SCALE_LEN];

public:
	ScaleReportParser(ScaleEvents *evt);

	virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __SCALERPTPARSER_H__

pressed post early.

the difference between the scales read in the example sketch and the scales im using is the format of the output.

the original example reads in a defined number of bytes:

03 04 0B FF 00 00

03 – this is the report ID, always 3 04 – status, in this case meaning the report containing correct weight 0B – unit of measurement, in this case ounces FF – exponent to the base of 10 to make a multiplier for the weight value contained in the next 2 bytes. It is a signed integer, in this case -1, which means the weight needs to be divided by 10 00 00 – weight, in this case zero

Mine chuck out an ascii string 15 characters long

0UNG/W+ 84.55kg 0UNG/W+ 83.65kg 0UNG/W+ 83.05kg 0UNG/W+ 72.30kg 0UNG/W+ 64.15kg 0UNG/W+ 43.70kg 0UNG/W+ 23.05kg 0UNG/W+ 8.70kg