2013-07-26 1 views
1

У меня есть регистр байтов размером 56 байтов на каком-то eeprom, который я бы хотел хранить с часами двигателя. В настоящее время я просто использую 3 байта, чтобы увеличить таймер 60 секунд, а затем загрузить информацию (число редко превышает 9999 минут до ее передачи).56 байтов и 99 проблем, связанных с датой и номером

Проблема в том, что мне нужно связать дату с этим. Каждый раз, когда автомобиль запускается, мне нужно начать запись своих часов, но мне нужно определить, в какой час этот час был увеличен.

Итак, если у меня есть массив байтов [56], каким будет самый простой способ сохранить дату (или только час даты), а затем число и сможете рассказать об этом отдельно?

Для передачи мне понадобится способ итерации по массиву и извлечение даты или часа, а также счет часов.

Любые идеи для этого были бы замечательными, спасибо тонну.

Конечные результаты по отчету будет выглядеть примерно так:

06:00 - 38 минут 9:00 - 60 минут 10:00 - 60 минут т.д.

+0

56 байт - это много места ... вам просто нужно придумать представление какой-то формы –

+0

Это то, что я хотел бы, можете ли вы подумать об этом? Я новичок в этом типе эффективности ... –

+0

Взгляните на статью msdn, которую я только что опубликовал в своем ответе в разделе «ОБНОВЛЕНИЕ» –

ответ

1

Okay здесь идея схему для размещения всех данных, которые вам нужны в ваших 56 байтах (на самом деле мы можем вместить до 11 дат и времени в 56 байт):

Предполагая, что вы не ожидаете, что эта система продлится более тысячи лет, мы можем определить первую часть года, то есть 2013 год делится на две, эпоху и год.

  • Эпоха: 5 бит (или один байт), что позволяет 0-31
  • Год: 7 бит (или один байт), что позволяет 0-99
  • день: 9 битов (два байта), позволяющие 0-365
  • час: 5 бит (один байт), что позволяет 0-24
  • Второе: 12bits (два байта), что позволяет 0-3600

Теперь вы можете просто использовать 7 байт и увеличиваем значения каждого и будет позволяют хранить до 8 дат и времени, но вы могли бы создать структуру и бит бит отдельные биты, чтобы скомбинировать его далее, позволяя вам втиснуть его в 40 бит (или 5 байтов), имея 11 дат.

Вы также можете отказаться от эпохи, если вы действительно зубрежки, но выше схема позволит вам работать с датами ДО 3199.

Я уверен, что есть другие, более компактные способы, т.е. количество миллисекунд, прошедших с 01.01. 1970, чтобы сказать, что несколько лет в будущем могут сократить его на несколько бит, но уменьшить долговечность вашего кода, но я не видел реальных значений.

Некоторые примеры кода (Были обновлены для использования в качестве BitArray BOOL внутренне байт (?!), но на самом деле BitArray бит ... Очень важно в OPS случае .:

OP следует отметить, что я считаю, вы хотите сохранить количество минут, приводимых в каждый час, но тогда потребуется намного больше места (запись за каждый час, в который они вошли, или начало и остановка записи за каждый день с указанием минуты их начала и остановки (остановка должна наступить после начала после).Приведенный ниже код позволит вам записать, сколько минут было проведено в определенный день.

using System; 
using System.Collections; 

namespace BitBangingDate 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CompactDateManipulator x = new CompactDateManipulator(); 
      Console.WriteLine(x.ToString()); 
      x.Month = 7; 
      x.Day = 27; 
      x.Minute = 1234; 
      Console.WriteLine(x.ToString()); 

      var bitArr = x.GetCompactedArray(); 

      CompactDateManipulator x1 = new CompactDateManipulator();//create new blank date to test whether can be reiitialised from BitArray 

      x1.ReinitialiseDateFromBitArray(bitArr); 

      Console.WriteLine(x1.ToString()); 
     } 
    } 

    class CompactDateManipulator 
    { 
     CompactDate _date = new CompactDate(); 

     public int Month 
     { 
      get 
      { 
       return BoolArrayToInt(_date.month); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.month, value); 
      } 
     } 
     public int Day 
     { 
      get 
      { 
       return BoolArrayToInt(_date.day); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.day, value); 
      } 
     } 
     public int Minute 
     { 
      get 
      { 
       return BoolArrayToInt(_date.minute); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.minute, value); 
      } 
     } 

     public BitArray GetCompactedArray() 
     { 
      return _date.GetFullArray(); 
     } 

     public void ReinitialiseDateFromBitArray(BitArray arr) 
     { 
      _date.SetDate(arr); 
     } 

     //utility methods 
     void IntToBoolArray(ref bool[] bits, int input) 
     { 
      var len = bits.Length; 
      for (int i = 0; i < len; i++) 
      { 
       bits[i] = (input & 1) == 1 ? true : false; 
       input >>= 1; 
      } 
     } 
     int BoolArrayToInt(bool[] bits) 
     { 
      if (bits.Length > 32) throw new ArgumentException("Can only fit 32 bits in a int"); 
      int r = 0; 
      for (int i = 0; i < bits.Length; i++) 
      { 
       if (bits[i]) r |= 1 << i; 
      } 
      return r; 
     } 
     public override string ToString() 
     { 
      return String.Format("Stored Date mm/dd/ss: {0}/{1}/{2}", Month, Day, Minute); 
     } 
    } 

    class CompactDate 
    { 
     //Layout Month(5) Day(9)  Minute (12) 
     //  11111  111111111 111111111111 
     public bool[] month = new bool[5]; 
     public bool[] day = new bool[9]; 
     public bool[] minute = new bool[12]; 
     public BitArray GetFullArray() 
     { 
      int fullLen = month.Length + day.Length + minute.Length; 
      BitArray full = new BitArray(fullLen); 
      int index = 0; 
      for (int i = 0; i < month.Length; i++,index++) 
      { 
       full.Set(index,month[i]); 
      } 
      for (int i = 0; i < day.Length; i++, index++) 
      { 
       full.Set(index, day[i]); 
      } 
      for (int i = 0; i < minute.Length; i++, index++) 
      { 
       full.Set(index, minute[i]); 
      } 
      return full; 
     } 
     public void SetDate(BitArray arr) 
     { 
      int index = 0; 
      for (int i = 0; i < month.Length; i++, index++) 
      { 
       month[i] = arr.Get(index); 
      } 
      for (int i = 0; i < day.Length; i++, index++) 
      { 
       day[i] = arr.Get(index); 
      } 
      for (int i = 0; i < minute.Length; i++, index++) 
      { 
       minute[i] = arr.Get(index); 
      } 
     } 
    } 
} 
+0

Я не думаю, что нужно хранить всю дату. Мне нужен только день, час и количество накопленных в нем минут. Самое лучшее, что я имею до сих пор, - это использовать только День и Час, и на это рассчитывают минуты. Что-то вроде log [0] = 913 (09-й день, 13-й час - 3 байта), log [1] = 56 (56 минут для 13-го часа - 1 байт). Тогда log [2] = 914, log [3] = 10 и т. Д. Это все еще слишком неэффективно, потому что это означает, что я буду использовать 4 байта за каждый час, что оставляет мне 14 часов для хранения данных. Мне нужно, по крайней мере, пару дней. Я собираюсь сделать это неправильно? –

+0

см. Обновление для того, как закодировать биты. Мы можем хранить все время в 26 бит (4 байта) –

+0

В «День» вы имеете в виду день года или день месяца (один требует 9 бит других 4) –

0

Вы могли бы представлять время начала использования минут в случае, если она не запускается в точном час, поэтому 24x60 = 1440 является наибольшим числом вы должны учитывать в момент запуска. 1440, представленный в двоичном формате, - 0000010110100000 (2 байта), поэтому первые элементы 0-1 массива представляют время начала. Затем вы говорите, что 9999 минут является приемлемым верхним пределом времени выполнения, который в двоичном формате равен 0010011100001111 (2 байта), поэтому элементы массива 2-3 представляют собой время выполнения.

Смежные вопросы