Screen mirroring on a clone, and outputting to a TV via the TVOut library

Hi,
I have done an Arduboy clone using an Arduino Pro Micro, and I would like to output the serial communication trough the Tx and Rx (Pin 1 and 0 respectively), not via the USB cable, to interact with another device. As far as I understand, in principle I would need to use the following commands:

Serial1.begin(9600);

and

Serial1.write(arduboy.getBuffer(), 128 * 64 / 8);

But there is no output at all on pin 0 and 1 (I have check with a scope).
I tried this with the game “Snake”, and if I use the standard “Serial” instead of “Serial1”, I can use the screen mirroring trough your Arduboy Manager.
Furthermore, a simple sketch like this:

void setup() {
_ Serial1.begin(9600); _
}

void loop() {
_ Serial1.print(“X”);_
_ delay(4); _
}

works fine and I can see the ascii signal of “X” on my scope.
Do you have any idea why Serial1 does not produce any output when used in a Arduboy game?
Thank you in advance,
Rob Cai

The Arduboy2 library has a line in Arduboy2Core.cpp which disables USART1 (see below), so you may need to comment that line out?

void Arduboy2Core::bootPowerSaving()
{
  // disable Two Wire Interface (I2C) and the ADC
  // All other bits will be written with 0 so will be enabled
  PRR0 = _BV(PRTWI) | _BV(PRADC);
  // disable USART1
  PRR1 |= _BV(PRUSART1);
}

Are you using Mr.Blinky’s version of the Arduboy2 library?

I thing “Snake” uses the Arduboy-master library, since it calls at the beginning
#include <Arduboy.h>
I am trying then to comment in “core.cpp” the line
power_usart1_disable(); in
void ArduboyCore::saveMuchPower()
{
power_adc_disable();
power_usart0_disable();
power_twi_disable();
// timer 0 is for millis()
// timers 1 and 3 are for music and sounds
power_timer2_disable();
power_usart1_disable();
// we need USB, for now (to allow triggered reboots to reprogram)
// power_usb_disable()
}

If this make sense…

It looks it works!!! I can see an output with the scope on the pin Tx now!
uXe and Pharap, thank you very much.
Rob Cai

2 Likes

Out of curiosity, what is the other device you will be talking to?

I don’t think I actually did anything.
All I did was ask a question.

1 Like

The idea would be to get the signal with another Arduino (such as Uno or Nano) running the TvOut library and see if I can convert/write it in the frame buffer, to send it to a TV.
I do not know yet if it possible.
For the moment I have just seen that, by setting the baud rate to 115200 in the Arduino Pro Micro used as an Arduboy clone, the frame buffer is sent to Tx in about 87 ms and the game (Snake) is still playable, eventually a bit slower.

Have you seen this?

Yes, I have seen it, that’s exactly the idea, but I would like to try with a simpler device such as another Arduino. I have no idea if it is possible to do the same due to its limitation and my (lack of) knowledge.
By the way, I do not know at all how to program an FPGA…

PS just seen that this topic has been splitted…

Yes, I have seen it, that’s exactly the idea, but I would like to try with a simpler device such as another Arduino. I have no idea if it is possible to do the same due to its limitation and my (lack of) knowledge.
By the way, I do not know at all how to program an FPGA…

Just so you’re aware in case you think it’s all you but there is slight lag when using serial screen mirroring.

@obono released an android app that’s capable of screen mirroring I previously used this with a chromecast.

FPGAs aren’t programmable.
They’re designed with a HDL (Hardware Description Language) and then manufactured.
They do one job and nothing else.

If you had one of @uXe’s VGA 1306 boards,
you could use it to connect your clone to a television without having to send the screen buffer over serial.
Essentially it’s a circuit that pretends to be an SSD1306 screen, but outputs VGA signals.

It is probably possible, but screen mirroring over serial might not be the best way to do it.

I think a better way to do it might be to send rendering commands over serial and let the chip running TVOut do its own rendering.

E.g.

// Arduboy program:
enum class Command : uint8_t
{
	DrawPixel = 0x01,
	DrawLine = 0x02,
	DrawCircle = 0x03,
	FillCircle = 0x13,
	DrawRect = 0x04,
	FillRect = 0x14,
};

class ArduboyTVOut
{
private:
	Arduboy2 arduboy;
	
public:
	Arduboy2 & getArduboy(void) { return this->arduboy; }
	const Arduboy2 & getArduboy(void) const { return this->arduboy; }

	void begin(void)
	{
		Serial1.begin(9600);
	}
	
	void drawPixel(int16_t x, int16_t y, uint8_t colour = WHITE)
	{
		Serial1.print(static_cast<uint8_t>(Command::DrawPixel));
		Serial1.print(x);
		Serial1.print(y);
		Serial1.print(colour);
		arduboy.drawPixel(x, y, colour);
	}
};

// TVOut program:
enum class Command : uint8_t
{
	DrawPixel = 0x01,
	DrawLine = 0x02,
	DrawCircle = 0x03,
	FillCircle = 0x13,
	DrawRect = 0x04,
	FillRect = 0x14,
};

class ArduboyTVOut
{
private:
	TVout tv;
	
public:
	char beginPAL(void) { return this->tv.begin(PAL); }
	char beginNTSC(void) { return this->tv.begin(NTSC); }

	void drawPixel(int16_t x, int16_t y, uint8_t colour = WHITE)
	{
		tv.set_pixel(x, y, colour);
	}
};

ArduboyTVOut arduboy;

void setup(void)
{
	arduboy.beginPal();
	
	// Await connection
	if(!Serial1);
}

void loop(void)
{
	if(Serial1.available() > 0)
	{
		int data = Serial1.read();
		Command command = static_cast<Command>(data);
		
		switch(command)
		{
			case Command::DrawPixel:
				int x = Serial1.read();
				int y = Serial1.read();
				int colour = Serial1.read();
				arduboy.drawPixel(x, y, colour);
				break;
		}
	}
}

Unfortunately sprite rendering would be a bit difficult,
but for most of the simpler commands it should result in less data being sent over serial, and the data would be sent in small chunks instead of all at once.

Yes, help requests get more attention if they are in a separate thread.
People tend not to notice them as much if they are at the end of a different thread.

And yet FPGA stands for Field Programmable Gate Array. :wink:

1 Like

Technically they’re programmable, but not in the same way as a microcontroller.
Essentially on the scale of abstraction they’re somewhere between assembly and building a circuit, so I’d argue that it’s a bit of a blurred line.

Either way, @rocaj wouldn’t need to do any programming, @uxe already did that part.

1 Like

3 posts were split to a new topic: Discussing FPGAs

To get back on topic.

When you’re already modifying the sketch. You could also consider just using SPI and lower the speed from 8MHz down to 4/2/1MHz so the UNO could handle it. This would be much faster then using Serial @ 115200bps. (Idea courtesy @MLXXXp)

1 Like

@JayGarcia managed to get the screen buffer sent over SPI to a second microcontroller, using a Due:

You could also use a Raspberry Pi instead of a Uno / Nano (Pi is obviously kind of over-powered by comparison, but on the other hand not very over-priced by comparison):

…or, you could look into using a dual-port RAM chip as a middle-man like I did with these two:

All that being said, we are not too far away now from having an online store manufacturing and selling VGA1306 boards for us if you can hold out for that? :grin:

2 Likes

One more thought… if you are set on using TVout, it may be easier in the long-term to work on modifying the Arduboy library(s) to run on a single microcontroller outputting directly to TV, refactoring the functions and the frame-buffer into ‘TVout format’?

1 Like

Really!? I hope you’re breaking out some more IOs (Thinking about (S)NES controller hack :P)

4 Likes