Here is a new version of the viewer program.
It shows crude grayscale at the top and the "U" and "V" channels at the bottom.
Try holding different solid color object to the camera and see the "U" and "V" results.
Red has a "light" affect on the "V" channel.
Blue has a "light" affect on the "U" channel AND a "dark" affect on the "V" channel.
CON_clkmode = xtal1 + pll16x_xinfreq = 5_000_000
tiles = vga#xtiles * vga#ytiles
tiles32 = tiles * 32
SerRxPin = 0' Serial interface connect to Sout on LRF
SerTxPin = 1' connect to Sin on LRFOBJ
vga : "vga_512x384_bitmap"
ser : "JDCogSerial"' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/)VARlong sync, pixels[tiles32]
word colors[tiles]
PUBstart | h, i, j, k, x, y, value
ser.Start(|<SerRxPin, |<SerTxPin, 19200) ' Start JDCogSerial cog'start vga
vga.start(16, @colors, @pixels, @sync)
'init colorsrepeat i from0to tiles - 1
colors[i] := $FC00' White on blackwaitcnt(cnt+clkfreq)
ser.Tx("U")
waitcnt(cnt+clkfreq)
repeatwaitcnt(cnt+clkfreq/4)
ser.RxFlush
ser.Tx("Y")
y := 0repeat80
x := 0repeat64
value := ser.Rx ' Read Y1
plotGS(x, y, value)
value := ser.Rx ' Read U
plotGS(x>>1, y+170, value)
value := ser.Rx ' Read Y2
plotGS(x+2, y, value)
value := ser.Rx ' Read V
plotGS(x>>1+138, y+170, value)
x += 4
y += 2PRIplotGS(x, y, value)if value > 51
plot(x, y)
else
unplot(x, y)
if value > 102
plot(x+1, y+1)
else
unplot(x+1, y+1)
if value > 153
plot(x+1, y)
else
unplot(x+1, y)
if value > 204
plot(x, y+1)
else
unplot(x, y+1)
PRIplot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
PRIUnPlot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
pixels[y << 4 + x >> 5] ^= |< x
I know this picture isn't very good but your viewer works for me using your firmware. At first I thought it did just a frame grab until I stood in front of the LRF and found out it is constantly updating.
Dave,
Nice. If you hold up a large blue object you should see a pattern in the U and V fields.
I am working on a new version that will capture a frame and then let the remote request the data one line at a time. This will allow you to communicate much faster by using a buffer to store 1 line, process it, then request another line. The lines can be requested in any order. So you can just request the line you are interested in. Requesting a line > 79 terminates the command.
I'd also like to allow the single line data to be returned in RGB format (16-bit or 24-bit). I'm working on that part now.
Talk about a fancy line scanner! I thought I would post some pixs I took of the uOLED and the view the LRF was looking at. That device is so small it was hard to get a good picture. Also a pix of my current setup.
Dave,
Here is the latest version that returns lines in RGB (8-bits each, 384 bytes per line).
CON_clkmode = xtal1 + pll16x_xinfreq = 5_000_000
tiles = vga#xtiles * vga#ytiles
tiles32 = tiles * 32
SerRxPin = 0' Serial interface connect to Sout on LRF
SerTxPin = 1' connect to Sin on LRFOBJ
vga : "vga_512x384_bitmap"
ser : "JDCogSerial"' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/)VARlong sync, pixels[tiles32]
word colors[tiles]
byte cameraline[128*3]
PUBstart | x, y, i, value, lineNo
ser.Start(|<SerRxPin, |<SerTxPin, 115200) ' Start JDCogSerial cog'start vga
vga.start(16, @colors, @pixels, @sync)
'init colorsrepeat i from0to tiles - 1
colors[i] := $FC00' White on blackwaitcnt(cnt+clkfreq)
ser.Tx("U")
waitcnt(cnt+clkfreq)
repeat
ser.Tx("Z")
y := 0repeat lineNo from0to79
ser.rxFlush
ser.Tx(lineNo)
repeat i from0to383
cameraLine[i]:=ser.Rx
x := 0
i := 0repeat128' 128 pixels per line
value := cameraLine[i++] ' Read r
plotGS(x, y, value)
value := cameraLine[i++] ' Read g
plotGS(x+256, y, value)
value := cameraLine[i++] ' Read b
plotGS(x+128, y+170, value)
x += 2
y += 2
ser.Tx(255)
PRIplotGS(x, y, value)if value > 51
plot(x, y)
else
unplot(x, y)
if value > 102
plot(x+1, y+1)
else
unplot(x+1, y+1)
if value > 153
plot(x+1, y)
else
unplot(x+1, y)
if value > 204
plot(x, y+1)
else
unplot(x, y+1)
PRIplot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
PRIUnPlot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
pixels[y << 4 + x >> 5] ^= |< x
I couldn't get a good picture of the uOLED but heres a color pix on uOLED and a normal shot of the room as the lrf would see it. There is a dark colored bookcase on the right hand side that probably should be dark or black show blue on the uOLED. But other than that everything else looks natural.
Con_CLKMODE = XTAL1 + PLL16X_XINFREQ = 5_000_000
ack = $06' Acknowledge byte
nak = $15' Invalid command byte Varbyte cameraline[128*3]
Obj
db : "pcfullduplexserial"
fd : "fullduplexserial"Pubstart| i,j,x,y
fd.start(6, 7, 0, 115200) '
db.init
db.addport(0, 31, 30, -1, -1, 0, 0, 19200) 'debug port
db.addport(1, 4, 5, -1, -1, 0, 0, 115200) 'uoled
db.start
waitcnt(clkfreq*3+cnt)
fd.rxflush
fd.tx("U")
repeatuntil fd.rx == ":"
db.str(0, string("Camara online",13))
db.rxflush(1)
db.tx (1, "U")
waitack
db.str(0, string("uOLED ready",13))
waitcnt(1600000+cnt)
erase
repeat
get
Pubwaitackrepeatuntil db.rx(1) == ack
Puberase
db.tx (1, "E")
waitack
Pubget | i, r, g, b, x, y, z
fd.tx("Z")
repeat y from0to79
fd.rxflush
fd.tx(y)
repeat i from0to383
cameraline[i]:=fd.Rx
i := 0repeat x from0to127
r := cameraline[i++]
g := cameraline[i++]
b := cameraline[i++]
plot(x, y, r, g, b)
Pubplot(x, y, r, g, b)' X : 0 to 127 ' Y : 0 to 127 ' Red : 0 to 255 ' Green : 0 to 255 ' Blue : 0 to 255
r := r >> 3 << 11 | (g >> 2 << 5) | (b >> 3)
db.tx(1, "P")
db.tx(1, x)
db.tx(1, y)
db.tx(1, r.byte[1])
db.tx(1, r.byte[0])
waitack
Dave, Yeah I can't really see anything in the picture.
By "everything else looks natural" you mean the image color look good ?
I've noticed that sometimes black shows blocks of white (full on), but I have the variables limited so I can't tell why it does that sometimes. That may be the blue you are seeing instead of black.
Try to get a better picture of the oLED if you can. I'd love to see a color image.
Dave,
Here is a version of the viewer that shows color objects.
CON_clkmode = xtal1 + pll16x_xinfreq = 5_000_000
tiles = vga#xtiles * vga#ytiles
tiles32 = tiles * 32
SerRxPin = 0' Serial interface connect to Sout on LRF
SerTxPin = 1' connect to Sin on LRFOBJ
vga : "vga_512x384_bitmap"
ser : "JDCogSerial"' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/)VARlong sync, pixels[tiles32]
word colors[tiles]
byte cameraline[128*3]
PUBstart | x, y, i, r, g, b, lineNo
ser.Start(|<SerRxPin, |<SerTxPin, 115200) ' Start JDCogSerial cog'start vga
vga.start(16, @colors, @pixels, @sync)
'init colorsrepeat i from0to6*16if i & 15 < 8
colors[i] := 3<<14' redelse
colors[i] := 3<<12' green repeat i from5*16to12*16-1
colors[i] := 3<<10' Bluewaitcnt(cnt+clkfreq)
ser.Tx("U")
waitcnt(cnt+clkfreq)
repeat
ser.Tx("Z")
y := 0repeat lineNo from0to79
ser.rxFlush
ser.Tx(lineNo)
repeat i from0to383
cameraLine[i]:=ser.Rx
x := 0
i := 0repeat128' 128 pixels per line
r := cameraLine[i++] ' Read r
g := cameraLine[i++] ' Read g
b := cameraLine[i++] ' Read b' Only show the strongest colorif (r > g) and (r > b)
plotGS(x, y, r)
else
plotGS(x, y, 0) ' Plot Rif (g > r) and (g > b)
plotGS(x+256, y, g) ' Plot Gelse
plotGS(x+256, y, 0)
if (b > r) and (b > g)
plotGS(x+128, y+170, b) ' Plot Belse
plotGS(x+128, y+170, 0)
x += 2
y += 2
ser.Tx(255)
PRIplotGS(x, y, value)if value > 51
plot(x, y)
else
unplot(x, y)
if value > 102
plot(x+1, y+1)
else
unplot(x+1, y+1)
if value > 153
plot(x+1, y)
else
unplot(x+1, y)
if value > 204
plot(x, y+1)
else
unplot(x, y+1)
PRIplot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
PRIUnPlot(x,y)' if x => 0 and x < 512 and y => 0 and y < 384
pixels[y << 4 + x >> 5] |= |< x
pixels[y << 4 + x >> 5] ^= |< x
Bean I finally burned out my uOLED last night. This was my second one and I knew about their problems of removing power before issueing a power down command. I had taken many pictures of the uOLED but that was the best one. Looking at it in person except for the blue everything else in the picture the color tones looked as they did in real life. When I turned the LRF to a spot with no dark places in it the whole picture looked natural. I also have a C328 camera so I will be looking for another serial color display device without the problem posted below. Have any suggestions?
Good grief! Software (or the lack thereof) should never be allowed to damage the hardware that it drives. Would it have been so hard for the uOLED designers to include an automatic power-down sequencer? Hewlett Packard discovered this the hard way on their HP85 desktop computer that had a built-in thermal printer. Problem was, the thermal printhead was controlled in software by the main microprocessor. A bug in the user's software could cause the printhead to overheat and burn out, since there was no hardware one-shot to limit the "on" time.
Good grief! Software (or the lack thereof) should never be allowed to damage the hardware that it drives. -Phil
Agreed. HOWEVER, one of my back burner projects is just to make an LED clock. Dull and boring, but I want to do the LED multiplexing directly using my 16 little IO pins. A good challenge. Trouble is, the duty cycle is so low (like 1/24) that I have to overdrive each LED segment just to make it bright enough to see. Which means driving the LED segment directly (and briefly) from the IO pin's 5V with no resistor. No problem as long as the program keeps running. But if & when the program stops execution (code error? Moi?) during development, I'm likely to release the magic smoke from the IO pin. Oh sure, I could use an optoisolator buffer for protection, but where's the fun in that?
I am trying right now to communicate between RobotBasic and the LRF. RobotBasic has bit mapped graphics and serial communication on the computer so it may take me a while to see if I can do it that way.
The new LCD Parallax sells should display a 8 bit grey scale image from the camera on the laser range finder.using this program. I have a different model than Parallax's but it is the same type. So anybody that happens to have both give this a try. Bean I am using the original firmware's "G" command and it puts out 160 x 128 not 176 x 144 as it describes for GR_X and GR_Y. I might have to take a look again at your firmware and see if I can attain color results.
Edit: The LCD display uses RGB565 but this program converts the 8bit grey scale from the camera to the LCD's RGB565.
Con'display picture from Parallax laser range finder to 4D systems ulcd_CLKMODE = XTAL1 + PLL16X_XINFREQ = 5_000_000
ACK = 6
LCD_RX = 17'input from lcd transmit pin
LCD_TX = 16'output to lcd receive pin
LRF_RX = 15'input from laser range finder transmit pin
LRF_TX = 14'output to laser range finder receive pinVarbyte buffer[20480]
Obj
lcd : "fullduplexserial"
lrf : "fullduplexserialplus"PubMain
lcd.start(LCD_RX, LCD_TX, 0, 115200)
lrf.start(LRF_RX, LRF_TX, 0, 115200)
lrf.tx("U")
repeatuntil lrf.rx == ":"
lcd.tx($ff)
lcd.tx($cd)
get_ack
display_frame
PubGet_Ackif lcd.rxtime(1000) == ACK
returntrueelsereturnfalsePubDisplay_Frame | i, r, g, b, x, y
lrf.rxflush
lrf.tx("G")
i := 0repeat
buffer[i++] := lrf.rx
if i > 20480waitcnt(350000 + cnt)
lrf.rxflush
quit
i := 0
lcd.rxflush
repeat y from0to127repeat x from0to159
r := g := b := buffer[i++]
put_pixel(x, y, r, g, b)
PubPut_Pixel(x, y, r, g, b) | color
color := r >> 3 << 11 | g >> 2 << 5 | b >> 3
lcd.tx($ff)
lcd.tx($c1)
lcd.tx(x >> 8)
lcd.tx(x)
lcd.tx(y >> 8)
lcd.tx(y)
lcd.tx(color >> 8)
lcd.tx(color)
get_ack
Here is a slightly improved version. Got rid of not needed stuff but this version takes 30 seconds to completely display a picture from the time you hit F10. That's because this version sets up the camera for it's current environment (white balance etc). It does
print the picture faster to the screen as it ignores the ACK's for the Put_Pixel method. I believe the first version if you comment out the get_ack in the Put_Pixel method you can get a picture to print in less than 20 seconds but you have to take a couple of
pictures in a row to get the white balance etc.setup. This also prints a message to the screen asking you to wait.
Con'display picture from Parallax laser range finder to 4D systems ulcd_CLKMODE = XTAL1 + PLL16X_XINFREQ = 5_000_000
ACK = 6
LCD_RX = 17'input from lcd transmit pin
LCD_TX = 16'output to lcd receive pin
LRF_RX = 15'input from laser range finder transmit pin
LRF_TX = 14'output to laser range finder receive pinVarbyte buffer[20480]
Obj
lcd : "fullduplexserial"
lrf : "fullduplexserialplus"PubMain
lcd.start(LCD_RX, LCD_TX, 0, 115200)
lrf.start(LRF_RX, LRF_TX, 0, 115200)
clear_screen
put_string(@splash)
lrf.tx("U")
repeatuntil lrf.rx == ":"
lrf.tx("E")
repeatuntil lrf.rx == ":"
clear_screen
display_frame
PubClear_Screen
lcd.tx($ff)
lcd.tx($cd)
repeatuntil lcd.rx == ACK
PubDisplay_Frame | i, r, g, b, x, y
lrf.tx("G")
i := 0repeat
buffer[i++] := lrf.rx
if i > 20480repeatuntil lrf.rx == ":"
quit
i := 0repeat y from0to127repeat x from0to159
r := g := b := buffer[i++]
put_pixel(x, y, r, g, b)
waitcnt(clkfreq/100 + cnt)
lcd.rxflush
PubPut_Pixel(x, y, r, g, b) | color
color := r >> 3 << 11 | g >> 2 << 5 | b >> 3
lcd.tx($ff)
lcd.tx($c1)
lcd.tx(x >> 8)
lcd.tx(x)
lcd.tx(y >> 8)
lcd.tx(y)
lcd.tx(color >> 8)
lcd.tx(color)
PubPut_String(str)
lcd.tx($00)
lcd.tx($18)
lcd.str(str)
lcd.tx($00)
repeatuntil lcd.rx == ACK
Dat
Splash byte"Please wait for camera to",13,10,13,10," setup & take picture",0
Comments
It shows crude grayscale at the top and the "U" and "V" channels at the bottom.
Try holding different solid color object to the camera and see the "U" and "V" results.
Red has a "light" affect on the "V" channel.
Blue has a "light" affect on the "U" channel AND a "dark" affect on the "V" channel.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 tiles = vga#xtiles * vga#ytiles tiles32 = tiles * 32 SerRxPin = 0 ' Serial interface connect to Sout on LRF SerTxPin = 1 ' connect to Sin on LRF OBJ vga : "vga_512x384_bitmap" ser : "JDCogSerial" ' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/) VAR long sync, pixels[tiles32] word colors[tiles] PUB start | h, i, j, k, x, y, value ser.Start(|<SerRxPin, |<SerTxPin, 19200) ' Start JDCogSerial cog 'start vga vga.start(16, @colors, @pixels, @sync) 'init colors repeat i from 0 to tiles - 1 colors[i] := $FC00 ' White on black waitcnt(cnt+clkfreq) ser.Tx("U") waitcnt(cnt+clkfreq) repeat waitcnt(cnt+clkfreq/4) ser.RxFlush ser.Tx("Y") y := 0 repeat 80 x := 0 repeat 64 value := ser.Rx ' Read Y1 plotGS(x, y, value) value := ser.Rx ' Read U plotGS(x>>1, y+170, value) value := ser.Rx ' Read Y2 plotGS(x+2, y, value) value := ser.Rx ' Read V plotGS(x>>1+138, y+170, value) x += 4 y += 2 PRI plotGS(x, y, value) if value > 51 plot(x, y) else unplot(x, y) if value > 102 plot(x+1, y+1) else unplot(x+1, y+1) if value > 153 plot(x+1, y) else unplot(x+1, y) if value > 204 plot(x, y+1) else unplot(x, y+1) PRI plot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x PRI UnPlot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x pixels[y << 4 + x >> 5] ^= |< x
Bean
Nice. If you hold up a large blue object you should see a pattern in the U and V fields.
I am working on a new version that will capture a frame and then let the remote request the data one line at a time. This will allow you to communicate much faster by using a buffer to store 1 line, process it, then request another line. The lines can be requested in any order. So you can just request the line you are interested in. Requesting a line > 79 terminates the command.
I'd also like to allow the single line data to be returned in RGB format (16-bit or 24-bit). I'm working on that part now.
Bean
Here is the latest version that returns lines in RGB (8-bits each, 384 bytes per line).
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 tiles = vga#xtiles * vga#ytiles tiles32 = tiles * 32 SerRxPin = 0 ' Serial interface connect to Sout on LRF SerTxPin = 1 ' connect to Sin on LRF OBJ vga : "vga_512x384_bitmap" ser : "JDCogSerial" ' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/) VAR long sync, pixels[tiles32] word colors[tiles] byte cameraline[128*3] PUB start | x, y, i, value, lineNo ser.Start(|<SerRxPin, |<SerTxPin, 115200) ' Start JDCogSerial cog 'start vga vga.start(16, @colors, @pixels, @sync) 'init colors repeat i from 0 to tiles - 1 colors[i] := $FC00 ' White on black waitcnt(cnt+clkfreq) ser.Tx("U") waitcnt(cnt+clkfreq) repeat ser.Tx("Z") y := 0 repeat lineNo from 0 to 79 ser.rxFlush ser.Tx(lineNo) repeat i from 0 to 383 cameraLine[i]:=ser.Rx x := 0 i := 0 repeat 128 ' 128 pixels per line value := cameraLine[i++] ' Read r plotGS(x, y, value) value := cameraLine[i++] ' Read g plotGS(x+256, y, value) value := cameraLine[i++] ' Read b plotGS(x+128, y+170, value) x += 2 y += 2 ser.Tx(255) PRI plotGS(x, y, value) if value > 51 plot(x, y) else unplot(x, y) if value > 102 plot(x+1, y+1) else unplot(x+1, y+1) if value > 153 plot(x+1, y) else unplot(x+1, y) if value > 204 plot(x, y+1) else unplot(x, y+1) PRI plot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x PRI UnPlot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x pixels[y << 4 + x >> 5] ^= |< x
Bean
Bean
Con _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 ack = $06 ' Acknowledge byte nak = $15 ' Invalid command byte Var byte cameraline[128*3] Obj db : "pcfullduplexserial" fd : "fullduplexserial" Pub start| i,j,x,y fd.start(6, 7, 0, 115200) ' db.init db.addport(0, 31, 30, -1, -1, 0, 0, 19200) 'debug port db.addport(1, 4, 5, -1, -1, 0, 0, 115200) 'uoled db.start waitcnt(clkfreq*3+cnt) fd.rxflush fd.tx("U") repeat until fd.rx == ":" db.str(0, string("Camara online",13)) db.rxflush(1) db.tx (1, "U") waitack db.str(0, string("uOLED ready",13)) waitcnt(1600000+cnt) erase repeat get Pub waitack repeat until db.rx(1) == ack Pub erase db.tx (1, "E") waitack Pub get | i, r, g, b, x, y, z fd.tx("Z") repeat y from 0 to 79 fd.rxflush fd.tx(y) repeat i from 0 to 383 cameraline[i]:=fd.Rx i := 0 repeat x from 0 to 127 r := cameraline[i++] g := cameraline[i++] b := cameraline[i++] plot(x, y, r, g, b) Pub plot(x, y, r, g, b) ' X : 0 to 127 ' Y : 0 to 127 ' Red : 0 to 255 ' Green : 0 to 255 ' Blue : 0 to 255 r := r >> 3 << 11 | (g >> 2 << 5) | (b >> 3) db.tx(1, "P") db.tx(1, x) db.tx(1, y) db.tx(1, r.byte[1]) db.tx(1, r.byte[0]) waitack
By "everything else looks natural" you mean the image color look good ?
I've noticed that sometimes black shows blocks of white (full on), but I have the variables limited so I can't tell why it does that sometimes. That may be the blue you are seeing instead of black.
Try to get a better picture of the oLED if you can. I'd love to see a color image.
Bean
Here is a version of the viewer that shows color objects.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 tiles = vga#xtiles * vga#ytiles tiles32 = tiles * 32 SerRxPin = 0 ' Serial interface connect to Sout on LRF SerTxPin = 1 ' connect to Sin on LRF OBJ vga : "vga_512x384_bitmap" ser : "JDCogSerial" ' Full-duplex serial communication (Carl Jacobs, http://obex.parallax.com/objects/398/) VAR long sync, pixels[tiles32] word colors[tiles] byte cameraline[128*3] PUB start | x, y, i, r, g, b, lineNo ser.Start(|<SerRxPin, |<SerTxPin, 115200) ' Start JDCogSerial cog 'start vga vga.start(16, @colors, @pixels, @sync) 'init colors repeat i from 0 to 6*16 if i & 15 < 8 colors[i] := 3<<14 ' red else colors[i] := 3<<12 ' green repeat i from 5*16 to 12*16-1 colors[i] := 3<<10 ' Blue waitcnt(cnt+clkfreq) ser.Tx("U") waitcnt(cnt+clkfreq) repeat ser.Tx("Z") y := 0 repeat lineNo from 0 to 79 ser.rxFlush ser.Tx(lineNo) repeat i from 0 to 383 cameraLine[i]:=ser.Rx x := 0 i := 0 repeat 128 ' 128 pixels per line r := cameraLine[i++] ' Read r g := cameraLine[i++] ' Read g b := cameraLine[i++] ' Read b ' Only show the strongest color if (r > g) and (r > b) plotGS(x, y, r) else plotGS(x, y, 0) ' Plot R if (g > r) and (g > b) plotGS(x+256, y, g) ' Plot G else plotGS(x+256, y, 0) if (b > r) and (b > g) plotGS(x+128, y+170, b) ' Plot B else plotGS(x+128, y+170, 0) x += 2 y += 2 ser.Tx(255) PRI plotGS(x, y, value) if value > 51 plot(x, y) else unplot(x, y) if value > 102 plot(x+1, y+1) else unplot(x+1, y+1) if value > 153 plot(x+1, y) else unplot(x+1, y) if value > 204 plot(x, y+1) else unplot(x, y+1) PRI plot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x PRI UnPlot(x,y) ' if x => 0 and x < 512 and y => 0 and y < 384 pixels[y << 4 + x >> 5] |= |< x pixels[y << 4 + x >> 5] ^= |< x
Bean
-Phil
Bean
Agreed. HOWEVER, one of my back burner projects is just to make an LED clock. Dull and boring, but I want to do the LED multiplexing directly using my 16 little IO pins. A good challenge. Trouble is, the duty cycle is so low (like 1/24) that I have to overdrive each LED segment just to make it bright enough to see. Which means driving the LED segment directly (and briefly) from the IO pin's 5V with no resistor. No problem as long as the program keeps running. But if & when the program stops execution (code error? Moi?) during development, I'm likely to release the magic smoke from the IO pin. Oh sure, I could use an optoisolator buffer for protection, but where's the fun in that?
Edit: The LCD display uses RGB565 but this program converts the 8bit grey scale from the camera to the LCD's RGB565.
Con 'display picture from Parallax laser range finder to 4D systems ulcd _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 ACK = 6 LCD_RX = 17 'input from lcd transmit pin LCD_TX = 16 'output to lcd receive pin LRF_RX = 15 'input from laser range finder transmit pin LRF_TX = 14 'output to laser range finder receive pin Var byte buffer[20480] Obj lcd : "fullduplexserial" lrf : "fullduplexserialplus" Pub Main lcd.start(LCD_RX, LCD_TX, 0, 115200) lrf.start(LRF_RX, LRF_TX, 0, 115200) lrf.tx("U") repeat until lrf.rx == ":" lcd.tx($ff) lcd.tx($cd) get_ack display_frame Pub Get_Ack if lcd.rxtime(1000) == ACK return true else return false Pub Display_Frame | i, r, g, b, x, y lrf.rxflush lrf.tx("G") i := 0 repeat buffer[i++] := lrf.rx if i > 20480 waitcnt(350000 + cnt) lrf.rxflush quit i := 0 lcd.rxflush repeat y from 0 to 127 repeat x from 0 to 159 r := g := b := buffer[i++] put_pixel(x, y, r, g, b) Pub Put_Pixel(x, y, r, g, b) | color color := r >> 3 << 11 | g >> 2 << 5 | b >> 3 lcd.tx($ff) lcd.tx($c1) lcd.tx(x >> 8) lcd.tx(x) lcd.tx(y >> 8) lcd.tx(y) lcd.tx(color >> 8) lcd.tx(color) get_ack
print the picture faster to the screen as it ignores the ACK's for the Put_Pixel method. I believe the first version if you comment out the get_ack in the Put_Pixel method you can get a picture to print in less than 20 seconds but you have to take a couple of
pictures in a row to get the white balance etc.setup. This also prints a message to the screen asking you to wait.
Con 'display picture from Parallax laser range finder to 4D systems ulcd _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 ACK = 6 LCD_RX = 17 'input from lcd transmit pin LCD_TX = 16 'output to lcd receive pin LRF_RX = 15 'input from laser range finder transmit pin LRF_TX = 14 'output to laser range finder receive pin Var byte buffer[20480] Obj lcd : "fullduplexserial" lrf : "fullduplexserialplus" Pub Main lcd.start(LCD_RX, LCD_TX, 0, 115200) lrf.start(LRF_RX, LRF_TX, 0, 115200) clear_screen put_string(@splash) lrf.tx("U") repeat until lrf.rx == ":" lrf.tx("E") repeat until lrf.rx == ":" clear_screen display_frame Pub Clear_Screen lcd.tx($ff) lcd.tx($cd) repeat until lcd.rx == ACK Pub Display_Frame | i, r, g, b, x, y lrf.tx("G") i := 0 repeat buffer[i++] := lrf.rx if i > 20480 repeat until lrf.rx == ":" quit i := 0 repeat y from 0 to 127 repeat x from 0 to 159 r := g := b := buffer[i++] put_pixel(x, y, r, g, b) waitcnt(clkfreq/100 + cnt) lcd.rxflush Pub Put_Pixel(x, y, r, g, b) | color color := r >> 3 << 11 | g >> 2 << 5 | b >> 3 lcd.tx($ff) lcd.tx($c1) lcd.tx(x >> 8) lcd.tx(x) lcd.tx(y >> 8) lcd.tx(y) lcd.tx(color >> 8) lcd.tx(color) Pub Put_String(str) lcd.tx($00) lcd.tx($18) lcd.str(str) lcd.tx($00) repeat until lcd.rx == ACK Dat Splash byte "Please wait for camera to",13,10,13,10," setup & take picture",0