• Please review our updated Terms and Rules here

Is there an RX01 Emulator?

So, today I just finished round one of testing the RX02 emulator attached to my PDP-8m and its M8357 RX8E/RX28 interface board.

So far, so good.

I am using a custom test program I wrote from scratch (thus the delay in test results) that exercises the emulator in the following mode combinations:

RX8E/RX01 in single density, both 8b and 12b mode, both unit 0 and 1 (4 test combos)
RX28/RX02 in both single and double density, both 8b and 12b mode, both unit 0 and 1 (8 test combos)

The tests do full disk write/read/check with both fixed and random data patterns, and exercise various control functions (ie, like set media to reformat SD to DD and vice versa, in RX28 mode).

The test program passes fully under both SIMH (not always indicative of correctness) and on the real PDP-8m and emulator.

Next step will be to come up with bootable RX01/RX02 OS8 disk images to copy those over to the SDcard and boot.

I will have to go back to my running SIMH and generate disk images and then copy those over to the SDcard to finish the testing.

But so far so good on the PDP-8 side as well.
 
Ok, some good (and bad) PDP-8m RX emulator testing news.

Here are commands after booting an OS8 v3Q RX01 SD image in RX01/RX8E mode:
Code:
.
.DIR

SYS  VOLUME--   1
SYS:=RX8E
OS/8 SYSTEM   VERSION   3Q

BUILD .SV  33           HELP  .SV   8           BASIC .UF   4
ABSLDR.SV   5           PAL8  .SV  19           BCOMP .SV  17
BITMAP.SV   5           PIP   .SV  11           BLOAD .SV   8
BOOT  .SV   5           PT8E  .BN   1           BRTS  .SV  15
CCL   .SV  18           RESORC.SV  10           EABRTS.BN  24
CREF  .SV  13           RXCOPY.SV   6           RESEQ .BA   6
DIRECT.SV   7           SABR  .SV  24           ECHO  .SV   2
EDIT  .SV  10           TECO  .SV  22           RKLFMT.SV   9
EPIC  .SV  14           BASIC .AF   4           SET   .SV  14
FBOOT .SV   2           BASIC .FF   4           BATCH .SV  10
FOTP  .SV   8           BASIC .SF   4           FUTIL .SV  26
HELP  .HL  55           BASIC .SV   9           IDS   .SV   5

  36 FILES IN  437 BLOCKS -    1 FREE BLOCKS

.RESORC
SYS,DSK,PTP,PTR,RXA0,RXA1,RKA0,RKB0,RKA1,RKB1,TTY,LPT

And likewise after booting an OS8 v3D RX02 DD image in RX02/RX28 mode:
Code:
.
.DIR

LIB8  .RL  29               FLOAT .RL   5               POWERS.RL   3
INTEGR.RL   2               IPOWRS.RL   2               SQRT  .RL   2
TRIG  .RL   2               ATAN  .RL   2               RWTAPE.RL   2
IOPEN .RL   2               GENIOX.RL   3               DIRECT.SV   7
RXCOPY.SV   9               CREF  .SV  13               SRCCOM.SV   5
MCPIP .SV  13               PIP10 .SV  17               PAL8  .SV  19
BITMAP.SV   5               CAMP  .SV  13               EPIC  .SV  14
ABSLDR.SV   6               BUILD .SV  37               BOOT  .SV   5
FOTP  .SV   8               PIP   .SV  11               RESORC.SV  14
CCL   .SV  31               LOADER.SV  12               SABR  .SV  24
FORT  .SV  25               LIBSET.SV   5               IOH   .RL   7
UTILTY.RL   3               BRTS  .SV  15               BASIC .SV   9
BCOMP .SV  17               BLOAD .SV   8               BASIC .AF   4
BASIC .SF   4               BASIC .FF   4               BASIC .UF   4
RESEQ .BA   6               SET   .SV  14               GENIOX.SB  14
BATCH .SV  10               HELP  .SV   8               MSBAT .SV  23
TECO  .SV  22               FUTIL .SV  27               HELP  .HL  55
BPAT  .BN   1               EABRTS.BN  24               F4    .SV  20
PASS2 .SV  20               PASS2O.SV   5               PASS3 .SV   8
RALF  .SV  19               FORLIB.RL 170               FRTS  .SV  26
EDIT  .SV  10               LOAD  .SV  16               LIBRA .SV  11
FPAT  .BN   1

   0 FREE BLOCKS

.

On either version I can launch and run BASIC and simple programs seem to work as expected.

However, I was not able to initialize and format either a SD or DD disk image on RXA1: on either version. INIT/PIP*z work, but DIR returns an error. Looking at the log of commands it appears that the disk write command is returning a status that OS8 does not like. So some more investigation needed there.

I also suspect that creating/updating files on the system drive RXA0 will likely not work, altho I did not explicitly try that. It may be that right at this moment with the current software disk reads are working, but disk writes are not (at least under OS8 ). My standalone test program written per the RX02 Tech Manual RX8E/28 guidelines does both reads and writes perfectly in both 8b and 12b modes, SD and DD, without issue.

[I found the OS278 sources that have both system and non-system RX driver source files, so I am now looking thru those to see what might be different about how OS8 accesses the RX drive when writing. Unfortunately these drivers are really obtuse ...]

During some operations I see the Arduino RX emulator lockup with the green LED ON, and the debug console is unresponsive. This means the Arduino is in the middle of executing an active command, but it stuck in an loop (this should not happen ... :-(). So some more debugging needed here as well. [Looks like I should add a wall clock timeout to the fill/empty loops so that they cannot become infinite if the CPU bails in the middle of a fill/empty buffer sequence -- I believe a real RX01/2 have this kind of timeout timer.]

I also need to implement a flag/option so that disk images can be mounted read-only on the emulator (currently all images are read/write). [This is now added to the latest s/w image on GITHUB - 8:33PM PDT 10/23/2016]

Don
 
Last edited:
So ... after reloading the Arduino with the latest emulator code, I got back to debugging on the PDP-8m with RX28 and RX02 emulation using the OS8V3D.RX2 image.

This time, after booting the image on unit 0, I mounted a new RX02 image file on unit 1 (ie, created from scratch), and was able to:
ZERO RXA1:
and
COPY RXA1:<RXA0:*.*/L
and have it march thru copying all the files one by one. They all copied OK with no errors, and I did spot compares on some files and they matched.

So I can't explain the issue I was having last night with unable to init the unit 1 file (possible operator error?) but for now I cannot replicate it (this is good).

I also checked the same Arduino image back on my 11/44 with RX211 and it still runs and passes all the tests it did before.

Marking units as 'write protected' now also is implemented and works (tested with XXDP trying to INIT a write protected drive).

So at this point the emulator code looks pretty clean for significant other testing, however, as always don't do anything without a backup.

I will appreciate any feedback. Best place is probably on the GITHUB site for the code for any bug reports or feature requests. General feedback here is OK.

Don

Testing that remains: RXV21, RXV11, RX11 compatibility.
Tested: RX211, RX8E, RX28.
 
Last edited:
Don,

We now have the V3 board working well on the VT278 Decmate. The most disk-intensive exercise I can come up with is OS/78 disk duplication (DUPLIC RXA1:<RXA0). I can now do that without errors. Everything else I try is fine also, such as running programs in Basic (which uses overlays and is disk intensive.) It really works excellent and is much faster than Bela's emulator (which I am able to use read-only on the Decmate, I may try to make the fix you point out in post #38 ).

Some pictures :
http://www.vcfed.org/forum/album.php?albumid=346&attachmentid=34078
http://www.vcfed.org/forum/album.php?albumid=346&attachmentid=34079

Out of laziness, I simply reused the cabling in the enclosure I built for Bela's emulator. I need to make up another set now.

However, there was some learning to get to this point. With my setup, the emulator works best when completely disconnected from the PC and powered from a wall wart. When plugged into the PC, the more activity I have over the serial monitor, the more errors there are in the communication between the Decmate and the emulator. As I would progressively lower the diagnostic reporting, there would be fewer errors. At D 0, there would be the least frequent errors, but still an occasional error. With the PC disconnected, there are no errors. The PC here is a Dell laptop that has been running on its battery for this testing. I wonder if the load on the PC USB port is heavy and perhaps the voltage is low. I'm sure running the PC on battery wouldn't help. I should try to measure the PC's USB port voltage.

I'd really like to be able to change disk images without the PC involved. I don't necessarily need an LCD display. Perhaps I'll put together some code to use thumbwheels to select the drive 0 and 1 images. When I get that done, I need to build an enclosure.

Don, it really is most excellent!!!

Lou
 
Last edited:
I have yet to see any random/flaky errors while running any tests, either in RX01 mode on my PDP-8m (RX8E), or RX02 mode on my 8m (RX28) and my PDP-11/44 (RX211 DMA). The only errors I have seen are of the 'hard' nature where the emulator wasn't quite behaving the way that the host side software/diagnostic expected it to (and at least for now all these errors have been eliminated).

All my testing has been done with an emulator connected to my Lenovo T530 laptop USB port. I have tested both the 8641 based and the 2N7000 based versions on each interface (RX211 and RX8E/RX28).

Performance is slower when timing modes 1 or 2 are used (obviously) vs timing mode 0 (fastest). Same for debug modes 1 or 2 vs debug mode 0.

I did some benchmark testing using debug mode 0 (ie, debug off) vs debug mode 1 (medium debug, prints each command, no data). I found that writes are 20% slower, and reads 60% slower when in debug mode 1 vs debug mode 0 (done using a custom test that reads or writes all sectors on the disk as fast as possible). No errors seen in either, however. Even in debug mode 2 (full buffer data dumping) it just runs (a lot) slower performance-wise, but I still don't see any errors on either the PDP11 or PDP8. I have switched between debug 0/1/2 and timing 0/1/2 while tests are running, and the tests still complete error free. They just take longer at higher debug and/or timing mode values.

Just yesterday I uploaded a new version of code (v1.4) that improves performance by 5% to 10% when in debug off mode by using polling on the RUN line vs interrupt driven (which was a bit of overkill for the RUN signal sampling).

One question, what baud rate are you running the USB menu command interface at? The default I setup was 250K baud (exactly) which, for debug mode, has minimal impact, and is the fastest that the USB serial interface chip (actually an AVR 16U2 part) will run at.

I also believe the Mega2560 has power supply circuity that allows you to power it thru the DC power connector (6-9VDC IIRC) while also connected to USB. If DC input voltage is detected then the power source will be switched to that, and 5V USB power will not be used. That would be an interesting test. I measured the active 5V USB current required during operation and for the RX02 shield plus Mega2560 it was 180mA maximum at 4.75V measured. Maybe your DELL laptop USB can't quite meet those specs.

Don
 
Last edited:
Don,

I've been running the serial console at the max speed (250k baud). I am very sure that my problem is with my laptop. Your emulator has been working perfectly when disconnected from the laptop. Unfortunately this one laptop is the only portable I have with a USB port. No big deal though.

Now that I have your emulator working perfectly I've turned my attention back to trying to get Bela's to work (mostly because I spent $25 on the Due, which I would not otherwise want to use for any other projects.) I did fix Bela's code per your earlier post #38, but there is more wrong than that.

Anyone,

Has anyone here actually gotten Bela's emulator working properly?

Lou
 
Don,

I've been running the serial console at the max speed (250k baud). I am very sure that my problem is with my laptop. Your emulator has been working perfectly when disconnected from the laptop. Unfortunately this one laptop is the only portable I have with a USB port. No big deal though.

Now that I have your emulator working perfectly I've turned my attention back to trying to get Bela's to work (mostly because I spent $25 on the Due, which I would not otherwise want to use for any other projects.) I did fix Bela's code per your earlier post #38, but there is more wrong than that.

Anyone,

Has anyone here actually gotten Bela's emulator working properly?

Lou

Have you tried using the emulator with the USB connected AND an external power supply in the DC input jack (that should work on the Mega2560, it has the circuitry to switch to external power if present and disconnect from USB 5V power, but keeping USB connectivity in place)?

What about using a powered USB hub between the emulator and your PC? Have you tried that, if you can?

With debug level 0 there is no ongoing serial output display activity, just monitoring for menu commands between emulator functions (which if you don't type anything to the monitor screen should have no impact). So my suspicion is that the issue is related to the USB supply voltage on your laptop, and not the serial link activity, or USB connectivity per se.

The baud rate actually only applies to the Mega2560 to/from AVR 16U2 serial link on the Arduino board itself. The USB link does not care. Based on the 8M/16MHz clock rates on the CPUs 250K baud is an exact (0% error) clock rate (as opposed to 230.4K, or 115.2K, which have small % errors in frequency).

Don
 
Last edited:
Don,

Ok, same trouble even when powering the mega from a 9V wall wart that I use for other Arduino projects. Even at D 0, when doing the disk intensive disk copying there will be bad sector glitches or the decmate will hang. Tomorrow night I will try the powered hub, which is a good idea.

Lou
 
Don,

Ok, same trouble even when powering the mega from a 9V wall wart that I use for other Arduino projects. Even at D 0, when doing the disk intensive disk copying there will be bad sector glitches or the decmate will hang. Tomorrow night I will try the powered hub, which is a good idea.

Lou

So this is with USB connected and the Arduino powered by a 9VDC wall adapter?

Other interesting tests:

If you use the wall adapter only, and disconnect the USB, then it works reliably?

What about with the wall adapter only, an in various debug modes (eg, 'd 0' vs 'd 2')?
For these tests, connect via USB, set debug mode 0 (none) or 2 (lots), then write the init file (via W) to set the power up default configuration.
Then disconnect/reboot to only wall wart power and see if it still generates errors in debug 0 vs debug 2.
The debug info goes out the main RS232 serial port 0 of the Mega2560 (not a USB connection until it is received by the 16U2 part and retransmitted over USB).

Whether USB is connected or not should really not affect the Mega2560 CPU, only the subsidiary 16U2 part which is acting as a smart USB serial adapter.

Don
 
Last edited:
Don,

Sorry for taking so long to get back on this. I've been playing Mr. Mom this week while my wife was at a conference.

AK6DN said:
So this is with USB connected and the Arduino powered by a 9VDC wall adapter?

Yes.

AK6DN said:
If you use the wall adapter only, and disconnect the USB, then it works reliably?

Yes.

AK6DN said:
What about with the wall adapter only, an in various debug modes (eg, 'd 0' vs 'd 2')?
For these tests, connect via USB, set debug mode 0 (none) or 2 (lots), then write the init file (via W) to set the power up default configuration.
Then disconnect/reboot to only wall wart power and see if it still generates errors in debug 0 vs debug 2.
The debug info goes out the main RS232 serial port 0 of the Mega2560 (not a USB connection until it is received by the 16U2 part and retransmitted over USB).

You may be relieved to know that the disk copying exercise does work fine at D 2 level as well as D 0 under the test conditions above. Of course it takes a hell of a lot longer at D 2. So it must be a USB problem.

I did some testing with the powered hub and D 2. The disk copy fails quickly when the mega is powered only through the hub. When I power with the wall wart and have the powered hub attached, and watch the action on the serial monitor, it does not fail. At least this is helpful since now I can use this laptop and leave it connected while still having the emulator work reliably.

I took a look at the mega schematic and did notice that the USB power in and on board 5V regulator are diode auctioneered. I haven't looked at the power supplies with a scope, but there must be something better (cleaner?) when using the on-board 5V regulator. I should also mention that this is not an Italian made mega, it is the inexpensive Inland brand from MicroCenter.

We probably shouldn't spend any more time on this since I am convinced it's a (my) USB power problem. At some point in the future I'll try a different laptop. I think we can pretty safely say that VT278 compatibility has been verified!

I have the feeling that there are many VT278s out there in people's basements and garages with no RX02, and so they go unloved. This emulator is so small it can fit inside the case and for $30 the machine can be brought to life. It should be just as useful in a VT103 with RXV21.

Lou
 
Last edited:
Well, that is all good news. Thanks for the additional testing.

In the Mega2560 R3 'standard' schematic I have the USB 5V power comes in thru a 500ma polyfuse (0.2ohm min to 1.0ohm max) and then thru a PMOS MOSFET with an Rds(on) of 0.070ohm maximum. So at 200mA the voltage drop would be 200mV maximum, but probably closer to about 100mV on this circuit.

If someone 'cheated' and used a non-schottky diode to OR the two supplies then the USB voltage drop could easily be 700mV or so, quite a difference (about 500mV more).

So depending upon the design of the Mega2560 used, and the Vout vs Iload capability of the USB port, powering from just USB may not work on some systems.

On my Mega2560 R3 and Lenovo T530 laptop USB port I see 4.75V USB voltage, and 4.65V on the 5V rail on the shield.

---

I did some performance studies using some PDP-11 test programs that read (or write) all sectors of all tracks on a drive, as fast as possible, and record the number of 60Hz clock ticks to do it. I found in debug mode 1, writes are 20% slower than debug mode 0; and reads are 60% slower in debug mode 1 vs debug mode 0. debug mode 2 dumps out a LOT more data (ie, all the buffer contents on empty/fill buffer commands) so debug mode 2 may very well be 10X - 100X slower than debug mode 1.

---

Lastly, I have now received ~20 more 2N7000-based boards and ~10 more 8641 based boards, so if anybody wants/needs more I can supply them. Still the same cost per board ($7.50 plus $2.50 shipping in the US, more international). I also still have a limited number (~10) of the Sparkfun microSD adapters ($5.00) each (but you can get those for $4.95 direct from Sparkfun: https://www.sparkfun.com/products/13743 they have 165 in stock at last count). I am considering listing on eBay to make ordering/etc easier to track and process but have not decided as of yet.

Don
 
Last edited:
So ... over the past month I was able (finally) to finish and test my version of XXDPDIR (actually xxdpdir.pl plus an XXDP.pm Perl module) that supports access to RX01 and RX02 media images (as well as simple linear block drives like TU58, MSCP, RL02, etc) so I could now build RX01 and RX02 bootable XXDP file systems just like I did for TU58 bootable XXDP filesystems. It is written in plain jane Perl, so I run it under CYGWIN 32b on Win7 64b, but it will run on just about any OS that supports Perl, including linux.

The RX02 (new) files are here: http://www.ak6dn.com/PDP-11/RX02/

The TU58 (existing) files are here: http://www.ak6dn.com/PDP-11/TU58/

The RX02 images have been tested on my RX02 emulator board attached to my RX211 / 11/44 system, and boot / run diagnostics as expected.

I had been using the legacy XXDPDIR.EXE / DIAGDIR.EXE 16b DOS applications to build my TU58 images, but once I moved to Win7 64b (from WinXP 32b) I could no longer run these programs from the command line (as 64b Win won't run 16b applications any more). I had to run thru DOSBOX (which was doable, but inconvenient). And the legacy apps did not support RX01/RX02 media format either.

Don

At some point I will push my xxdpdir.pl/XXDP.pm implementation up to github alongside my other projects. Right now I have to cleanup and finish the user documentation.

PS I still have a number of 2N7000-based and 8641-based RX02_emulator bare PCB available; going rate is $10 ea plus shipping (I did these in ENIG which was a bit more costly).

FYI here is what running xxdpdir.pl looks like to create an RX02 image (note .RX2 extension autoconfigures RX02 device image mode):

Code:
rx02[627] ./11XXDP.sh
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract '*.SYS'
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert '*.SYS' --init --boot
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract HELP.TXT
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert HELP.TXT
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract PATCH.BIC
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert PATCH.BIC
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract SETUP.BIC
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert SETUP.BIC
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract UPDAT.BIC
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert UPDAT.BIC
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract XTECO.BIC
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert XTECO.BIC
++ xxdpdir.pl --image ../../XXDP/XXDP_v25_rl02.dsk --path tmpdir --extract FLOAT.BIN
++ xxdpdir.pl --image ./11XXDP.RX2 --path tmpdir --insert FLOAT.BIN
++ xxdpdir.pl --image ./11XXDP.RX2 --directory --format standard > 11XXDP.TXT
rx02[628]

And the directory listing:
Code:
DOS11 format, assume monitor starts at block 23
Image supports 1001 blocks
16 directory blocks, block 3 thru 18
4 bitmap blocks, block 19 thru 22
401 device blocks in use according to the bitmap

ENTRY# FILNAM.EXT        DATE          LENGTH  START   VERSION

    1  XXDPSM.SYS       1-MAR-89          29     55     E.0
    2  XXDPXM.SYS       1-MAR-89          39     84     F.0
    3  DRSSM .SYS       1-MAR-89          24    123     G.2
    4  DRSXM .SYS       1-MAR-89          48    147     C.0
    5  DATE  .SYS       1-MAR-89           2    195     B.0
    6  DB    .SYS       1-MAR-89           2    197     C.0
    7  DD    .SYS       1-MAR-89           3    199     D.0
    8  DIR   .SYS       1-MAR-89           7    202     D.0
    9  DL    .SYS       1-MAR-89           4    209     D.0
   10  DM    .SYS       1-MAR-89           4    213     C.0
   11  DR    .SYS       1-MAR-89           3    217     C.0
   12  DU    .SYS       1-MAR-89           4    220     E.0
   13  DUSZ  .SYS       1-MAR-89           2    224     C.0
   14  DY    .SYS       1-MAR-89           3    226     D.0
   15  LP    .SYS       1-MAR-89           1    229     B.0
   16  MM    .SYS       1-MAR-89           3    230     C.0
   17  MS    .SYS       1-MAR-89           4    233     C.0
   18  MU    .SYS       1-MAR-89           4    237     E.0
   19  HELP  .TXT       1-MAR-89          29    241
   20  PATCH .BIC       1-MAR-89          31    270
   21  SETUP .BIC       1-MAR-89          27    301
   22  UPDAT .BIC       1-MAR-89          29    328
   23  XTECO .BIC       1-MAR-89          26    357
   24  FLOAT .BIN       1-MAR-89          18    383

FREE BLOCKS:   600
 
Last edited:
I just joined this forum. "DEC" was (of course) the first group to visit, and the "Is there an RX01 emulator" (this thread) caught my eye.
A very quick scan of this thread already proves the quality of this forum. I will need time to get through all this info.
But, to return to the original question. Pete Dundas (IIRC) developed several year ago an RX01 emulator. You need a UNIBUS machine, his dual-width dveloped module, one M105 and one M7821. A ribbon cable connects the dual-width module to the parallel port of a PC. A program runs on the PC. That's all. It works with the standard RT11 DX driver.
I have that module, and did actually boot RT11 on an 11/34 with it via a PC. If interestd, I can start a search ...

Season's Greetings,
- Henk, PA8PDP
 
OK, we've had the food and watched the movie and now I'm back to the Arduino. I need some help from you C++ literate folks. I'm trying to add printf() to the Print class, as per Don's note #1. I've added the support code to what seems to me to be the end of Print.h in the appropriate core directory for my Mega 2560 board (only board installed on my system) but I still get a bunch of error messages as shown in the (edited) output below:

Code:
Arduino: 1.8.0 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

sketch\rx02_driver.cpp: In function 'void rx_xmit_es()':


rx02_driver.cpp:609: error: 'class HardwareSerial' has no member named 'printf'


     if (debugLevel) debugPort->printf(F("RX: %s rx_xmit_es(%04o)\n\n"), rx.fcn.name, rx.es);

​                             ^
.
.
.
.


exit status 1
'class HardwareSerial' has no member named 'printf'


This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I'm pretty sure it relates to my inability to paste the printf code into Print.h - I'm not really sure how the public: section is delimited or where and how, exactly, to paste the provided code. I've tried a couple variations (as per my commented out bits at the end of the file) but really have no idea what I'm doing. Here's what I've done - please set me straight!

Thanks and Season's Best to all -

Jack

Code:
/*
  Print.h - Base class that provides print() and println()
  Copyright (c) 2008 David A. Mellis.  All right reserved.


  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.


  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.


  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/


// 12-25-2016 jr added printf support as per Arduino playground page


#ifndef Print_h
#define Print_h


#include <inttypes.h>
#include <stdio.h> // for size_t


#include "WString.h"
#include "Printable.h"


#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2


class Print
{
  private:
    int write_error;
    size_t printNumber(unsigned long, uint8_t);
    size_t printFloat(double, uint8_t);
  protected:
    void setWriteError(int err = 1) { write_error = err; }
  public:
    Print() : write_error(0) {}
  
    int getWriteError() { return write_error; }
    void clearWriteError() { setWriteError(0); }
  
    virtual size_t write(uint8_t) = 0;
    size_t write(const char *str) {
      if (str == NULL) return 0;
      return write((const uint8_t *)str, strlen(str));
    }
    virtual size_t write(const uint8_t *buffer, size_t size);
    size_t write(const char *buffer, size_t size) {
      return write((const uint8_t *)buffer, size);
    }
    
    size_t print(const __FlashStringHelper *);
    size_t print(const String &);
    size_t print(const char[]);
    size_t print(char);
    size_t print(unsigned char, int = DEC);
    size_t print(int, int = DEC);
    size_t print(unsigned int, int = DEC);
    size_t print(long, int = DEC);
    size_t print(unsigned long, int = DEC);
    size_t print(double, int = 2);
    size_t print(const Printable&);


    size_t println(const __FlashStringHelper *);
    size_t println(const String &s);
    size_t println(const char[]);
    size_t println(char);
    size_t println(unsigned char, int = DEC);
    size_t println(int, int = DEC);
    size_t println(unsigned int, int = DEC);
    size_t println(long, int = DEC);
    size_t println(unsigned long, int = DEC);
    size_t println(double, int = 2);
    size_t println(const Printable&);
    size_t println(void);
    
    };


#endif


    
#include <stdarg.h>
#define PRINTF_BUF 80 // define the tmp buffer size (change if desired)
   void printf(const char *format, ...)
   {
   char buf[PRINTF_BUF];
   va_list ap;
    va_start(ap, format);
    vsnprintf(buf, sizeof(buf), format, ap);
    for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines
    {
        if(*p == '\n')
            write('\r');
        write(*p);
    }
    va_end(ap);
   }
#ifdef F // check to see if F() macro is available
   void printf(const __FlashStringHelper *format, ...)
   {
   char buf[PRINTF_BUF];
   va_list ap;
    va_start(ap, format);
#ifdef __AVR__
    vsnprintf_P(buf, sizeof(buf), (const char *)format, ap); // progmem for AVR
#else
    vsnprintf(buf, sizeof(buf), (const char *)format, ap); // for the rest of the world
#endif
    for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines
    {
        if(*p == '\n')
            write('\r');
        write(*p);
    }
    va_end(ap);
   }
#endif


//    };


//#endif
 
Merry Christmas and Happy Holidays to all ...

The added code segment needs to be inserted just prior to the last two non-blank lines: }; and #endif and just after the line: size_t println(void);

The added chunk of code needs to be the last entries in the public: section.

Or if you want, if you are using any 1.6.x version (last was 1.6.13) just copy this whole print.h file intact (it hasn't changed in a while):

Code:
/*
  Print.h - Base class that provides print() and println()
  Copyright (c) 2008 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef Print_h
#define Print_h

#include <inttypes.h>
#include <stdio.h> // for size_t

#include "WString.h"
#include "Printable.h"

#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2

class Print
{
  private:
    int write_error;
    size_t printNumber(unsigned long, uint8_t);
    size_t printFloat(double, uint8_t);
  protected:
    void setWriteError(int err = 1) { write_error = err; }
  public:
    Print() : write_error(0) {}
  
    int getWriteError() { return write_error; }
    void clearWriteError() { setWriteError(0); }
  
    virtual size_t write(uint8_t) = 0;
    size_t write(const char *str) {
      if (str == NULL) return 0;
      return write((const uint8_t *)str, strlen(str));
    }
    virtual size_t write(const uint8_t *buffer, size_t size);
    size_t write(const char *buffer, size_t size) {
      return write((const uint8_t *)buffer, size);
    }
    
    size_t print(const __FlashStringHelper *);
    size_t print(const String &);
    size_t print(const char[]);
    size_t print(char);
    size_t print(unsigned char, int = DEC);
    size_t print(int, int = DEC);
    size_t print(unsigned int, int = DEC);
    size_t print(long, int = DEC);
    size_t print(unsigned long, int = DEC);
    size_t print(double, int = 2);
    size_t print(const Printable&);

    size_t println(const __FlashStringHelper *);
    size_t println(const String &s);
    size_t println(const char[]);
    size_t println(char);
    size_t println(unsigned char, int = DEC);
    size_t println(int, int = DEC);
    size_t println(unsigned int, int = DEC);
    size_t println(long, int = DEC);
    size_t println(unsigned long, int = DEC);
    size_t println(double, int = 2);
    size_t println(const Printable&);
    size_t println(void);

#include <stdarg.h>
#define PRINTF_BUF 80 // define the tmp buffer size (change if desired)
   void printf(const char *format, ...)
   {
   char buf[PRINTF_BUF];
   va_list ap;
        va_start(ap, format);
        vsnprintf(buf, sizeof(buf), format, ap);
        for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines
        {
                if(*p == '\n')
                        write('\r');
                write(*p);
        }
        va_end(ap);
   }
#ifdef F // check to see if F() macro is available
   void printf(const __FlashStringHelper *format, ...)
   {
   char buf[PRINTF_BUF];
   va_list ap;
        va_start(ap, format);
#ifdef __AVR__
        vsnprintf_P(buf, sizeof(buf), (const char *)format, ap); // progmem for AVR
#else
        vsnprintf(buf, sizeof(buf), (const char *)format, ap); // for the rest of the world
#endif
        for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines
        {
                if(*p == '\n')
                        write('\r');
                write(*p);
        }
        va_end(ap);
   }
#endif

    
};

#endif

FYI this is my original post on how to edit Print.h to add the printf capability: http://www.vcfed.org/forum/showthread.php?51918-Is-there-an-RX01-Emulator&p=432851#post432851
 
Last edited:
I must not be holding my mouth right - I tried several things - I downloaded your example, I went back and re-edited my file, I downloaded your first example when Mark had this problem, I even reloaded Ardruino 1.6.8, all with no success and the same error stating 'class HardwareSerial' has no member named 'printf'.

????

Jack
 
Back
Top