EcoModder.com

EcoModder.com (https://ecomodder.com/forum/)
-   OpenGauge / MPGuino FE computer (https://ecomodder.com/forum/opengauge-mpguino-fe-computer.html)
-   -   Signal Generator (https://ecomodder.com/forum/showthread.php/signal-generator-2857.html)

dcb 06-06-2008 03:36 AM

Signal Generator
 
Not sure where this goes, but it is basically two duinos. One (the plain chip and crystal) has been programmed in arduino to simulate a vehicle vss and injector signal, and the other is running the mpguino code. The test code is at the bottom. Now it isn't single digit microsecond accurate, but it also isn't limited by the number of timers either. With this approach you can generate a lot of different signals, i.e. buttons, etc. And since both the guino and the signal generator are connected to the computer simultaneously it is quite possible to have a PC program with all kinds of scenarios that tell the signal generator what to generate and get the result from the gunio to see if it is correct.

http://ecomodder.com/wiki/images/c/c...generator1.JPG
http://ecomodder.com/wiki/images/d/d...generator2.JPG
http://ecomodder.com/wiki/images/4/4c/TestWiring.gif

PHP Code:

//GPL Software 
//cheesey signal generator, made for bench testing the mpguino
//signal generator pins
#define sig1Pin 2   //inj
#define sig2Pin 3   

//overflow counter used by millis()   
extern volatile unsigned long timer0_overflow_count;   
unsigned long lastMicroSeconds=millis() * 1000;
unsigned long microSeconds (void){  
  
unsigned long tmp_timer0_overflow_count
  
unsigned long tmp
  
byte tmp_tcnt0
  
cli(); //disable interrupts 
  
tmp_timer0_overflow_count timer0_overflow_count
  
tmp_tcnt0 TCNT0
  
sei(); // enable interrupts 
  
tmp = ((tmp_timer0_overflow_count << 8) + tmp_tcnt0) * 4;  
  if((
tmp<=lastMicroSeconds) && (tmp<4293967296)) 
    return 
microSeconds();  
  
lastMicroSeconds=tmp;
  return 
tmp;  



unsigned long elapsedMicroseconds(unsigned long startMicroSecondsunsigned long msec ){   
  if(
msec >= startMicroSeconds)   
    return 
msec-startMicroSeconds;   
  return 
4294967295 - (startMicroSeconds-msec);   
}   


/*
metro signal generator notes:
//#define vssPulsesPerMile 10000ul   
//#define microSecondsPerGallon 267857143ul //injector flow rate   
@20mph, 4th gear
~48mpg
~44000uS injector open time per 1/2 second
18 inj pulses per 1/2 second
55 vss pulses per 1/2 second
therefore: 
sig1, off for 2444uS, on for 25333uS
sig2, on for 16000uS, off for 2180uS
*/
unsigned long sig1Start//injector
byte sig1State HIGH//injector 1=closed
unsigned long sig2Start//vss
byte sig2State LOW//vss

#define sig1PinOffTime 2444
#define sig1PinOnTime 25333
#define sig2PinOnTime 16000
#define sig2PinOffTime 2180


void setup (void){    
  
pinMode(sig1Pin,OUTPUT);   
  
pinMode(sig2Pin,OUTPUT);   
}    

void loop (void){    

  
digitalWrite(sig1Pin,sig1State);
  
digitalWrite(sig2Pin,sig2State);
  
sig1Start microSeconds();
  
sig2Start sig1Start;
  while(
true){ 
    
//snapshot of the time variables:
    
unsigned long tmp microSeconds();  
    
unsigned long tmp1 elapsedMicroseconds(sig1Starttmp);  
    
unsigned long tmp2 elapsedMicroseconds(sig2Starttmp);  

    
//sig 1 timing logic
    
if(sig1State==HIGH){
      if (
tmp1>=sig1PinOnTime){
        
sig1Start=tmp;
        
sig1State=LOW;
        
digitalWrite(sig1Pin,sig1State);
      }
    }else{
      if (
tmp1>=sig1PinOffTime){
        
sig1Start=tmp;
        
sig1State=HIGH;
        
digitalWrite(sig1Pin,sig1State);
      }
    }  

    
//sig 2 timing logic
    
if(sig2State==HIGH){
      if (
tmp2>=sig2PinOnTime){
        
sig2Start=tmp;
        
sig2State=LOW;
        
digitalWrite(sig2Pin,sig2State);
      }
    }else{
      if (
tmp2>=sig2PinOffTime){
        
sig2Start=tmp;
        
sig2State=HIGH;
        
digitalWrite(sig2Pin,sig2State);
      }
    }  

    

     
//sig3?  sigX? 

  
}   



wikityler 06-08-2008 03:45 PM

What is the signal logic on the VSS and injector line? I'd like to make an interface for my carputer to do FE calculations.

dcb 06-08-2008 04:15 PM

It is basically a 5 volt square wave defined by these lines in the code:

#define sig1PinOffTime 2444
#define sig1PinOnTime 25333
#define sig2PinOnTime 16000
#define sig2PinOffTime 2180

sig1 (simulating the injector signal) is off for 2444 microseconds and on for 25333 microseconds, roughly.

sig2 (simulating the vss signal) is on for 16000 microseconds and off for 2180 microseconds, roughly.

So you going to start from scratch, or can you help us troubleshoot the guino? It would be downright trivial to send the instant raw data out the serial port on the guino and collect it on the carpc and make sense out of it there. I do it all the time for debugging.

awillard69 06-08-2008 04:50 PM

You beat me to the end. :thumbup: My 555 is working, but not very precisely. While its accurate, without a scope, I'm having trouble zeroing in on trustworthy streams.

So, let me get this straight, you have a basic ATMEGA168 chip, that you loaded using your Freeduino board, or the load cable, then placed that code loaded chip to your solderless breadboard with the bare bones components for a functioning chip. You then power it from the same place as the MPGuino and tap its outputs.

I may just have to break down and buy some more Freeduinos to catch up. :o

My soldering iron is heating up so I can migrate my LCD and input interfacing components to a proto shield. I'm trying to make mine look less like a spaghetti ball on the bench.

dcb 06-09-2008 04:12 PM

Quote:

Originally Posted by awillard69 (Post 32671)
So, let me get this straight, you have a basic ATMEGA168 chip, that you loaded using your Freeduino board, or the load cable, then placed that code loaded chip to your solderless breadboard with the bare bones components for a functioning chip. You then power it from the same place as the MPGuino and tap its outputs.

That's pretty much it. I bought some 20mhz PDIP atmega 168's and some 16mhz crystals after I cooked one atmega, then wrestled a bootloader on them by putting them in my freeduino board socket and mucking around with the parallel port ICSP programmer (not for the faint of heart), then I could program it via the USB/Serial port on the board and use plain old arduino IDE and code.

NCK had some chips with bootloaders on them, but no crystals, and when I looked they did not have chips in stock, so as hokey and painful as the parallel programmer can be to get working, it has proved to be invaluable. It's brought back a couple chips after experiments that have gone wrong and cost me nothing :)

Course the real nice thing about this arrangement is that I can create cheap little devices, but anybody with a duino can also use what has been written very easily.

Edit: I was just checking out the iduino and noticed that fundamental logic, http://www.spiffie.org has atmegas with bootloaders preloaded and crystals, as well as a breadboard usb duino kit for $18! I had to get one at that price (plus a couple more atmegas and crystals)

MilesPerTank 06-09-2008 08:27 PM

Great work DCB. Thanks for all your help on this project as far as debugging the software (and writing it hahaha).

I may build one of these with my spare board. I always buy spares when it comes to components....I've got a habit....

awillard69 06-10-2008 12:10 PM

I got my cluster of wires pushed to the proto shield from NKC. But, then ran into several issues.

The first was the size of the holes are tight for the Zener diodes, or if you have larger watt resistors. Not a big deal, but does require some persuasion and the small area makes it challenging.

The second problem is more of an issue. Basically, the trace across the center of the board for 5V is not connected, just solder pads; the ground is OK.

I contacted NKC and they acknowledged my find. They were prompt, but I would wait for a new generation board before getting another proto shield from them.

All in all, it went great, aside from the issues with "placement on the fly". And, it looks good, piggy backed on the Guino. Still not as compact as a custom PCB setup, but very friendly for plug-and-go with any Freeduino board, snap in, snap out.

I'm waiting for my other Freeduino's to arrive so I can assemble the generator and get back to testing this thing.

awillard69 06-15-2008 01:35 PM

Have you changed or updated your generator code? I've got it running on a 2nd Freeduino, straight inputs, not resistors.

It looks like I'm showing 55-58 mpg. Is that what you are getting?

I show MH 40.0x and MG ~57.

Not related directly to the generator, when I display the CPU % screen, it seems to revert back to the startup, like a reset as the MI reverts back to near 0.

I get it if I cycle left once, or right 6 times.

I'm not quite sure if it's the code somehow resetting the CPU or something else. Version 0.61.

The generator makes it nice to see it actually running.

dcb 06-15-2008 09:28 PM

I've not touched the signal generator code since fixing the 72 minute issue. I do keep messing with the microseconds per gallon and vssTicsPermile though but 57/58 mpg @40mph sound just right for the last version.

re:reset, currently , hitting left button and middle button simultaneously will reset the tank trip, hitting right and middle will reset the current trip. Is it possible that the middle button is getting "fat fingered" when hitting the left or the right button?

awillard69 06-16-2008 10:16 AM

I've checked and the buttons don't appear to be solder bridged or anything. And the buttons are far enough apart to not likely be fat fingered. But, it also happens if I right button to that screen, also.

But it appears to be resetting the program, ie running setup() again.

With my current configuration, if I press the reset button on the Freeduino the LCD goes "one line" on me - known issue. This doesn't happen, so I'm not quite sure it's a full on restart, but like it's just running setup() again somehow. I went looking through the Guino code, looking for a possible hosed pointer or something, something where a memory address is getting trounced. Nothing jumped out at me. It could be a memory corruption or allocation/deallocation issue within the arduino program code. A bit far fetched maybe. Does it not happen for you?

dcb 06-16-2008 10:31 AM

I've never witnessed that behavior and I have tried to reproduce it, lots of fast rights and lefts, casual lefts and rights, hundreds in a row, no problemo.

FYI, on the plan for the signal generator program (eventually) is to add button signals too.

If you want to give that a go, the resistors are cheap insurance, I do have actual, non speculative, first hand experience with cooking a chip by connecting them directly :) The pin states may not be in a known state when the chips boot up and they may not boot up perfectly in sequence, or you just forgot what code you had on one of the chips :o. so two pins could be in output mode (non-low impedence) and one high and one low and that's all it takes.

awillard69 06-16-2008 11:04 AM

Maybe I wasn't very clear. When I display the CPU screen, I see what appears to be a single update, then the apparent reset.

I'll plug in some resistors to see how it goes. Currently, both Freeduino's are powered from the same 12v source (bench power) with a split pigtail for the power jacks, so a common ground. Since the Guino code is vastly larger, I'm speculating that it comes online after the test generator, but, you're right, that's no guarantee. My two Freeduinos are not easy to mix up as the Guino one has the proto-shield with the LCD and the generator is just a plain board. Yes, I suppose I could have uploaded the incorrect program, but I think I'm better than that ;).

I think I'll update the generator to put a signature pin 13 blink sequence or something to it will be obvious when it's functioning.

dcb 06-16-2008 11:19 AM

Hmm.. Can you try commenting out all the lines inside doDisplay7()? Should just have a nonsense screen for CPU Monitor hopefully instead of a quasi-reset.

awillard69 06-16-2008 11:26 AM

I'll give that a try this evening when I get home.

awillard69 06-16-2008 08:49 PM

I tried...
 
It appears the the memoryTest() function is the culprit - on 2 different Duinos. I've commented it out completely, and it works; I've commented out the while loop and it works. Something in the allocation routine is amiss, like maybe the processor is getting trounced - at the moment it needs memory, the program has it allocated, so it resets.

I've modified it as follows, what do you get on the serial? I changed it to an unsigned long to match the data type in the calling function, but no luck. I even added the check before the final deallocation.

Code:

// this function will return the number of bytes currently free in RAM   
unsigned long memoryTest() {   
  unsigned long byteCounter = 0; // initialize a counter   
  byte *byteArray = NULL; // create a pointer to a byte array   

  while ( (byteArray = (byte*) malloc ((int)byteCounter * sizeof(byte))) != NULL )
  {   
//    byteCounter++; // if allocation was successful, then up the count for the next try   
    byteCounter += 10; // if allocation was successful, then up the count for the next try   
    free(byteArray); // free memory after allocating it   
    #ifdef debuguino
    Serial.print("Memory: ");Serial.print(byteCounter);Serial.print("\n");
    #endif
  }
  if( byteArray != NULL ) free(byteArray); // also free memory after the function finishes   
  return byteCounter; // send back the highest number of bytes successfully allocated   
}

On count by 1 (ie byteCounter++), I get:
Code:

...snip
Memory: 840
Memory: 841
Memory: 842
Memory: 843
JMemory: 844KMemory: L845Memory:M846MemoryN847MemorO848MemoP849MemQ850MeR851MS852T85385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291317367953914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979instant: 0,133444,54,166
current: 0,133444,54,166

...snip

For += 10, I get:
Code:

...snip
Memory: 910
Memory: 920
Memory: 930
MĘ940
MĘ950
MĘ960
MĘ970
MĘ980
MĘ990
MĘ1000

...snip

Any help?

dcb 06-17-2008 03:43 AM

Here's what I get, no problem there, about time for another round of optimizing though :(

instant: 0,44072,18,27
current: 0,879320,360,550
Memory: 10
Memory: 20
Memory: 30
Memory: 40
Memory: 50
Memory: 60
Memory: 70
Memory: 80
Memory: 90
Memory: 100
Memory: 110
Memory: 120
Memory: 130
Memory: 140
Memory: 150
Memory: 160
Memory: 170
instant: 0,46516,19,28
current: 0,925836,379,578

awillard69 06-17-2008 08:56 AM

Ok, my next stab might be something like: something different between our ATMEGA's, like maybe a different generation of boot loader software, some memory management issue. I've tried it on two different Duino's bought weeks apart, so that doesn't seem very likely..

But, I'm willing to consider other options, as well.

What about your coding IDE? What platform are you using? I'm using v0011 on Ubuntu 8.04. Even though it's supposed to be the same, might there be a difference in the bytecode generated?

I haven't ruled out my proto board, either. Tonight I'll try running the Duino on just the board itself, no peripherals and just trigger the left switch and watch the trace.

dcb 06-17-2008 09:05 AM

Hard to imagine something external messing up malloc(), I would suspect linux is the key difference here. Are you using a script to start arduino (run.sh or something)? I know strange things can happen in windows if you do not use the script, there is less possibility of linking in the wrong malloc on windows too ;)


I tried 0010 and 0011 fyi, on a lot of chips. Some that I had used the IDE to load the decimillia bootloader on too.

FYI, in addition to the supercheap but flakey parallel iCSP, there is also a bit of code to turn a duino into an icsp programmer if you want to try a different bootloader: http://www.arduino.cc/playground/Code/Programmer2

awillard69 06-17-2008 09:38 AM

I'm running "arduino" in the arduino-0011 folder. It's basically a shell script:

Code:

#!/bin/sh

CLASSPATH=java/lib/rt.jar:lib:lib/build:lib/pde.jar:lib/core.jar:lib/antlr.jar:lib/oro.jar:lib/registry.jar:lib/mrj.jar:lib/RXTXcomm.jar
export CLASSPATH

# put the directory where this file lives in the front of the path, because
# that directory also contains jikes, which we will need at runtime.
#
PATH=`pwd`/tools:${PATH}
export PATH

# put the directory with the native RXTX libs in the library path
LD_LIBRARY_PATH=`pwd`/lib:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH

java processing.app.Base

Nothing special there. I compared it to the Windoz version, and it seems comparable. So, maybe there is a bug in the Linux variant. I'll have to try to find a different machine to use the IDE and see if it actually matters.

awillard69 06-17-2008 10:04 AM

I found this link, http://www.arduino.cc/cgi-bin/yabb2/...num=1213583720, and http://forum.pololu.com/viewtopic.ph...w=unread#p4218, and it seems to indicate the complexity of checking free RAM.

It might also be related to the intermixing of C++ and C constructs on immature compiler/libraries. I only have anecdotal support, but I've seen it happen before - on Solaris no less!

dcb 06-17-2008 10:18 AM

Hmm, the malloc version returns 318, if I replace the memoryTest function with the following I get 381. I suspect the stack pointer version is not as future proof or accurate though. But it may still be useful enough. Your *10 malloc version also highlights the fact that the free memory may not be contiguous, since that returns only 170 bytes free when retrieved in 10 byte chunks.

Code:

extern int  __bss_end;
extern int  *__brkval;
int memoryTest(){
  int free_memory;
  if((int)__brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);
  return free_memory;
}


dcb 06-17-2008 07:42 PM

Actually I did several ram optimizations and the malloc version did not register a change, but the above function showed 484 bytes free. And you are having issues with the malloc version, so lets go with the above function till it bites us :) I'll put it in the next version.

awillard69 06-17-2008 08:55 PM

I tried it with a bare, unadorned board and got the same results. I'll plug in that function and see how it goes from there.

I don't have a non-Linux PC at home with a serial port to try. I'll have to rethink that one.

dcb 06-26-2008 02:04 AM

Parity check
 
FYI, I currently have set up two guinos on the same signal generator running to see if there is any consistency. I expect the injector open times will be slightly different due to frequency variations, but the injector and vss counts should be very close and so far they are, but will let it run for a few days. Also it is all rigged to run on the one 7805, hence the heat sink wedged behind it :) I will try and leave it alone for a day or so.
http://opengauge.org/diympggauge/parity1.JPG

awillard69 06-26-2008 09:29 AM

That will be nice to know.

You may need to mechanically affix the heat sync to the 7805. Something like a small screw, alligator clamp, etc. should do the trick and help dissipate the heat.

If/when you get your scope, hopefully it's a 2+ channel. Then you could run up both and look at the signals. You should be able to see any variance or drift.

But, then again, maybe it doesn't matter... It's only used for bench testing.

dcb 06-26-2008 10:19 AM

Update:
@ 511 minutes:
trip MPG on green unit 64.80
trip MPG on blue unit 64.79
Distance on both 270.21
Injector and vss counts in synch
MPG variance %0.015 :thumbup:

7805 seems happy.

dcb 06-27-2008 11:29 PM

Update
green Time: 2734.30 minutes
blue Time: 2734.30 minutes

green cumulative mpg 64.82
blue cumulative mpg 64.82

green distance 1316.3 miles
blue distance 1316.3 miles

green fuel 20.31 gallons
blue fuel 20.31 gallons

:thumbup::thumbup::thumbup::thumbup:


All times are GMT -4. The time now is 05:59 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2022, vBulletin Solutions Inc.
Content Relevant URLs by vBSEO 3.5.2
All content copyright EcoModder.com