at a loss--bitwise math SPI interface

I am using the MCP3202 analog to digital converter (mentioned elsewhere in the forum) to collect data from two sensors–a photodiode and a temperature sensor (the TMP36). My data looks good for a while, then goes wonky for a stretch. Take a look at an excerpt:

LightData,TempData,DateAndTime
63,579,7/10/2011T12:56:5
64,580,7/10/2011T12:56:6
63,580,7/10/2011T12:56:8
64,580,7/10/2011T12:56:9
609,591,7/10/2011T12:56:10
77,5791,7/10/2011T12:56:11
68,5801,7/10/2011T12:56:13
67,5791,7/10/2011T12:56:14
67,5791,7/10/2011T12:56:15
65,5791,7/10/2011T12:56:16
64,5791,7/10/2011T12:56:18
65,5791,7/10/2011T12:56:19
64,5791,7/10/2011T12:56:20
64,5791,7/10/2011T12:56:21
64,5791,7/10/2011T12:56:23
64,5791,7/10/2011T12:56:24
131,579,7/10/2011T12:56:25
2937,579,7/10/2011T12:56:26
2928,587,7/10/2011T12:56:28
2956,587,7/10/2011T12:56:29
2919,579,7/10/2011T12:56:30
90,57979,7/10/2011T12:56:32
69,58079,7/10/2011T12:56:33
66,58079,7/10/2011T12:56:34
65,58179,7/10/2011T12:56:35
64,58179,7/10/2011T12:56:37

The first few entries are correct. The light data should jump up and down–I’m covering and uncovering the sensor with my hand. But the temp data should not. Note that it goes bad near where the lightdata jump, and that the last two decimal places remain the same (mostly) as it jumps by a factor of 10 or 100.

This suggests to me that my bitwise math is messed up. I have pored over the whitepaper for the MCP3202 but I do not have the knowledge to figure out what my problem might be. One possibility is that I’m using the wrong type, i.e. that I shouldn’t be using an “int” to store the result from the ADC. But I would think that problem would be independent of the separate channels on the MCP3202. So I still think it’s in the bitwise math.

I obtained this snippet of code elsewhere on the forum (not sure where, it’s been a while). Can anyone take a look and puzzle it out for me?

//read_adc() communicates with the ADC--sets it up and collects the data from it, returns it
//it will be a number 0-4095 (12 bit resolution)
//feed read_adc() an argument of 1 or 2 to tell it which channel to read
int read_adc(int channel){
	
    int adcvalue = 0;				//a variable to hold the digital value given by the ADC
    byte commandbits = B11010000; //command bits - start, mode, chn, MSBF 

    //allow channel selection
  	commandbits|=(channel<<5);
  
    digitalWrite(SELPIN,LOW); //turn on adc
	// setup bits to be written
  
	//send the command setup to the chip:
	//first bit is a start message
	//second bit tells it to use single-ended mode (rather than differential)
	//third bit tells it what channel to look at
	for (int i=7; i>=4; i--){
	    digitalWrite(DATAOUT,commandbits&1<<i);
    	//cycle clock
    	digitalWrite(SPICLOCK,HIGH);
    	digitalWrite(SPICLOCK,LOW);
    }

	//cycle clock up and down twice to ignore 1 null bits
  	digitalWrite(SPICLOCK,HIGH);   
  	digitalWrite(SPICLOCK,LOW);

  	//now read bits from adc
  	//??why does it only read in 11 bits instead of 12? should this be "=" instead of ">="?
  	for (int i=11; i>=0; i--){
    	adcvalue+=digitalRead(DATAIN)<<i;
    	//cycle clock
    	digitalWrite(SPICLOCK,HIGH);
    	digitalWrite(SPICLOCK,LOW);
    }
    
	digitalWrite(SELPIN, HIGH); //turn off device
	delay(20);					//very slight delay to let device reset
	return adcvalue;
}

extra details: The arduino is collecting the data from the MCP3202 and sending it over a wireless link (pair of xbees) to a laptop; I have a number of additional, unrelated features in the code, which is why I excerpted the part with the bitwise math separately. I’ll post the full arduino code and processing sketch at the bottom. [EDIT: message was too long, I couldn’t post the full code, I put both programs in a text attachment]

much thanks to anyone who is willing to take a moment out to help!
matt

MattsCode.txt (18.3 KB)

I haven’t looked at the MCP3202 datasheet - is there some reason you are not using the SPI library?
Hardware transfers will be much quicker, and take less code:

include <SPI.h> // format may be off a little, can import from the IDE, will call it correctly.

in setup:
SPI.begin(); // leave blank as we are the master

in loop, something along these lines:
digitalWrite (selpin, LOW); // select device
// may need an SPI write out or two for device setup
highByte = SPI.transfer(); // read upper 8 bits
lowByte = SPI.transfer(); // ready lower 8 bits
digitalWrite (selpin, HIGH); // deselect device

result = highByte<<8; // move upper 8 bits into top of int result
result = result | lowbyte; // move lower 8 bits into bottom of result
// manipulate as needed for trailing 0’s,etc.

My data looks good for a while, then goes wonky for a stretch.

Sounds like an input impedance problem at the input to your external A/D converter rather than any software. You get the same effect on the arduino where there is effectively cross talk between the channels due to the residual charge on the sample and hold capacitor not being changed quickly enough by the new input being switched in.