OneWire Temp causing jumpy overlay

Store Forums Video Experimenter Bugs/Problems OneWire Temp causing jumpy overlay

Viewing 15 posts - 1 through 15 (of 17 total)
  • Author
    Posts
  • #469
    pinkstond
    Member

    On my project everything was displaying and working correctly! Until… I added a this:

    http://bildr.org/2011/07/ds18b20-arduino/

    After adding this the text is jumping from it’s original position to various spots horizontal to it’s current position. It’s also jumping up and down by 1-2 px. As soon as I take out the “getTemp” float, then the text is all back to normal. I’ll be the first to admit I am very new to arduino in general, I’m quick to copy,paste, modify and google for hours until I learn things and get them to work how I want. However I’ve been stumped on this one for some time. I’m guessing maybe it’s some kind of compatibility issue, or maybe some kind of interference?

    Regardless, I would very much appreciate any help I can get in tracing and correcting this problem.

    Thanks!
    Derek

    P.S. To see the undesired effect, visit this link: http://homewebwatch.com/test123.php?passwd=helpme (not the fastest, but it gets the point across)

    #1216
    Michael
    Keymaster

    The example on that site has the sensor connected to pin 2 on the Arduino. Is that what you did? Because that would mess up the video timing, since the Video Experimenter uses pin 2. If so, you could try another pin (like 3).

    #1283
    pinkstond
    Member

    Sorry, should have mentioned that. It is currently on D10.

    #1284
    Michael
    Keymaster

    Is your version of the OneWire library disabling/enabling interrupts? The current version does this, and that will interfere with the video timing. The TVout library relies on interrupts to perform the timing.

    How often are you polling the sensor? You could arrange for the sensor reading to only happen during the video blanking interval. TVout has a way to set a hook function to be called during the VBI. You pass a pointer to the function you want called.

    tv.set_vbi_hook(&readSensor);

    Where you have a function called readSensor that does the work:

    void readSensor() {
    // do the work of reading the sensor
    }

    And you certainly don’t need to read the sensor 60 times per second. Use a counter to arrange for it to happen every 60th call to readSensor or something. Make sense?

    #1285
    pinkstond
    Member

    Hrm, I’m sure I am doing this all wrong… But when ever I did what you said I don’t get anything displayed at all. Right after it uploads I get a big block of squiggly lines that fill the screen for a second and then nothing..

    #1286
    pinkstond
    Member

    I’ve also tried this method:

    viewtopic.php?f=25&t=2394

    Ignore the sloppiness, and the noobness. Lots of copy and pasting and moving stuff around to see if it’ll work right.

    #include 
    #include
    #include
    #define W 136
    #define H 96

    OneWire ds1(10);
    TVout tv;
    unsigned char x,y;
    unsigned char originx = 5;
    unsigned char originy = 80;
    unsigned char plotx = originx;
    unsigned char ploty = 40;
    char emf[10];
    char temp[4];
    float val;
    float tmp;
    unsigned short avg;
    char inVBI;

    void setup() {
    tv.set_vbi_hook(&setVBIFlag);
    tv.begin(NTSC, W, H);
    initOverlay();
    tv.select_font(font6x8);
    tv.fill(0);
    Serial.begin(9600);
    }

    void initOverlay() {
    TCCR1A = 0;
    TCCR1B = _BV(CS10);
    TIMSK1 |= _BV(ICIE1);
    EIMSK = _BV(INT0);
    EICRA = _BV(ISC11);
    }
    ISR(INT0_vect) {
    display.scanLine = 0;
    }

    void setVBIFlag() {
    inVBI = true;
    }

    void loop() {
    if (inVBI) {

    delay(2000);
    byte data1[3];
    byte addr1[0];

    if ( !ds1.search(addr1)) {
    //no more sensors on chain, reset search
    // ds1.reset_search();
    // return -1000;
    }

    ds1.reset();
    ds1.select(addr1);
    ds1.write(0x44,1); // start conversion, with parasite power on at the end
    byte present = ds1.reset();
    ds1.select(addr1);
    ds1.write(0xBE); // Read Scratchpad

    //No Prob Here
    for (int p = 0; p < 9; p++) { // we need 9 bytes
    data1[p] = ds1.read();
    }

    ds1.reset_search();

    float MSB = ((data1[1] << 8));
    float LSB = (data1[0]);

    float tempRead = (MSB + LSB); //using two's compliment
    float tmp = tempRead / 16 * 1.8 + 32;
    dtostrf(tmp, 1, 1, temp);
    int ary1[300];
    for(int b = 0; b < 300; ++b) {
    ary1 = analogRead(1);
    avg += ary1
    ;
    }

    val = avg / 300;
    val = constrain(val, 0, 100);
    val = map(val, 0, 100, 0, 255);
    val = val *.1;
    dtostrf(val, 1, 1, emf);
    avg = 0;
    inVBI = false;

    }
    tv.print(0, 89, "EMF");
    tv.print(20, 89, emf);
    tv.print(24, 80, "*F");
    tv.print(0, 80, temp);
    }
    #1279
    Michael
    Keymaster

    pinkstond, if you want people to help you with your code, you need to organize it and format it so it’s readable. People are busy, so you need to make the effort…

    You have a delay(2000) within the “if (inVBI)” block. The VBI is only a couple of milliseconds long, so you can’t wait for 2 seconds. Move that delay out of there.

    #1282
    pinkstond
    Member

    I’m sorry, I’m really new to this and sometimes when I work days on a simple issue like that I get too lazy and quick to get an answer. The code below I stripped out the information that is not relevant to this issue and organized it the best I can.

    #include 
    #include
    #include

    OneWire ds1(10);
    TVout tv;
    unsigned char x,y;
    unsigned char originx = 5;
    unsigned char originy = 80;
    unsigned char plotx = originx;
    unsigned char ploty = 40;
    char temp[10];


    void setup() {
    tv.begin(NTSC, 120, 96);
    initOverlay();
    tv.select_font(font6x8);
    tv.fill(0);
    tv.set_vbi_hook(&getTemp);
    }

    void initOverlay() {
    TCCR1A = 0;
    TCCR1B = _BV(CS10);
    TIMSK1 |= _BV(ICIE1);
    EIMSK = _BV(INT0);
    EICRA = _BV(ISC11);
    }

    ISR(INT0_vect) {
    display.scanLine = 0;
    }

    void loop() {

    tv.print(23, 80, "*F");
    tv.delay_frame(1);
    dspData(); //Display the recieved temp from getTemp
    }


    //Get the temp from the sensor.
    void getTemp() {

    byte data1[12];
    byte addr1[8];

    if ( !ds1.search(addr1)) {
    }

    ds1.reset();
    ds1.select(addr1);
    ds1.write(0x44,1);
    byte present = ds1.reset();
    ds1.select(addr1);
    ds1.write(0xBE);

    for (int p = 0; p < 9; p++) {
    data1[p] = ds1.read();
    }

    ds1.reset_search();
    float MSB = ((data1[1] << 8));
    float LSB = (data1[0]);
    float tempRead = (MSB + LSB);
    float tmp = tempRead / 16 * 1.8 + 32 - 5; //Convert Celsius to Fahrenheit
    dtostrf(tmp, 1, 1, temp); //Convert the float to a string so it can be displayed properly
    }

    //Display the temp
    void dspData() {
    tv.print(0, 80, temp);
    }

    I didn’t know if I needed to call the getTemp function in the loop, but I have tried both ways. With the code above I end up getting this on the video output:

    #1276
    Michael
    Keymaster

    It’s better to set a flag in your VBI hook function, then act on that flag in loop(). The reason is that you don’t want to do sensor communication in the TVout interrupt handler.

    So I’d try this:
    Declare a flag and a count variable at the beginning of your code.

    volatile boolean inVBI = false;
    int vbiCount = 0;

    In setup(), do this:

    tv.set_vbi_hook(&setVBIFlag);

    Implement setVBIFlag as you did before:

    void setVBIFlag() {
    inVBI = true;
    }

    loop() should inspect the inVBI variable and get sensor data only once per second

    void loop() {
    if (inVBI) {
    if (++vbiCount == 60) {
    // only fetch temperature every 60th frame (once per second)
    getTemp();
    tv.print(23, 80, "*F");
    dspData(); //Display the recieved temp from getTemp
    vbiCount = 0; // reset counter
    }
    inVBI = false; // reset flag
    }
    }

    Also, keep in mind that comminicating with a sensor like this in an interrupt driven program is not really a beginner project. It’s much easier to simply read an analog sensor versus one that has its own communication protocol. The current version of the OneWire library turns interrupts on and off, and that interferes with video.

    #1277
    pinkstond
    Member

    Added and arranged things as you said to, and it’s back to it’s original behavior. The temp shows up fine, but when the temp updates it jumps across the screen. It’s almost like the VBI isn’t enough time for the code to run? Or the VBI isn’t happening?

    I drove around town and tried to find a analog temp sensor since I’ve lost so much time on this, but was unable to find one locally.

    I think I might just find an analog one online, but it would be nice to find the solution to this issue to possibly help others in the same position in the future. I just don’t want to use up more of your time.

    #1278
    Michael
    Keymaster

    I think your sensor code is working fine since the temperature value is changing (I’m looking at your live feed).

    Maybe your string buffer handling isn’t working right. I use sprintf, like:

    sprintf(temp, "%.1f", tmp);

    You can verify whether your string handling is working by just printing a constant string to the screen and see if it jumps around.

    tv.print(0, 80, "foo");
    #1269
    Michael
    Keymaster

    …this is cool that I’m watching you experiment on your live feed….

    looks like a constant “?” and “foo” still jump…

    #1270
    pinkstond
    Member

    Nope. Its not the string, it’s the part of the sensor reading. I did have another analog sensor hooked up and was displaying it on the screen the same way, and it never skipped until I added the code under the getTemp function. I’ve tried to narrow down what part of that is doing it with no luck.

    I added

    tv.print(0, 70, "foo");

    and commented out these two

    tv.print(0, 80, temp);
    dtostrf(tmp, 1, 1, temp);

    and foo is still blinking from what I am guessing is the part where it’s pulling the info from the sensor.

    #1271
    Michael
    Keymaster

    Yeah, the OneWire library is messing with interrupts. Please look at the OneWire code and see if it is turning interrupts on and off. If you see lines “noInterrupts()” and “interrupts()”, comment them out. I think the communication might still work.

    I’m sitting here watching you — it’s funny. I can see when you are uploading new code onto the Arduino. My kids think it’s cool, too.

    #1272
    Michael
    Keymaster

    “Hey Michael’s Kids”….thanks buddy.

Viewing 15 posts - 1 through 15 (of 17 total)
  • You must be logged in to reply to this topic.