When opening a file called output, for some reason tests get an error 472 bytes in 1 blocks are still reachable in loss record 1 of 1. The program works okay, it is only a memory error that needs to be fixed. The goal of the program is to take a .raw file, scan it 512 bytes at a time for a .jpg file header at the start of the block and recover 50 .jpg pictures (they go one after the other). Error happens on the line where the comment is the error. What do I do to make this mistake go away? I've tried anything I can, nothing seems to help
int x = 0;
char buffer[8];
uint8_t bytes[512];
FILE *output;
//Going through the input file 512 bytes at a time
while (fread(bytes, 1, 512, input))
{
//Checking for .jpg header
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff && ((bytes[3] & 0xf0) == 0xe0))
{
if (x > 0)
{
//Closing the output file if I used it before
fclose(output);
}
//Creating file name string
sprintf(buffer, "%03i.jpg", x);
x++;
//Creating and opening a file to append to
output = fopen(buffer, "a"); //472 bytes in 1 blocks are still reachable in loss record 1 of 1
//Writing the header to the output file
fwrite(bytes, 1, 512, output);
}
else if (x > 0)
{
//Appending bytes until a new header is found
fwrite(bytes, 1, 512, output);
}
}
Setup
I have two nodes connected to one CAN bus. The first node is a black-box, controlled by some real-time hardware. The second node is a Linux machine with attached PEAK-USB CAN controller:
+--------+ +----------+
| HW CAN |--- CAN BUS ---| Linux PC |
+--------+ +----------+
In order to investigate some problem related to occasional frame loss I want to mimic the CAN arbitration process. To do that I am setting the CAN bit-rate to 125Kb/s and flooding it with random CAN frames with 1ms delay, controlling the bus load with canbusload from can-utils. I also monitor CAN error frames running candump can0,0~0,#ffffffff and the overall can statistics with ip -s -d link show can:
26: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
pcan_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0
RX: bytes packets errors dropped overrun mcast
120880 15110 0 0 0 0
TX: bytes packets errors dropped carrier collsns
234123 123412 0 0 0 0
Problem
Now the problem is that the given setup works for hours with zero collisions (arbitration) or any other kind of error frames when the load is at 99%. When I reduce the delay to increase the bus load write(2) fails with either "ENOBUFS 105 No buffer space available" or "EAGAIN 11 Resource temporarily unavailable" - the actual error depends on whether I modify the qlen parameter or set to to defaults.
As I understand it, the load I put is either not enough or too much. What would be the right way to make two nodes enter the arbitration? A successful result would be a received CAN error frame corresponding to the CAN_ERR_LOSTARB constant from can/error.h and a value of collsns other than 0.
Source code
HW Node (Arduino Due with CAN board)
#include <due_can.h>
CAN_FRAME input, output;
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
Serial.println("start");
// Can0.begin(CAN_BPS_10K);
Can0.begin(CAN_BPS_125K);
// Can0.begin(CAN_BPS_250K);
output.id = 0x303;
output.length = 8;
output.data.low = 0x12abcdef;
output.data.high = 0x24abcdef;
}
// the loop function runs over and over again forever
void loop() {
Can0.sendFrame(output);
Can0.read(input);
delay(1);
}
Linux node
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main(int argc, char *argv[])
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
const char *ifname = "can0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
printf("%s at index %d\n", ifname, ifr.ifr_ifindex);
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
frame.can_id = 0x304;
frame.can_dlc = 2;
frame.data[0] = 0x11;
frame.data[1] = 0x22;
int sleep_ms = atoi(argv[1]) * 1000;
for (;;) {
nbytes = write(s, &frame, sizeof(struct can_frame));
if (nbytes == -1) {
perror("write");
return 1;
}
usleep(sleep_ms);
}
return 0;
}
From the documentation subsection 4.1.2 RAW socket option CAN_RAW_ERR_FILTER, it says that the errors are by default not activated which is why the lost arbitration field in ip was not increasing.
In order to toggle on all the errors, you need to add those two lines :
can_err_mask_t err_mask = CAN_ERR_MASK;
setsockopt(socket_can, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask));
But this feature is not available for all drivers and devices because it requires from the hardware to have a loopback mode. In the case of the PEAK-USB, it seems that if the version of the firmware from the device is less than 4.x, there is no loopback [source]. Thus SocketCAN won't be able to detect lost arbitration.
I am trying to run the test code for the OLED display simulation on the DSP board TMSC320C5515 eZdsp UsbStick, variant "USBSTK5515".
I have included the bsl folder and needed included libraries and header files through the spectrum website. Now the problem is that I am being unable to compile; I am getting the error:
**** Build of configuration Debug for project OLED ****
"G:\\TheDevelopmentKitCodeComposerv6\\ccsv6\\utils\\bin\\gmake" -k all
'Building file: ../main.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="main.pp" "../main.c"
'Finished building: ../main.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_gpio.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_gpio.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_gpio.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_gpio.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_i2c.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_i2c.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_i2c.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_i2c.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_led.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_led.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_led.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_led.c'
' '
'Building target: OLED.out'
'Invoking: C5500 Linker'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 -z -m"OLED.map" --stack_size=0x200 --heap_size=0x400 -i"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/lib" -i"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --reread_libs --display_error_number --warn_sections --xml_link_info="OLED_linkInfo.xml" --rom_model --sys_stacksize=0x200 -o "OLED.out" "./main.obj" "./usbstk5515bsl/bsl/usbstk5515.obj" "./usbstk5515bsl/bsl/usbstk5515_gpio.obj" "./usbstk5515bsl/bsl/usbstk5515_i2c.obj" "./usbstk5515bsl/bsl/usbstk5515_led.obj" "../lnkx.cmd" "../usbstk5515bsl/usbstk5515bsl.lib" -l"libc.a" -l"rts55x.lib"
<Linking>
undefined first referenced
symbol in file
--------- ----------------
_main G:\TheDevelopmentKitCodeComposerv6\ccsv6\tools\compiler\c5500_4.4.1\lib\rts55x.lib<args_main.obj>
error #10234-D: unresolved symbols remain
error #10010: errors encountered during linking; "OLED.out" not built
>> Compilation failure
gmake: *** [OLED.out] Error 1
gmake: Target `all' not remade because of errors.
**** Build Finished ****
And in the problem window :
Description Resource Path Location Type
#10010 errors encountered during linking; "OLED.out" not built OLED C/C++ Problem
#10234-D unresolved symbols remain OLED C/C++ Problem
unresolved symbol _main, first referenced in G:\TheDevelopmentKitCodeComposerv6\ccsv6\tools\compiler\c5500_4.4.1\lib\rts55x.lib<args_main.obj> OLED C/C++ Problem
My Code as downloaded from spectrum website is
/*
* Copyright 2010 by Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*/
/*
* OSD9616 OLED Test
*
*/
#include "usbstk5515.h"
//#include "usbstk5515_led.h"
#include "usbstk5515_i2c.h"
#include "lcd.h"
#include "usbstk5515_gpio.h"
#define OSD9616_I2C_ADDR 0x3C // OSD9616 I2C address
/* ------------------------------------------------------------------------ *
* *
* Int16 OSD9616_send( Uint16 comdat, Uint16 data ) *
* *
* Sends 2 bytes of data to the OSD9616 *
* *
* ------------------------------------------------------------------------ */
Int16 OSD9616_send( Uint16 comdat, Uint16 data )
{
Uint8 cmd[2];
cmd[0] = comdat & 0x00FF; // Specifies whether data is Command or Data
cmd[1] = data; // Command / Data
return USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 2 );
}
/* ------------------------------------------------------------------------ *
* *
* Int16 OSD9616_multiSend( Uint16 comdat, Uint16 data ) *
* *
* Sends multiple bytes of data to the OSD9616 *
* *
* ------------------------------------------------------------------------ */
Int16 OSD9616_multiSend( Uint8* data, Uint16 len )
{
Uint16 x;
Uint8 cmd[10];
for(x=0;x<len;x++) // Command / Data
{
cmd[x] = data[x];
}
return USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, len );
}
/* ------------------------------------------------------------------------ *
* *
* Int16 printLetter(Uint16 l1,Uint16 l2,Uint16 l3,Uint16 l4) *
* *
* Send 4 bytes representing a Character *
* *
* ------------------------------------------------------------------------ */
Int16 printLetter(Uint16 l1,Uint16 l2,Uint16 l3,Uint16 l4)
{
OSD9616_send(0x40,l1);
OSD9616_send(0x40,l2);
OSD9616_send(0x40,l3);
OSD9616_send(0x40,l4);
OSD9616_send(0x40,0x00);
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* Int16 oled_test() *
* *
* Testing function for the OSD9616 display *
* *
* ------------------------------------------------------------------------ */
Int16 oled_test()
{
Int16 i, i2c_err;
Uint8 cmd[10]; // For multibyte commands
/* Initialize I2C */
USBSTK5515_I2C_init( );
/* Initialize LCD power */
USBSTK5515_GPIO_setDirection( 12, 1 ); // Output
USBSTK5515_GPIO_setOutput( 12, 1 ); // Enable 13V
/* Initialize OSD9616 display */
i2c_err = OSD9616_send(0x00,0x00); // Set low column address
i2c_err = OSD9616_send(0x00,0x10); // Set high column address
if(i2c_err) // Don't setup display if not connected
return 1;
OSD9616_send(0x00,0x40); // Set start line address
cmd[0] = 0x00 & 0x00FF; // Set contrast control register
cmd[1] = 0x81;
cmd[2] = 0x7f;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xa1); // Set segment re-map 95 to 0
OSD9616_send(0x00,0xa6); // Set normal display
cmd[0] = 0x00 & 0x00FF; // Set multiplex ratio(1 to 16)
cmd[1] = 0xa8;
cmd[2] = 0x0f;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xd3); // Set display offset
OSD9616_send(0x00,0x00); // Not offset
OSD9616_send(0x00,0xd5); // Set display clock divide ratio/oscillator frequency
OSD9616_send(0x00,0xf0); // Set divide ratio
cmd[0] = 0x00 & 0x00FF; // Set pre-charge period
cmd[1] = 0xd9;
cmd[2] = 0x22;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
cmd[0] = 0x00 & 0x00FF; // Set com pins hardware configuration
cmd[1] = 0xda;
cmd[2] = 0x02;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xdb); // Set vcomh
OSD9616_send(0x00,0x49); // 0.83*vref
cmd[0] = 0x00 & 0x00FF; //--set DC-DC enable
cmd[1] = 0x8d;
cmd[2] = 0x14;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xaf); // Turn on oled panel
/* Fill page 0 */
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+0); // Set page for page 0 to page 5
for(i=0;i<128;i++)
{
OSD9616_send(0x40,0xff);
}
/* Write to page 0 */
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+0); // Set page for page 0 to page 5
for(i=0;i<22;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x7F,0x30,0x0E,0x7F); // N
printLetter(0x41,0x49,0x49,0x7F); // E
printLetter(0x7F,0x06,0x06,0x7F); // M
printLetter(0x3F,0x40,0x40,0x3F); // U
printLetter(0x46,0x29,0x19,0x7F); // R
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x7F,0x30,0x0E,0x7F); // N
printLetter(0x00,0x7F,0x00,0x00); // I
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x7C,0x09,0x0A,0x7C); // A
printLetter(0x63,0x1C,0x1C,0x63); // X
printLetter(0x41,0x49,0x49,0x7F); // E
printLetter(0x01,0x7F,0x01,0x01); // T
for(i=0;i<23;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
/* Fill page 1*/
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+1); // Set page for page 0 to page 5
for(i=0;i<128;i++)
{
OSD9616_send(0x40,0xff);
}
/* Write to page 1*/
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+1); // Set page for page 0 to page 5
for(i=0;i<20;i++)
{
OSD9616_send(0x40,0x00);
}
printLetter(0x41,0x22,0x14,0x7F); // K
printLetter(0x22,0x41,0x41,0x3E); // C
printLetter(0x00,0x7F,0x00,0x00); // I
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x32,0x49,0x49,0x26); // S
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x36,0x49,0x49,0x7F); // B
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x3F,0x40,0x40,0x3F); // U
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x06,0x09,0x09,0x7F); // P
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x3E,0x41,0x41,0x7F); // D
printLetter(0x43,0x4D,0x51,0x61); // Z
printLetter(0x10,0x58,0x58,0x30); // e
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x00,0x7F,0x00,0x00); // 1
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x22,0x41,0x41,0x3E); // C
for(i=0;i<23;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
/* Set vertical and horizontal scrolling */
cmd[0] = 0x00;
cmd[1] = 0x29; // Vertical and Right Horizontal Scroll
cmd[2] = 0x00; // Dummy byte
cmd[3] = 0x00; // Define start page address
cmd[4] = 0x03; // Set time interval between each scroll step
cmd[5] = 0x01; // Define end page address
cmd[6] = 0x01; // Vertical scrolling offset
OSD9616_multiSend( cmd, 7 );
OSD9616_send(0x00,0x2f);
/* Keep first 8 rows from vertical scrolling */
cmd[0] = 0x00;
cmd[1] = 0xa3; // Set Vertical Scroll Area
cmd[2] = 0x08; // Set No. of rows in top fixed area
cmd[3] = 0x08; // Set No. of rows in scroll area
OSD9616_multiSend( cmd, 4 );
return 0;
}
Probably a bit late now, but I think the problem is that you don't have a main function defined to call any of the functions, hence message "unresolved symbol _main".
Not familiar with that particular board, but the example that came with my ezdspc5535 had 2 c files, one of which had a main and examples of how to call the functions in oled_test.c
My code (below) is working if I use QoS 0. But for QoS 1 or QoS 2. MQTTClient_publishMessage(...) failed.
Am I missing any configuration? Or, is it because I am using free XIvely account?
I use Paho API.
------------------------------- start of cut -------------------------------------
/**
* #file
*
* Paho MQ Client API to Xively mqtt broker
*
*/
enter code here
#include "MQTTClient.h"
#include <stdlib.h>
void usage()
{
printf("Usage: speicify QoS\n");
printf(" turn on bulb -> ka_pub Qos 1 1\n");
printf(" turn off bulb -> ka_pub Qos 1 0\n");
printf(" send 7 to led -> ka_pub Qos 2 7\n");
printf(" send 2 to led -> ka_pub Qos 2 2\n");
}
int main(int argc, char** argv)
{
int rc = 0;
if (argc < 3) {
usage();
exit (0);
}
char TOPIC[250] ; // given enough space first to avoid malloc
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int QoS = atoi(argv[1]);
if (argv[2][0] == '1') {
strcpy(TOPIC, BULB_TOPIC);
conn_opts.username = BULB_API_KEY ;
conn_opts.password = "" ; // will be ignored
} else
if (argv[2][0] == '2') {
strcpy(TOPIC, LED_TOPIC) ;
conn_opts.username = LED_API_KEY ;
conn_opts.password = "" ; // will be ignored
} else {
printf("Bad arg\n");
usage();
exit (0);
}
setenv("MQTT_C_CLIENT_TRACE", "ON", 1); // same as 'stdout'
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1); //ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM
MQTTClient_create(&client, XIVELY_END_URL, "test", MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);
//conn_opts.keepAliveInterval = 20; // init to 60
//conn_opts.cleansession = 1; // default 1, will clean previous msg in server
conn_opts.reliable = 0 ; //default 1, only 1 can in-flight, 0 - allow 10 msg
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);
}
// prepare publish msg
char tmsg[250] ; // check max 250 boundary later
if (argv[2][0] == '1')
sprintf(tmsg, "{\"id\":\"switch\",\"current_value\":\"%c\"}", argv[3][0]);
else
sprintf(tmsg, "{\"id\":\"num\",\"current_value\":\"%c\"}", argv[3][0]) ;
int tmsg_len = strlen(tmsg);
pubmsg.payload = &tmsg[0] ;
pubmsg.payloadlen = tmsg_len; //mlen
pubmsg.qos = QoS;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
//MQTTClient_publish(client, TOPIC, pubmsg.payloadlen, pubmsg.payload,
// pubmsg.qos, pubmsg.retained, &token);
rc = MQTTClient_waitForCompletion(client, token, 100000);
printf("Finish publish for TOPIC: %s, QoS: %d, msg of '%s'\n", TOPIC, pubmsg.qos, (char *) pubmsg.payload);
if (rc == 0)
MyLog(LOGA_INFO, "verdict pass");
else
MyLog(LOGA_INFO, "verdict fail");
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}
------------------------------- end of cut -------------------------------------
I don't believe Xively supports QoS>0.
I am currently trying some simple (ready) programs from Arduino examples regardin the ethernet shield. I am still getting no result. Am always receiving that I am not connected or a blank serial monitor. Does anyone knows why? I think I am connected to the DHCP since i am on the DHCP list of my router
<#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
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 Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for (;;)
;
}
Udp.begin(localPort);
}
void loop()
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ( (epoch % 60) < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
}
// wait ten seconds before asking for the time again
delay(10000);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
If your ethernet shield is a cheap clone, they are known to be faulty.
You will be able to get a DHCP address by plugging it directly into your DHCP server, but you will not get an address if the shield is connected to a switch.
You can fix this by soldering 2 x 100 Ohm resistors to the correct pins of the network socket on the bottom of the shield.
Alternatively, use a static ip address, or buy a different ethernet shield.