Shop OBEX P1 Docs P2 Docs Learn Events
dprint alternatives? — Parallax Forums

dprint alternatives?

So here's the problem as far as I understand it so far, I have a device and I am trying to send it commands from the propeller and I'm using C. I wanted to use a single line to send the commands such as

dprint(r302, "%c%c%c%c%c%c%c%c%c", 0x7e, 0xff, 0x06, 0x0f, 0x00, 0x01, 0x02, 0xef, 0xef);

I belive my problem is with having to send the "0x00". if I send the string with no "0x00" it works fine, when I use writeChar(r302, 0x00) and send everything individually it works also.
so my question, is there a way to use a single line to send a string with a "0x00" within it?

Comments

  • kwinnkwinn Posts: 8,697
    String functions use 0x00 as the "end of string" byte, so no way around that.

    In spin and pasm I have written string routines that use the first byte as the string length so any byte including 0x00 can be part of the string. Of course that limits the length to 256 bytes, but that is fine for my use. It could be increased by using the first two bytes as the string length.

    The same could be done for C.
  • Heater.Heater. Posts: 21,230
    I don't see any strings in the example shown. Only individual char. So I would expect a 0x00 to be OK.
  • Heater. wrote: »
    I don't see any strings in the example shown. Only individual char. So I would expect a 0x00 to be OK.
    Depends on how they implemented dprint. They might have used sprintf into a local buffer and then fputs to output that buffer. In that case, the 0x00 would act as a terminator.
  • Just as I suspected:
    int dprint(text_t *device, const char *fmt, ...)
    {
      char buf[256];
      va_list args;
      int r;
      va_start(args, fmt);
      r = _dosprnt(fmt, args, buf);
      va_end(args);
      writeStr(device, buf);
      return r;
    }
    
  • @bnikkel,

    That's tough. Sorry to hear it's not working well for you. PropWare's Printer class would take care of this, though it will take more than 10 seconds to get it working in your project (assuming you're in SimpleIDE). PropWare's Printer class has a printf method which will look very familiar to you but does not use the _dosprnt() function in its implementation, which is the source of your problems here.

    Here's an example of using the Printer class to wrap the existing Simple object: https://github.com/parallaxinc/PropWare/blob/develop/Examples/PropWare_Simple_Hybrid/Hybrid_Demo.cpp
    Where that example uses "::putChar(c);", you would want to use "writeChar(r302, c);" (and something similar in place of the "putStr(c)").

    Okay... so maybe you like my idea but don't know how to make this work. If that's the case, let me know your current project setup and I can walk you through what it would take to make update it.
  • Dave HeinDave Hein Posts: 6,347
    edited 2017-09-28 19:56
    dprint prints to a string and then sends the string to a device using writeStr. If you insert a 0x00 in the string it will be interpreted as the end of the string. It will also generate a carriage return when it encounters a line feed. The source for dprint is as follows:
    int dprint(text_t *device, const char *fmt, ...)
    {
      char buf[256];
      va_list args;
      int r;
      va_start(args, fmt);
      r = _dosprnt(fmt, args, buf);
      va_end(args);
      writeStr(device, buf);
      return r;
    }
    
    and the code for writeStr is
    int writeStr(text_t *p, char *str)
    {
      int n = 0;
      while(*str) {
        if(*str == '\n')
          writeChar(p, '\r');
        writeChar(p, *str);
        str++;
        n++;
      }
      return n;
    }
    
    There doesn't seem to be a device block write routine in the library, but you could use this code to write out an array.
    #include "simpletext.h"
    
    void dwrite(text_t *p, char *ptr, int size)
    {
      while (size-- > 0)
        WriteChar(p, *ptr++);
    }
    
Sign In or Register to comment.