Giter VIP home page Giter VIP logo

Comments (20)

indrekluuk avatar indrekluuk commented on June 8, 2024

I have never tried it with MEGA myself, but it seems to me that you are mostly correct.

I added "#if defined" for "AVR_ATmega1280" and "AVR_ATmega2560" so it would compile, but there probably should be completely separate section for MEGA with its own definitions (just like for STM32)

But you can add your own definitions on top of the file before all "#include" statements since all the definitions are checked by "#ifndef" before defining them in the CameraOV7670.h

SIOC -> PIN 21 - PD0
SIOD -> PIN 20 - PD1
I am using the Wire library to configure the camera. So this should work by default and no additional configuration is necessary.

VSYNC -> PIN 46 - PL5
Should have definition:
#define OV7670_VSYNC (PINL & 0b00100000)

HREF -> PIN47 - PL4
My code is not using HREF at all. I count pixels after the VSYNC signal. So there is no definition needed.

PCLK -> PIN49 - PL2
Should have definitions:
#define OV7670_PIXEL_CLOCK_PIN 49
#define OV7670_PIXEL_CLOCK (PINL & 0b00000100)

XCLK - > PIN48 - PL3
This is a bit more complicated. This needs to be a PWM pin. By Google'ing I found that PWM pins for MEGA are pins 2 - 13 and 44 - 46. Additionally you need to be able to configure it to emit 8Mhz pulses.
For UNO/Nano I didn't actually do it myself but found the solution by googling.

It is probably something similar to this (as far as I know it uses timer2 to make the pulses):
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS20);
OCR2A = 1;
OCR2B = 0

D0..D7 -> PIN37..PIN30 -> PC0..PC7 (in this way we do need to OR two different port).
Yes, this is simpler than for Uno
#define OV7670_READ_PIXEL_BYTE(b) b = PINC

Note that since it is faster it will mess up the timing for the pixel read cycle in the 10fps version in the "BufferedCameraOV7670_QQVGA_10hz.h"
So you should first try to get it working with a slow frame rate (one or two frames per second). If that works then it is easier to get the faster frame rate working.


I have a MEGA so at some point I will try it myself also. But if you get it working please let me know.

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi,
I have found this information:

Arduino mega pins and hardware Timers

Pin Timer
46 OC5C
45 OC5B
44 OC5A
13 OC0B //Caution: this one directly effects major timing { i.e delay and millis}
12 OC1B
11 OC1A
10 OC2A
9 OC2B
8 OC4C
7 OC4B
6 OC4A
5 OC3A
4 OC0B //Caution: this one directly effects major timing { i.e delay and millis}
3 OC3C
2 OC3B

another way to look at this is:
timer 0 —– pin 4, 13 *there’s alot of misinfo about Pin-13 but after checking 13
timer 1 —– pin 11, 12, 13 it is in fact on Timer 0 “Thx Max K.”
timer 2 —– pin 9, 10
timer 3 —– pin 2, 3, 5
timer 4 —– pin 6, 7, 8
timer 5 —– pin 44, 45, 46

Timer 0,2 are 8bits, and timer 1,3,4,5 are 16bits.

So I think I will change the setting in this way

SIOC -> PIN 21 - PD0
SIOD -> PIN 20 - PD1
No define but this will be the wiring

VSYNC -> PIN 48 - PL3
Should have definition:
#define OV7670_VSYNC (PINL & 0b00001000)

//HREF -> no connection

XCLK - > PIN47 - PL4
TCCR4A = _BV(COM4A1) | _BV(COM4B1) | _BV(WGM21) | _BV(WGM20);
TCCR4B = _BV(WGM22) | _BV(CS20);
OCR4A = 1;
OCR4B = 0;

I will test it I will tell you
Regards
Giancarlo

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

I googled "arduino mega 8mhz output" and the first result gave me this:

pinMode(11, OUTPUT); // select Pin as ch-A
TCCR1A = B01000011; // Fast PWM change at OCR1A
TCCR1B = B11001; // System clock
OCR1A = 0; // 8 MHz

I tried it and checked it with Oscilloscope. This makes pin 11 to pulse at 8Mhz on Arduino Mega

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi,
there are some news but not completle good news.
I have used this setting
#if defined(AVR_ATmega2560) || defined(AVR_ATmega1280)
// VSYNC -> PIN42 - PL7
#ifndef OV7670_VSYNC
#define OV7670_VSYNC (PINL & 0b10000000)
#endif

//PCLK -> PIN43 - PL6
#define OV7670_PIXEL_CLOCK_PIN 43
#define OV7670_PIXEL_CLOCK (PINL & 0b01000000)

// (PIN 22..29)
#ifndef OV7670_READ_PIXEL_BYTE
#define OV7670_READ_PIXEL_BYTE(b) b = PINA
#endif

// pin 46 to 8Mhz (LiveOV7670Library clock)
//XCLK - > PIN46 - PL3
#ifndef OV7670_INIT_CLOCK_OUT
#define OV7670_INIT_CLOCK_OUT
pinMode(45, OUTPUT);
TCCR5A = B01000011;
TCCR5B = B11001;
OCR5A = 0;
OCR5B = 0
#endif

#endif

I have got to move from PIN45 to PIN46. I don't know why but I do not have the Oscilloscope so I cannot understand it I have used wrong setting or it doesn' work at all.
Now the camera inizialize and start grabbing.
But I do not get a image, or better I'm not yet able to see a image, because I'm using a a TFT LCD shield with 8bit data and I'm using MCUFRIEND_kbv to display the image.
I will try to save the image to see if it a grabbing issue or a displaying issue.
Regards
Giancarlo

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

I tried and checked with Oscilloscope. It works. This puts PIN 46 to 8Mhz (in the code you pasted here had "pinMode(45, OUTPUT);" I changed it to 46):
pinMode(46, OUTPUT);
TCCR5A = B01000011;
TCCR5B = B11001;
OCR5A = 0;
OCR5B = 0;

Did camera.init(); return true? If yes then that means that configuration was successful.
If camera init is successful then you should try to check if you get VSYNC. If you get VSYNC then the camera should be working.

How do you send pixel data to the screen? Do you use "drawPixel" method from MCUFRIEND_kbv? If yes then it is way too slow. I wrote bytes directly to SPI, but since your screen takes 8 bits in parallel then maybe pushColors is fast enough.

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi.
the camera init and also I get the VSYNC.
I have also moved from drawPixel to pushColors.
Right now I see something in the display and it refresh fast (I do not know the real speed), but is is not a image. I think the issue is the time for write the pixel. If the time for writing a pixel is more that a pixelclock, the next pixel read will not be the next pixel in the image. Is it right ?

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

Do you read and write pixels one by one or line by line?
Can you show the code you have done?
It probably is timing issue.

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

LiveOV7670_AS8.zip

this is all the code.
I'm sure that it is timing issue, I will try to check how much time I spend to read a full image to see if I'm in time :-)

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

You can delete the "asm volatile("nop");" lines in "sendPixel". I needed them since I wrote directly to the SPI register and didn't want to waist time on checking SPI status. So I just waited a constant time after sending a byte before sending the next one. But pushColors does all the checking so no extra delay is necessary.

You can make the pixels sending faster by calling pushColors with line buffer instead of doing one pixel at the time. Something like this:
tft.pushColors((uint16_t *)camera.getPixelBuffer(), camera.getPixelBufferLength() / 2, first);
(divided by 2 since it gives byte count not pixel count)

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi,
I have tested how much time I need for a single frame.
Using
BufferedCameraOV7670_QVGA camera(CameraOV7670::PIXEL_RGB565, BufferedCameraOV7670_QVGA::FPS_1p25_Hz);

I have got to reenable interrupts otherwise millis() doesn't work.
Based on my test I need 2380 ms to capture and display all the pixel. But if the FPS is 1.25 every 800 ms I will have a new frame. This means that MCUFRIEND_kbv is not fast enought.
I have also tested your suggestion of displaying a full line with tft.pushColors, but it doesn't change the time is the same.
Does you have any suggestion on how I can try to display a image for now 1 image every 3 or 4 sec will be fine, becuase first of all I would like to be sure that the camera works.
Regards_

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

You can decrease FPS by increasing camera pre-scaler.
In the BufferedCameraOV7670_QVGA file there is this function

  static uint8_t getPreScalerForFps(FramesPerSecond fps) {
    switch (fps) {
      default:
      case FPS_2p5_Hz:
        return 3;
      case FPS_2_Hz:
        return 4;
      case FPS_1p66_Hz:
        return 5;
      case FPS_1p43_Hz:
        return 6;
      case FPS_1p25_Hz:
        return 7;
    }
  }

If you return a bigger number then the frame rate should be lower.

Another option is to try first with smaller resolution (QQVGA - 160x120). You can display the image in the corner of the screen. This reduces pixel count four times.

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi, I will try your suggestion.
I would like also to test a different way but before start coding I would like to ask you if you already has tried it.
I have same experience interfacing cameras but of course on PC and using framegrabbers, and I would like to use a similar interface. I would like to attach a interrupt to PCLK so that every time that it change, I will call the function to read the pixel, and display it. Of course read the pixel and display it need to be run in a PCLK cycle. I could also attach a interrupt to HREF so that I know when start a new line and on VSYNC to know when start a new frame. Have you tested the interrupt approch ? what do you think ?
Regards

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

You might be able to use interrupts with slow frame rates.

Here is an oscilloscope image of QQVGA(160x120)@10FPS. Yellow is pixel clock from the camera and blue is SPI clock to the screen. It is line by line reading and writing.
10fps
There is no way to fit this into one pixel cycle on Arduino at that frame rate. Also to get that speed I read the pixels blindly without even checking pixel clock because this waists too much clock cycles.

I have read that reaction time for Arduino input PIN's interrupt is 4 clock cycles. You probably have to set up the interrupt yourself to get that fast reaction time. It is likely that Arduino framework adds its own code before and after interrupt call if you use "attatchInterrupt" method.

Another thing is that if you use smaller resolution than 640x480 then you are better off reading the line first and then writing to the screen. This camera reduces resolution by adding blank lines.
For example with 320x240 resolution you get an image line and then there is pause for the equivalent time of a line. You can see the same thing in the above image. Since it is QQVGA the resolution is reduced four times. As you can see by the yellow line it sends a line and then there is pause for next three lines. It is good idea to use that for sending data to screen. Of course if you use full 640x480 resolution then you have to read pixel and send it immeiately.

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi,
I have done some progress but not yet a image from the real world.
I have added some function to your code to be able to see the color bar and also to disable HREF on blank line.
You can find the code in this attachment and if you want you can include in your code.
LiveOV7670Library.zip

This is the image of the color bar that I get
p_20180624_002630_1_p

and this is my code
LiveOV7670_AS8.zip

I'm not sure that it is the right color bar because if I turn off the color bar I do not get a good image from the real world.
Could you take a image of your color bar.

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

Thanks! I added a method to display color bars to the library in my github repository.

I actually discovered that you can either have color bars with solid colors or transparently overlayed on the image. So I made the configuration function like this:

void CameraOV7670Registers::setShowColorBar(bool transparent) {
  if (transparent) {
    setRegisterBitsOR(REG_COM7, COM7_COLOR_BAR);
  } else {
    setRegisterBitsOR(REG_COM17, COM17_CBAR);
  }
}

Color bars:
img_1497

Color bars with transparent overlay:
img_1496

from liveov7670.

giancarlodomanico avatar giancarlodomanico commented on June 8, 2024

Hi,
I haven't seen the trasparent color bar becuase I'm not able to see a real image, this is why I set both register.
Your color bar is :
white
yellow
cyan
green
magenta
violet
red
blu
black
Is It right ?
My color bar has not the right color. I need to investigate about it.
Thank you for your help.

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

Yes.
It looks like your color bars are horizontal. They are vertical on my screen. It seems like height and width are switched.

What happens if you set color bars to be transparent? does it show random garbage under the colors?
Maybe you should switch pixel byte order?

from liveov7670.

zoomx avatar zoomx commented on June 8, 2024

indrekluuk,
have you added the new method in the STM32 version too?

from liveov7670.

indrekluuk avatar indrekluuk commented on June 8, 2024

zoomx, I have now updated the STM32 project also.

from liveov7670.

zoomx avatar zoomx commented on June 8, 2024

Wow thanks!

from liveov7670.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.