A have a problem when trying to read the serial port from my arduino. I am running on a Windows 7 64-bit with Ruby 1.9.2.
When i start my script nothing happens. To get it running i have to first start the Serial Monitor in Arduino IDE and see the data. Then close it and the ruby script works flawless.
I can now stop the script and start it again and it works, until i restart the computer or reset the arduino.
Right now i running it on a Teensy but it is the same on both Teensy and Arduino.
I have a Python script that does the same and it works without the work around.
Why it is doing this?
Ruby code:
require "serialport"
require "sequel"
def getTemperature(sp)
temp = ""
found_first_char = 0
#just read forever
while true do
sp_char = sp.getc
if sp_char == "R" or found_first_char == 1
found_first_char = 1
if sp_char == "\n"
break
end
if sp_char
temp = temp.concat(sp_char)
end
end
end
return temp
end
# connect to an in-memory database
DB = Sequel.sqlite('./templog.db')
# # create a dataset from the items table
temp_reads = DB[:temp_reads]
sp = SerialPort.new("COM7", 115200, 8, 1, SerialPort::NONE)
while true do
temperature1 = getTemperature(sp)
temperature2 = getTemperature(sp)
time = Time.now
data = []
data = temperature1.split(' ')
a = data[0].split('=')[1]
t = data[1].split('=')[1]
temp_reads.insert(:timestamp => time, :temp => t.to_i, :address => a)
puts "Log timestamp: #{time}, temperature: #{t}, address: #{a}"
data = temperature2.split(' ')
a = data[0].split('=')[1]
t = data[1].split('=')[1]
temp_reads.insert(:timestamp => time, :temp => t.to_i, :address => a)
puts "Log timestamp: #{time}, temperature: #{t}, address: #{a}"
sleep 300
end
sp.close
Arduino code:
#include <OneWire.h>
/* DS18S20 Temperature chip i/o */
OneWire ds(10); // on pin 10
const int redPin = 6;
void setup(void) {
Serial.begin(9600);
pinMode(redPin, OUTPUT);
}
void loop(void) {
byte i;
byte present = 0;
byte data[12];
byte addr[8];
if ( !ds.search(addr)) {
//Serial.print("No more addresses.\n");
ds.reset_search();
delay(500);
return;
}
Serial.print("R=");
for( i = 0; i < 8; i++) {
Serial.print(addr[i], HEX);
Serial.print("x");
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
if ( addr[0] != 0x10) {
Serial.print("Device is not a DS18S20 family device.\n");
return;
}
// The DallasTemperature library can do all this work for you!
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
//Serial.print("P=");
//Serial.print(present,HEX);
//Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
//Serial.print(data[i], HEX);
//Serial.print(" ");
}
Serial.print(" T=");
Serial.print(getTemp(data));
//Serial.print(" CRC=");
//Serial.print( OneWire::crc8( data, 8), HEX);
Serial.print("\n");
digitalWrite(redPin, HIGH);
delay(500);
digitalWrite(redPin, LOW);
}
float getTemp(byte data[]) {
int tr;
//put in temp all the 8 bits of LSB (least significant byte)
int LSB;
int HSB;
LSB = data[0];
HSB = data[1];
//check for negative temperature
if (HSB > 0x80){
LSB = !LSB + 1; //two's complement adjustment
LSB = LSB * -1; //flip value negative.
}
//COUNT PER Celsius degree (10h)
int CPC = data[7];
//COUNT REMAIN (0Ch)
int CR = data[6];
//drop bit 0
tr = LSB >> 1;
return (float)tr - (float)0.25 + (CPC - CR)/(float)CPC;
}