...wie ich meinem Lenovo S660 Smartphone das GPS gefixt habeMittwoch, 07 Oktober, 2015 19:37

Als die monatlichen Kosten für Smartphone unterwegs online zu sein 10 € erreicht hatten, war dies ausgerechnet bei T-Mobile der Fall und zwar bei der Prepaid Abteilung - wer hätte das gedacht! Zeit für mich, auch endlich einzusteigen und mir einen mobilen Minicomputer zu zulegen.

Mein erstes Smartie war ein Sony Xperia Tipo. So klein, dass es locker in die Hemdtasche ging, fand ich gut, aber auch so klein, dass ich etwas Schwierigkeiten beim Lesen hatte. Es war aber 2 Jahre lang mein treuer Begleiter und hat mich mit Navit und Openstreetmap auch gut durch unbekanntes Terrain gebracht.

Selbstverständlich hatte ich es gerootet. Ich will wohl schon Administrator auf meinen Computern sein :-) und hatte auch schon Pläne geschmiedet, es zu modden. - Leider wollte mir T-Mobile dem Gerät zwar wohl die SIM entsperren, den Bootloader jedoch nicht. Der Traum von alternativen ROMs oder vielleicht Cyanogenmod war ausgeträumt und ich stinkig..., nie wieder wollte ich in D oder der EU ein gefesseltes und geknebeltes Smartie kaufen...

Also stolperte ich über Chinabuy, nachdem mir die Inder ihr YU wohl nicht so gern bzw. Amazon nur über indische Banken verkaufen wollten, wäre auch wohl doch nicht sooo toll geworden, na egal. Ein China-Smartie sollte es dann sein und was war das ein bunter Katalog von Möglichkeiten, so dass ich ganz geblendet ganz vergaß bei der Auswahl doch auf Cyanogen-Kompatibilität zu achten und so kam es, dass ich ein Lenovo S660 kaufte.

Ganz schön großes Brett für ein Smartie, finde ich immer noch. Hemdtasche no go. Hosentasche nur vorübergehend :-) Schön schnell, wahrlich und auch ein schönes Metallgehäuse - nur das GPS war wider Erwarten der große Reinfall. Minutenlanges Warten, bis Satelliten entdeckt werden konnten und dann zeigte es mich nicht auf der Straße, sondern durch die anliegenden Häuser fahren und weit hinten oder weit vorne, es war einfach ein Krampf.

Wiederholte Recherche im deutschen und englischsprachen Bereich brachten zwar Tips, aber keinen Erfolg. Bis ich auf eine russische Webseite stieß, http://lenovo-forums.ru/  die auch erklärte, woran es vermutlich liegt, weswegen Smarties, die eigentlich für den chinesischen Markt bestimmt sind, auf unserem Kontinent nicht oder nicht so gut navigieren können. Interessierte lesen es am besten selbst: http://lenovo-forums.ru/topic/8945-lenovo-s660-улучшение-работы-gps-gps-и-как-с-ним-бороться/  und wer kein russisch kann, wirft es eben bei https://translate.google.de  ein oder so. Die notwendige Software gibt es im Google Marketplace und ich für mein Lenovo S660 hatte endlich Erfolg damit und kann es also weiterempfehlen!

Categories: Elektronik, Hardware, Lifestyle, Selbstgemacht, Software

[ [0] Kommentare ]

I2C ist geil und das neue Display auchFreitag, 10 April, 2015 15:15

Das neue LCD-Display hatte ich ja bestellt, damit ich belegte Pins am Arduino einsparen kann. Heute ist es hier aufgeschlagen. Hm, wie schließe ich jetzt das I2C Display und die RTC am Arduino an? Brauche ich software-I2C, oder was? Weit gefehlt, I2C Geräte haben Namen und können alle am gleichen Bus hängen und der Treiber findet das Gerät. Super, doppelt Pins gespart!

Und das Tolle ist, die neue Bibliothek kann das Display sogar ausschalten.

Hier das erste Bild:

I2C-LCD-RTC 01

...man sieht die übrig geblieben Pins und das ist übrigens ein Powersafe als Stromversorgung und ein USB-Leistungs-Messgerät. Aktiv braucht das Ganze 0.06 Ampere.

Und hier das ganz schlafend:

I2C-LCD-RTC 02

Der Strom ist nicht mehr messbar :) 

Categories:

[ [0] Kommentare ]

Den Arduino schlafen schicken und von der RealTimeClock wieder aufweckenFreitag, 10 April, 2015 11:07

Der Arduino soll ja mal mit Batterie laufen und deswegen (und überhaupt, nicht wahr?) sind stromsparende Zustände neben der Hauptfunktion ein zweiter Hauptfaktor in der Arduino Programmierung. Wie üblich waren durch Google bereits bekannt gewordene und auch neue Webseiten diesbezüglich auskunftsfreudig.

Dass es zuerst nicht klappen wollte, den Arduino wieder auf zu wecken - schlafen schicken ging ganz wunderbar und prompt, schien zunächst undurchsichtig zu sein. Aber auch hier hatten andere Leute dasselbe Problem und so kam ich der Ursache auf die Spur. - Meine naive Annahme, wenn ich die RTC anweise, den Interrupt zu aktivieren, mit dem sie den Arduino wieder aufwecken soll, dann funktionert das auch war falsch. Vorher putzen quasi muss schon sein :)

Und eine Seite stach aus allen anderen Seiten besonders hervor, weswegen ich sie gerne hier besonders erwähne:

Gammon Forum : Electronics : Microprozessors: Power saving techniques for microprozessors 

Und hier präsentiere ich mein Labor-Script, das funktioniert (Update, für das neue LED-Display und mit 2-stelligen Ausgaben überall :) ):

    
#include <LiquidCrystal_I2C.h>
#include <DS3232RTC.h> 
#include <Time.h>
#include <Wire.h>
#include <avr/sleep.h>
#include <avr/power.h>

// old LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int counter=0;
int pin2 = 2;

unsigned long(starttime)=2;
unsigned long(sleeptime)=1;

void setup()
{
  Serial.begin(9600);
  pinMode(pin2, INPUT); 
  lcd.begin(20, 4);
  lcd.setCursor(0,0);
  setSyncProvider(RTC.get);
  if(timeStatus() != timeSet) {
lcd.print("Unlucky - no RTC");
Serial.println("Unlucky - no RTC");
  }  
  else {
lcd.print("lucky - got RTC");
Serial.println("lucky - got RTC");
starttime=now();
sleeptime=starttime+30;
delay(2000);
  unsigned long alarmtime=sleeptime+30;
  Serial.print("Sleep time: ");
  SerialDigits(hour(sleeptime));
  Serial.print(":");
  SerialDigits(minute(sleeptime));
  Serial.print(":");
  SerialDigits(second(sleeptime));
  Serial.println("");
  Serial.print("Alarm time: ");
  SerialDigits(hour(alarmtime));
  Serial.print(":");
  SerialDigits(minute(alarmtime));
  Serial.print(":");
  SerialDigits(second(alarmtime));
  Serial.println("");
  RTC.squareWave(SQWAVE_NONE);
  RTC.alarm(1);
  RTC.alarm(2);
  RTC.alarmInterrupt(ALARM_1, true);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.setAlarm(ALM1_MATCH_HOURS, second(alarmtime), minute(alarmtime), hour(alarmtime), 0);
  Serial.println("Waiting for sleep");
  lcd.clear();
  } 
}

void loop(void)
{
  unsigned long(current)=now();
  unsigned long(soon)=current;
//  do {
 digitalClockDisplay();
//     delay(200);
 if ( (sleeptime > 1 ) and ( sleeptime = soon ) ) {
   enterSleep();
 }
//     soon=now();
//  } while ( soon  current +6);
//  do {
 digitalAlarmsDisplay();
 delay(200);
 if ( (sleeptime > 1 ) and ( sleeptime = soon ) ) {
   enterSleep();
 }
 soon=now();
//   } while ( soon   current +10);
}

void wake () {
 sleep_disable();
}
void enterSleep(void)
{
  lcd.setCursor(0,1);
  lcd.print("... entering sleep                ");
  lcd.setCursor(0,2);
  lcd.print("S1: ");
  LedDigits(hour(sleeptime));
  lcd.print(":");
  LedDigits(minute(sleeptime));
  lcd.print(":");
  LedDigits(second(sleeptime));
  lcd.setCursor(0,3);
  lcd.print("A1: ");
  LedHexes(RTC.readRTC(ALM1_HOURS));
  lcd.print(":");
  LedHexes(RTC.readRTC(ALM1_MINUTES));
  lcd.print(":");
  LedHexes(RTC.readRTC(ALM1_SECONDS));
  delay(2000);
  lcd.noBacklight();
  delay(2000);
  lcd.off();
  // disable ADC
  ADCSRA = 0;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  noInterrupts ();
  // This is triggered by interrupt
  attachInterrupt (0, wake, LOW);
  // turn off brown-out enable in software
  // turn on brown-out enable select
  MCUCR = bit (BODS) | bit (BODSE);
  // this must be done within 4 clock cycles of above
  MCUCR = bit (BODS);
  interrupts ();
  sleep_mode();
  
  /* After wake up continue from here. */
  
  detachInterrupt (0); 
  power_all_enable();
  lcd.on();
  sleeptime=1;
  setSyncProvider(RTC.get);
  RTC.alarmInterrupt(ALARM_1, false);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("..just woke up!!");
  delay(2000);
}

void setAlarmOnce() {
  unsigned long alarmtime=sleeptime+60;
  Serial.print("Sleep time: ");
  SerialDigits(hour(sleeptime));
  Serial.print(":");
  SerialDigits(minute(sleeptime));
  Serial.print(":");
  SerialDigits(second(sleeptime));
  Serial.println("");
  SerialDigits(hour(alarmtime));
  Serial.print(":");
  SerialDigits(minute(alarmtime));
  Serial.print(":");
  SerialDigits(second(alarmtime));
  Serial.println("");
}

void digitalClockDisplay(void)
{
  lcd.setCursor(0,0);
  LedDigits(hour());
  lcd.print(':');
  LedDigits(minute());
  lcd.print(':');
  LedDigits(second());
  lcd.print(' ');
  char tempF[6];
  int t = RTC.temperature();
  float celsius = t / 4.0;
  dtostrf(celsius, 5, 1, tempF);
  lcd.print(celsius);
  lcd.print((char)223);
  lcd.print('C');
  lcd.setCursor(0,1);
  LedDigits(day());
  lcd.print('.');
  LedDigits(month());
  lcd.print('.');
  lcd.print(year());
  lcd.print("  ");
}

void digitalAlarmsDisplay() {
lcd.setCursor(0,2);
lcd.print("S1: ");
LedDigits(hour(sleeptime));
lcd.print(":");
LedDigits(minute(sleeptime));
lcd.print(":");
LedDigits(second(sleeptime));
lcd.setCursor(0,3);
lcd.print("A1: ");
LedHexes(RTC.readRTC(ALM1_HOURS));
lcd.print(":");
LedHexes(RTC.readRTC(ALM1_MINUTES));
lcd.print(":");
LedHexes(RTC.readRTC(ALM1_SECONDS));
lcd.print("       ");

}

void LedDigits (int digits)
{
  if(digits < 10)
lcd.print('0');
  lcd.print(digits);
}

void SerialDigits (int digits)
{
  if(digits < 10)
Serial.print('0');
  Serial.print(digits);
}

void LedHexes (int digits)
{
  if(digits < 16)
lcd.print('0');
  lcd.print(digits, HEX);
}

Etwas lang geworden :)

Categories:

[ [0] Kommentare ]

Script fur das Arduino RTCpro ModulMittwoch, 08 April, 2015 10:36

Das Folgende betrifft Arduino, eine RTC und die Umgebung ist Linux, deswegen ist es für Windows völlig nutzlos, leider.

Meine batteriegepufferte, temperaturgesteuerte Realtimeclock für den Arduino hat beim Umstecken iwie ihre Pufferung verloren und ich musste sie neu programmieren. Welche Libraries man braucht gibt es bei Adafruit, Instructables und auch anderswo zu finden. Was man auch braucht, ist die Time-Library . Und mit der kann man die Uhr (neu) programmieren. Dazu braucht man den Unixtimestamp der gewünschten Zeit und setzt ein T davor, z. B. T1428486102 für den Mi 8. Apr 09:42:27 2015 und das wird einfach über die serielle Schnittstelle zum Arduino ausgegeben. Das kann man aus der Arduino IDE oder über minicom z. B. machen - oder einfach als echo nach /dev/ttyUSB0 umleiten :)

Aber die Arduino IDE und minicom können beide keine Zeitberechnungen oder gar den Unixtimestamp ausgeben. Und weil der frisch ausgeben von date auch nicht instant verwendet werden kann, habe ich mir mal ein kleines Script gebastelt:

    
#!/bin/sh
NOW=$(date +"%s")
# wintertime
#SOON=$(( $NOW + 3601 ))
# summertime
SOON=$(( $NOW + 7201 ))
echo "Now is $NOW which is:"
date --date="@$NOW"
echo "RTC will be set to T$SOON which is:"
date --date="@$SOON"
echo -e "T$SOON\n">/dev/ttyUSB0

Es ermittelt die gegenwärtige Zeit, passt den Zeitstempel für die Uhr und einen Übertragungszeitraum an, informiert auf der Shell und gibt das gewünschte Ergebnis direkt an der seriellen Schnittstelle aus, ganz so, wie es TimeRTCSet.ino erwartet. Es ist vorbereitet, normale Zeit statt Sommerzeit aufzubereiten und wenn die serielle Schnittstelle woanders ist, muss man das auch im Script anpassen. Ist schnell und schmutzig, ich weiß. Ein schnell mal eben gemachtes Werkzeug, mehr nicht.

Categories: Elektronik, Hardware, Programmierung, Selbstgemacht

[ [0] Kommentare ]

Mein erster Ausflug mit dem Arduino und dem DFRobot LCD Keypad shieldSamstag, 27 Dezember, 2014 17:37

Meine neue Spielwiese sollte der Arduino sein.

Mit Scripting und etwas Programmieren am Computer war ich ja schon vertraut und kam schnell auf die Idee, dass so eine Mikroprozessor-Programmierung ohne Display und Tatatur an der CPU recht uninformiert aufallen könnte. - Mein erster Ausflug sollte also gleich eine Textausgabe und eine Eingabemöglich am Gerät haben, auch wenn ich inzwischen schon bemerkt hatte, dass das Android SDK durchaus eine Wiedergabe der seriellen Konsole vom Arduino hat.

Deswegen hatte ich mir das DFRobot LCD Keypad für den Arduino gekauft, das ein blaues, beleuchtetes Display mit weißer Schrift und 6 Tasten für select, Cursorsteuerung und Reset bietet.

Aprops Arduino, ich hatte mir gekauft den Arduino Pro Mini, den Arduino Funduino, sowie den Arduino Nano gleich doppelt oder auch dreifach, Elektronik raucht schnell mal ab beim Entwickeln, dachte ich mir und die Preise sind ja echt günstig.

Bisher ist alles gut verlaufen :)

Wie man nun anfängt? Nun, ein Vergleich mit Windows und Linux hat mir gezeigt, dass es besser ist, mit Linux zu programmieren, was daran liegt, dass das Hochladen von Software bei Windows nicht geht, wenn der Arduinio am Programmierer oder sofern es geht, am USB-Kabel angeschlossen nicht erkannt wird. Das ist bei Linux kein Problem.

Ein Tip, den ich nach Fehlermeldungen am Windowscomputer beim Hochladen hatte und so nicht als Lösung im Internet gefunden habe:

Programmieren geht am Besten mit nackigen Arduino! Also nicht am Steckbrett, wo er noch mit anderen Modulen verbunden ist!!!

Ein oder mehrere Steckbretter mit kurzen und langen Steckkabeln gibt die Möglichkeit, Module mit dem Arduino zu verbinden, ohne dass man löten muss. Für Arduino geeignete Seriell-zu-USB Module, FTDI basiert, um Arduinos die keinen USB-Anschluss haben verbinden zu können. Geeignete USB-Kabel.

Das Problem auf das ich stieß, als ich das LCD am Arduino anschließen wollte, war, dass ich (natürlich) keine Webseiten fand, die die Verdrahtung ganz genau zeigten. Dokumente, die zeigten, dass man das LCD prima auf den Arduino Uno stecken konnte waren zunächst nicht so die richtige Hilfe... später, als ich mir die PIN-Schematics vom Arduino UNO reingezogen hatte, war alles klar.

Ich habe mal das PIN-Layout des LCD von einer meiner Funde mit XCircuit nachgezeichnet, hier ist es:

-die Anschlüsse, die man braucht, sind alle angehakt. Das ist auf der unteren Seite bei den Buttons Reset, 5V, Ground sowie A0 und auf der Oberseite D4-D9 und D10. Und ja, D11 MOSI ~ ist mir auf dem Bild wohl verloren gegangen und ich hab's zu spät gemerkt. Egal, brauchen wir hier ja nicht :)

Auch nicht unbedingt braucht man Reset und D10 für Backlight Control. Verbunden wird mit dem Arduino 1:1, d.h. LCD D4 geht auf Arduino D4, LCD D5 auf Arduino D5 usw., LCD 5V (Input) geht auf Arduino 5V (Output), GND auf GND und A0 auf A0. Ging bei meinem Funduino ohne weitere Maßnahmen.

Ein Sketch von DFRobot hat mir gut gefallen und modifiziert hatte ich es, weil ich wohl ein LCD V1.0 Board habe und weil ich wissen wollte, wie der Reset arbeitet und wie es ohne Backlight aussieht.

So sieht "der Gerät" aus:

Und so das modifzierte Sketch:

//Sample using LiquidCrystal library
#include <liquidcrystal.h>

/*******************************************************

This program will test the LCD panel and the buttons
Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
#define backLight 10

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor 
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 // For V1.1 us this threshold
/*
if (adc_key_in  50)   return btnRIGHT;  
 if (adc_key_in  250)  return btnUP; 
 if (adc_key_in  450)  return btnDOWN; 
 if (adc_key_in  650)  return btnLEFT; 
 if (adc_key_in  850)  return btnSELECT;  
*/
 // For V1.0 comment the other threshold and use the one below:

 if (adc_key_in  50)   return btnRIGHT;  
 if (adc_key_in  195)  return btnUP; 
 if (adc_key_in  380)  return btnDOWN; 
 if (adc_key_in  555)  return btnLEFT; 
 if (adc_key_in  790)  return btnSELECT;   



 return btnNONE;  // when all others fail, return this...
}

void setup()
{
 lcd.begin(16, 2);              // start the library
 lcd.setCursor(0,0);
 lcd.print("Push the buttons"); // print a simple message
}
 
void loop()
{
 lcd.setCursor(9,1);            // move cursor to second line "1" and 9 spaces over
 lcd.print(millis()/1000);      // display seconds elapsed since power-up


 lcd.setCursor(0,1);            // move to the begining of the second line
 lcd_key = read_LCD_buttons();  // read the buttons

  switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
 {
 lcd.print("RIGHT ");
 break;
 }
   case btnLEFT:
 {
 lcd.print("LEFT   ");
 break;
 }
   case btnUP:
 {
 lcd.print("UP    ");
 pinMode(backLight, OUTPUT);  // Backlight off
 break;
 }
   case btnDOWN:
 {
 lcd.print("DOWN  ");
 pinMode(backLight, INPUT);  // Backlight on
 break;
 }
   case btnSELECT:
 {
 lcd.print("SELECT");
 break;
 }
 case btnNONE:
 {
 lcd.print("NONE  ");
 break;
 }
 }

}  
  

Der Reset am LCD bewirkt ein Reset am Arduino, ist das Backlight aus (Cursor up, wieder an mit Cursor down), braucht man ein gut ausgeleuchtetes Display, um etwas lesen zu können. Aber vielleicht kann man ja die Darstellung invertieren und ich finde das noch irgendwann heraus.

Und jetzt geht es erst richtig los mit der Mikroprozessor-Programmierung XD

Categories: Elektronik, Hardware, Programmierung, Selbstgemacht, Software

[ [0] Kommentare ]