Letar efter demo kod för 8-bit mode LCD

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Jonaz
Inlägg: 2358
Blev medlem: 4 november 2003, 22:06:33
Ort: Huddinge

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av Jonaz »

Har nog glömt att nämna att timePrint kommer ifrån ett original bibliotek som heter Time.h, därav så är det lite krångligt att bara ändra hur som.

> ThomasL
Det där kan nog vara det jag letar efter, skall hem och prova.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46986
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av TomasL »

Öh, utan "h" tack :shock:
Du kanske skulle studera lite "C" :wink:
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av Kaggen »

Jonaz skrev:Fast just i detta fall vill jag att timePrint() skall hämta från getDateDS1307()
När man kollar koden för dessa funktioner som du postade på första sidan i denna tråd, och är någorlunda bevandrad i C, så ser man ju hur "datan" från getDateDS1307() kan skickas till timePrint().

Kod: Markera allt

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
Du definierar först variabler av typen byte för timme, minut, sekund m.fl. precis som proto för funktionerna anger i koden ovan. Sedan skickar du med pekarna till dom i anropet till getDateDS1307(), vilken fyller variablerna med rätt tid. På nästa rad skickar du med dessa variabler igen till timePrint() som skriver ut dom på LCDn. Klart och betalt!

Du borde som sagt studera C noggrannare. Det är svårt att förstå och tala ryska innan man lärt sig det... typ.. :)
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av jesse »

En sån klumpig kod! (Jag syftar på getDateDs1307.) Är det Arduion original? Det där kommer ju att kräva en hel del maskinkod + stack + processortid. Varför inte bara en pekare till en struct som innehåller alla bytes istället för en pekare för varje byte?

Nåja...

Om det bara är det att du ska hämta tiden från RTC och sedan skriva ut med timePrint så är det väl enkelt:
Vad du måste göra är alltså att först deklarera ett antal variabler i main eller globalt:

Kod: Markera allt

byte second;
byte minute;
byte hour;
byte dayOfWeek;
byte dayOfMonth;
byte month;
byte year;

// sedan anropar du getDateDs1307() med följande rad:

getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, byte &year);

// nu innehåller variablerna tiden (om det fungerade).
// utskriften sker sedan med anropet:

timePrint(hour, minute, second, month, dayOfWeek, year); // skriv till LCD

// klart !
Men det kanske inte var det du ville göra? Hela tråden känns lite förvirrande...
Användarvisningsbild
Jonaz
Inlägg: 2358
Blev medlem: 4 november 2003, 22:06:33
Ort: Huddinge

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av Jonaz »

Skulle just kasta in handduken och gå vidare i projektet, men gjorde ett försök till och har äntligen fått det att funka med klockan.
Hittade ett bibliotek med kod som hette DS1307RTC.

Nu står det bland annat,
DS1307RTC(current_time);

istället för
timePrint(current_time);

och det funkar att ställa klockan samt komma ihåg tiden. Toppen!

men, har lagt till en 18B20 temp sensor, det funkar förutom att den visar decimal grader som antingen ,0 eller ,5. jag skulle vilja att den visar bättre upplösning till ,1 vilket tydligen skall gå. Nu har visserligen 18B20 sensorn bara 0,5 i noggrannhet.
Datablad 18B20

Någon som har en ide vart man ändrar det?
Koden för 18B20 om man kör den i som ett eget program.

Kod: Markera allt

#include "LiquidCrystal_SPI_8Bit.h"
LiquidCrystal_SPI_8Bit LCD(8,53); 
#define TEMP_PIN  10 //See Note 1, sheepdogguides..ar3ne1tt.htm

void OneWireReset(int Pin);//See Note 2
void OneWireOutByte(int Pin, byte d);
byte OneWireInByte(int Pin);

void setup() {
   LCD.begin(20,2);

  LCD.setCursor(0,0);
    digitalWrite(TEMP_PIN, LOW);
    pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)
//LCD.begin(9600);
//9600 to match the data rate being used by the
//serial monitor on my system, which is set to
//the Arduino default. (Sample code published
//by nuelectronics used a faster baud rate.)
    delay(100);
      LCD.setCursor(0,0);
    LCD.print("temperature measurement:\n");
}

void loop(){
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0xbe);

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;


  if (SignBit) // If its negative
  {
   // LCD.setCursor(0,1);
     LCD.print("-");
  }
 LCD.setCursor(0,1);
  LCD.print(Whole);
  LCD.print(".");
  if (Fract < 10)
  {
   LCD.print("");
  }
LCD.setCursor(3,1);
  LCD.print(Fract);
//if (Fract > 10)
{
   LCD.print(" ");
  }
    LCD.setCursor(4,1);
     LCD.print("C");
  delay(50);      // 5 second delay.  Adjust as necessary
}

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }

      d=d>>1; // now the next bit is in the least sig bit position.
   }

}

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}

Tack för hjälpen förresten.

>>Du borde som sagt studera C noggrannare. Det är svårt att förstå och tala ryska innan man lärt sig det... typ.. :)
Jo det hade ju varit lite enklare..... Man kanske skulle jaga tag i nån bok eller motsvarande.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av jesse »

Absolut! En bra bok om C på svenska är"Vägen till C" av Ulf Bilting och Jan Skansholm. Jag ha den alltid i närheten. :)

>Någon som har en ide vart man ändrar det?
Det är alltså inte du som skrivit koden?

Du har ju hundradelar antalet grader celcius i Treading, heltalsdelen plockas ut i Whole och decimaldelen (hundradelar) i Fract. Inte så svårt.

Varför inte decimaldelen (Fract) skrivs ut riktigt vet jag inte, men den koden verkar ju lite knasig.
Alla dessa LCD.setCursor(x,x) kan ju stöka till det, och de behövs ju inte - man skriver ju ut alla tecken efter varandra bara.

jag har ändrat lite:

Kod: Markera allt

Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;

  LCD.setCursor(0,1); // sätt position en gång för alla innan något skrivs ut
char sign = " ";
  if (SignBit) 
  { 
       sign = "-"; 
  }
  LCD.print(sign); // skriv ut tecken på första position
  LCD.print(Whole); // skriv ut heltal grader
  LCD.print("."); // decimalpunkt
  if (Fract < 10)
  {
      LCD.print("0"); // skriv ut en nolla
  }
  LCD.print(Fract); // skriv ut decimalerna
  LCD.print("C");   // avsluta med ett C.
Problemet med den här koden är ju att hela talet kommer att hoppa fram och tillbaks beroende på om temperaturens heltalsdel är en, två eller tresiffrig. Man vill ju helst att tal ska vara högerjusterade vid utskrift. Det fixar man ju lätt med att lägga in lagom antal " " (space) före. t.ex.

Kod: Markera allt

if (Whole > 99) LCD.print(" ");
if (Whole > 9) LCD.print(" ");
Detta kommer att göra så att utskriften alltid blir 8 tecken (inklusive mellanslag och C i slutet).

Kod: Markera allt

t.ex:
"  -2.25C"
"  12.06C"
"-100.00C"
"  -0.18C"
Om man vill kan man ju få det ännu snyggare genom att ändra char sign = " "; till char sign = "+"; så får du ett plustecken framför positiva tempreaturer:

Kod: Markera allt

" +12.06C"
Användarvisningsbild
Jonaz
Inlägg: 2358
Blev medlem: 4 november 2003, 22:06:33
Ort: Huddinge

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av Jonaz »

LCD.print som fanns lite här och var, berodde på som du sa innan att en siffra hoppade fram och tillbaka dock var det decimalen.

signBit funktionen är egentligen hel ointressant för mig, men tack ändå.

Som sagt så visar det fortfarande bara xx,00 eller xx,50. :humm:

Rent spontant så verkar det som att felet ligger här någon stans.

Kod: Markera allt

OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0xbe);

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;

>>"Vägen till C" av Ulf Bilting och Jan Skansholm
Den var ju inte så lätt att hitta, slut överallt.
Senast redigerad av Jonaz 22 mars 2012, 22:58:45, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av sodjan »

Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av jesse »

Jag ser faktiskt inget fel som gör att de tre sista bitarna inte skulle komma med. Däremot ser jag något som kan förenklas: Ta bort SignBit och gör så här:

Kod: Markera allt

  // Treading är ett 16-bitars signed int !!!
  char sign = '+';
  if (Treading < 0) // negative
  {
    TReading = - Treading;
    sign = '-';
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 - Whole*100; // kanske tar mindre processorkraft än % ?
Kanske om du kollar Table 2. Thermometer Resolution Configuration på sidan åtta i databladet - det är nog detta som tar bort dina decimaler.
ronnylov
Inlägg: 987
Blev medlem: 23 februari 2012, 12:06:19
Ort: Borås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av ronnylov »

Vägen till C! Det var ju den boken vi hade på högskolan runt 1990 när vi hade programmeringskursen.
Får gräva lite i uthuset hos mina föräldrar där gamla skolböcker ligger.
Minns att den var bra. Första utgåvan var 1987 så den var väl ganska ny på den tiden.
Eller är det värt att köpa en nyare revision?
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av jesse »

Min är tredje upplagan från år 2000, om det nu har någon betydelse.
Användarvisningsbild
Jonaz
Inlägg: 2358
Blev medlem: 4 november 2003, 22:06:33
Ort: Huddinge

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av Jonaz »

Har äntligen löst det.

Det verkar som att man först måste programmera en 18B20 till att läsa i 12 bit mode dvs med decimaler typ 24,73C, eller vilket bit mode man nu vill.
Efter att jag gjort det så läser den "rätt" som koden här innan var.
Det går förmodligen att lösa på andra sätt men denna funkade för mig.

Lösning:
Först måste man veta vilken adress det är på 18B20
Det löste jag med denna kod.

Kod: Markera allt

// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial: 
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(22);  // Connect your 1-wire device to pin 22

void setup(void) {
  Serial.begin(9600);
  discoverOneWireDevices();
}

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

Här är koden som man kan ändra vilket bit mode man vill läsa av med, ju högre bit, desto längre tid tar det att läsa av, kan vara bra att veta.

Kod: Markera allt

//  This Arduino sketch reads DS18B20 "1-Wire" digital
//  temperature sensors.
//  Copyright (c) 2010 Mark McComb, hacktronics LLC
//  License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
//  Tutorial:
//  http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 22 on the Arduino
#define ONE_WIRE_BUS 22

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress insideThermometer = { 0x28, 0x97, 0x33, 0x66, 0x00, 0x00, 0x00, 0x79 }; // Kopiera in din adress här.
//DeviceAddress outsideThermometer = { 0x28, 0x6B, 0xDF, 0xDF, 0x02, 0x00, 0x00, 0xC0 };
//DeviceAddress dogHouseThermometer = { 0x28, 0x59, 0xBE, 0xDF, 0x02, 0x00, 0x00, 0x9F };

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 12); // här ändrar man bit mode 9,10,11,12
 // sensors.setResolution(outsideThermometer, 10);
  //sensors.setResolution(dogHouseThermometer, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print("C: ");
    Serial.print(tempC);
   // Serial.print(" F: ");
    //Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop(void)
{
//  delay(500);
//  Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();
 
 // Serial.print("Inside temperature is: ");
  printTemperature(insideThermometer);
  Serial.print("\n\r");
 // Serial.print("Outside temperature is: ");
 /*printTemperature(outsideThermometer);
  
 Serial.print("\n\r");
  Serial.print("Dog House temperature is: ");
  printTemperature(dogHouseThermometer);
  Serial.print("\n\r\n\r");*/
} 
Angående Vägen till C, Först hittade jag bara tredje upplagan som är slutsåld över allt, och med hjälp av Sodjans länk så hittade jag fjärde upplagan till försäljning. ISBN: 9789144076065


Tack för hjälpen så länge!!
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Letar efter demo kod för 8-bit mode LCD

Inlägg av jesse »

Ja, det var därför jag tipsade om att kolla Table 2. Thermometer Resolution Configuration på sidan åtta i databladet. Där står det om de olika val man kan göra när det gäller bitupplösning.
Skriv svar