Go Down

Topic: Problem with Ruby and serial port (Read 1 time) previous topic - next topic

MacLeod

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:
Code: [Select]
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:
Code: [Select]
#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;
}

MacLeod

I have now done some testing on my new Macbook Air and everything works great there.
So the serialport library for ruby on windows probably has some bug.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy