Go Down

Topic: [SOLVED] Send 32x32 image over serial (B&W) (Read 503 times) previous topic - next topic

Hackeitos

Dec 29, 2017, 10:31 am Last Edit: Dec 30, 2017, 08:08 pm by Hackeitos
I have an OLED screen and it's not RGB, so I just want to send over serial a 32x32 image which all its pixels are just black or white.

artisticforge

I have an OLED screen and it's not RGB, so I just want to send over serial a 32x32 image which all its pixels are just black or white.
What Arduino Board are you using?
What version of the Arduino IDE are you using?
What operating system are you using?
Linux, MacOSX, MS Windows, other

What is the make and model of the OLED?
Do you have a link for the OLED?

><>

Hackeitos

- Arduino BT
- 1.8.5
- Windows 10 x64

- Actually I haven't the OLED screen yet, but i'm doing tests with a TFT shield. Anyway I haven't any problems to print anything

AWOL

"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

david_prentice

#4
Dec 30, 2017, 12:20 am Last Edit: Dec 30, 2017, 12:21 am by david_prentice
Personally,   I would send human readable data e.g. a C array declaration.

The other side can see if there is garbage or realistic data.
Yes,   there is an enormous overhead.   But for 128 bytes of data,   who cares if you send 800 characters?

Bigger files are different.   You might compress the data and send packets with CRC and Error Correction.
There are many formats that have been proven e.g. over noisy radio, phone, internet.

David.

artisticforge

- Arduino BT
- 1.8.5
- Windows 10 x64

- Actually I haven't the OLED screen yet, but i'm doing tests with a TFT shield. Anyway I haven't any problems to print anything
Why did you say that you had it?
><>

Hackeitos

Why did you say that you had it?

Suposed to arrive yesterday, so posted that in the morning to have answers as soon as possible...

Hackeitos

Personally,   I would send human readable data e.g. a C array declaration.

The other side can see if there is garbage or realistic data.
Yes,   there is an enormous overhead.   But for 128 bytes of data,   who cares if you send 800 characters?
Can you explain better please?

ZinggJM

I have an OLED screen and it's not RGB, so I just want to send over serial a 32x32 image which all its pixels are just black or white.
I am still learning to understand "Newbie-Language".

You do not ask a specific question, but present some vague idea what you want to do.

In an attempt to try to help you, we can

- ask questions, to find out what your requirements are,

- present problem fields and potential pitfalls,

- present ideas how to get started, for you to get a more concrete picture of what you want to do.

Serial communication has its pitfalls, as serial communication drivers or libraries generally interpret special codes or characters. Therefore pure binary data should be transcoded for communication, as David mentioned.
I would go for a HEX ASCII representation for a start, as it is readable.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Hackeitos

#9
Dec 30, 2017, 10:56 am Last Edit: Dec 30, 2017, 11:36 am by Hackeitos
I am still learning to understand "Newbie-Language".

You do not ask a specific question, but present some vague idea what you want to do.
I have a 32x32 image, all of its pixels are just 1 or 0. I just tried to send the image like binary(1 or 0), but the board does not receive full string. This is the code i tried so far:

Code: [Select]
#include <SoftwareSerial.h>
void setup() {
  Serial.begin(9600);
}

void loop() {
  bool pixels[1024];
  int i = 0;
  char d = Serial.read();
  while (d != '!') {
    d = Serial.read();
    if (d == '1') {
      pixels[i] = true;
      i++;
    } else {
      pixels[i] = false;
      i++;
    }
  }

  i = 0;
  for (int n = 0; n < 1024; n++) {
    if (pixels[n] == true) i++;
  }
  Serial.print(i, DEC);
}


With this code, I send to serial 1024 chars "1" and "!" at the end, but arduino only responds with numbers smaller than 600. Now my specific question is: Wich format do I use to send this?

ZinggJM

Thank you, I like riddles, but preferably not in the form of code.

If I interpret your code correctly, it forever reads streams of characters terminated with '!'.
For each such streams it determines the number of ones '1' in a rather complicated way with an array of bools. And prints that number in decimal notation.

What we don't see is the part sending the streams of characters.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Hackeitos

If I interpret your code correctly, it forever reads streams of characters terminated with '!'.
For each such streams it determines the number of ones '1' in a rather complicated way with an array of bools. And prints that number in decimal notation.
Yeah, sorry for the no explanation.

What we don't see is the part sending the streams of characters.
Code: [Select]
Imports System.IO.Ports

Public Class Form1
    Dim Pixels(1024) As Boolean
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For h As Integer = 0 To 1023
            Pixels(h) = True
        Next
        Dim i As Integer = 0
        For y As Integer = 1 To 32
            For x As Integer = 1 To 32
                Dim pb As New PictureBox
                pb.Size = New Size(20, 20)
                pb.Location = New Point(5 + x * pb.Size.Width, 5 + y * pb.Size.Height)
                pb.BorderStyle = BorderStyle.FixedSingle
                pb.BackColor = Color.White
                pb.Tag = i
                i = i + 1
                AddHandler pb.Click, AddressOf pb_Click
                Me.Controls.Add(pb)
            Next
        Next
        SerialPort1.Open()
    End Sub

    Private Sub pb_Click(sender As Object, e As EventArgs)
        If sender.BackColor = Color.White Then
            sender.BackColor = Color.Black
            Pixels(sender.tag) = False
        Else
            sender.BackColor = Color.White
            Pixels(sender.tag) = True
        End If
    End Sub

    Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
        Dim s As String = ""
        For Each item In Pixels
            s = s + If(item, "1", "0")
        Next
        SerialPort1.Write(s & "!")
    End Sub

    Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        MsgBox(SerialPort1.ReadExisting)
    End Sub
End Class


The sending part is in Basic, and it is a form with 32x32 picturebox simulating pixels, so if i click one, it becomes black or white. There is a Send button, so if i click it, it sends every pixel with "!" at the end.

ZinggJM

Quote
With this code, I send to serial 1024 chars "1" and "!" at the end, but arduino only responds with numbers smaller than 600. Now my specific question is: Wich format do I use to send this?
Yes, in the meantime the meaning of your explanation became clear to me.

Your issue is that you seem to loose characters between the sending part and the receiving part.
This is not uncommon with serial communication, but unexpected for me for 9600baud.

I would first try to connect a terminal at the receiving end, to make sure there is no loss there.

Serial communication is not my field of deeper knowledge, and maybe Displays is the wrong Forum for this.

But thank you for the information about the sending part being Visual Basic.
I once sent video frames from a 800x600 video camera through an Arduino to Visual Basic for presentation, with a very slow frame rate.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Hackeitos

After many tries, finally I got it. I will left the codes here just in case someone finds it useful:

VB.NET (Computer, sending part):
Code: [Select]
Imports System.IO.Ports

Public Class Form1
    Dim Pixels(1023) As Boolean
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For h As Integer = 0 To 1023
            Pixels(h) = True
        Next
        Dim i As Integer = 0
        For y As Integer = 1 To 32
            For x As Integer = 1 To 32
                Dim pb As New PictureBox
                pb.Size = New Size(20, 20)
                pb.Location = New Point(5 + x * pb.Size.Width, 5 + y * pb.Size.Height)
                pb.BorderStyle = BorderStyle.FixedSingle
                pb.BackColor = Color.White
                pb.Tag = i
                i = i + 1
                AddHandler pb.Click, AddressOf pb_Click
                Me.Controls.Add(pb)
            Next
        Next
        SerialPort1.Open()
    End Sub

    Private Sub pb_Click(sender As Object, e As EventArgs)
        If sender.BackColor = Color.White Then
            sender.BackColor = Color.Black
            Pixels(sender.tag) = False
        Else
            sender.BackColor = Color.White
            Pixels(sender.tag) = True
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim s As String = "<"
        Dim s2 As String = ""
        For Each item In Pixels
            s = s + If(item, "1", "0")
            If s.Length = 33 Then
                s = s & ">"
                SerialPort1.Write(s)
                s2 = s2 + s
                'MsgBox(s)
                s = "<"
            End If
        Next
    End Sub

    Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        MsgBox("Serial: " & SerialPort1.ReadExisting)
    End Sub
End Class


Arduino (Receving part):
Code: [Select]
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h>

#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(19200);
  tft.reset();
  tft.begin(tft.readID());
  tft.fillScreen(BLACK);
}

void loop() {
  // put your main code here, to run repeatedly:
  readImage(20, 20, WHITE, BLACK);
}

void readImage(int x, int y, int fore, int back) {
  int total = 0;
  for (int i = 0; i < 32; i++) {
    String d = readSerial();
    if (d == "") return;
    for (int k = 0; k < 32; k++) {
      if (d.charAt(k) != '1' && d.charAt(k) != '0') {
        tft.fillRect(x, y, x + 32, y + 32, back);
        return;
      }
      if (d.charAt(k) == '1') {
        tft.drawPixel(k + x, i + y, fore);
        total++;
      }
      if (d.charAt(k) == '0') {
        tft.drawPixel(k + x, i + y, back);
        total++;
      }
    }
  }
  if (total != 1024) {
    tft.fillRect(x, y, x + 32, y + 32, back);
  }
}

String readSerial() {
  char d = Serial.read();
  String s = "";
  if (d == '<') {
    while (d != '>') {
      if (Serial.available() > 0) {
        if (d != '>' && d != '<') s = s + d;
        d = Serial.read();
      } else {
        delay(1);
        if (!Serial.available() > 0) {
          return "";
          break;
        }
      }
    }
    if (d != '>' && d != '<') s = s + d;
    //s.remove(0, 1);
    //s.remove(s.length() - 1, 1);
    return s;
  }
  return "";
}

Go Up