2017年7月3日 星期一

數位電視的 channels.conf (2017年版)

Linux 上實際做法可以參考這篇 : https://blog.gtwang.org/iot/raspberry-pi-dvb-usb-tv-stick/

但2017的現在, 我發現 scan  只能掃到 5690000 那個頻道 (公視3, 客家, 原民), 看了一下 tw-all 那個檔案, 裏面只有 569000 用 QAM_64, 其它用 QAM_16, 鑑於公視HD是最早的HD台, 我猜, 這 tw-all 太舊了, 把所有的頻率都改成 QAM_64 就都抓到了

....連帶, 我正在寫的 EPG 程式也自動 OK 了, 原來都是這個 QAM 惹的視


 channels.conf : (有+號的是雙語, 好像有些軟體不接受+號 )
中視:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1002+1003:100
中視新聞台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1011:1012:101
中視經典台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1021:1022:102
BRAVO經典台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1031:1032:103
公視:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2011:2012+2013:201
公視2台:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2021:2022+2023:202
民視:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3001:3002+3003:300
交通電視台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3011:3012:301
民視新聞台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3021:3022:302
民視台灣台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3041:3042:304
台視:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4001:4002+4003:400
台視新聞台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4011:4012:401
台視財經台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4021:4022:402
台視綜合台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4031:4032:403
華視:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5011:5012+5013:501
教育文化台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5021:5022:502
華視新聞台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5031:5032:503
國會頻道:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5041:5042:504

2017年6月24日 星期六

Ubuntu 16.04 64bit install

已經安裝過 32bit 的, 本來以為很快才對, 不過還是有些問題

1. Static IP
     社區網路的天兵工程師當初因為不會設定 Ubuntu, 乾脆直接鎖 Mac address, 好在當時我立刻抗議, 他給了我另一個 IP -> 其實我只付一個 IP 的錢, 結果我有了兩個 IP 可用
    但現在換主機板, 也就是換了網卡, 所以其中那個鎖 Mac address 不能用了, 得用目前 RPI3 佔用的那個 IP
   But, 平平是 Ubuntu Mate, 怎麼 IP 設定的方法和 RPI3 不同呢? 頭痛~~
   最後居然是最簡單的 UI 版 Networkmanager 就可以了

   2017/07/04 補記 : 發現原來 Mac address 可以改的 !
  /etc/network/interfaces:
    auto enp0xxx
     iface enp0xxx inet dhcp
         hwaddress ether  xx:xx:xx:xx

2.  HiChannel -> 想了好一會想才起來 : 要裝 flash-plugin

3. gcin 因為光碟安裝時沒有網路, 所以語言包沒裝好, 裝了 gcin 之後一直無法中文輸入, 後來是去地區/語言選項時, 才發現裝了語言包之後, 一切就好了

4. dconf-editor
     不喜歡的行為要改掉 : 1. automount-open 2.  side-by-side tiling(?)

5. chrome (for Line app)要求的keyring 要設空白, 不然每次都要輸入 (夠白痴的)

6. 啟動應用程式移除 blueman-serive, 不然明明沒有藍芽, 還要show個 icon

7. 用 QT5 寫的 vbook 不能用了, 得重 compile
     -> 安裝 QT5.5,  qmake, make

8. pcmanx 要裝 ttf-mscorefonts 才有慣用字型

9. 電視遙控器不能用!  python decode 的程式改了半天才能用, 但接收力比舊機器弱很多 -> 為什麼呢 ?

10. 新發現一個 command : acpi_listen 可以監測耳麥插拔, 因為本來懷疑原價屋小哥接錯了~~

11. crontab 裏 mplayer 需要 > /dev/null 2>&1

12. virtualbox 裏裝 additional 才有 sharefolder 可用
      apt install virtualbox-guest-utils
      加 user 進 vboxfs group (/etc/group)

   

買新電腦啦

全都是為了 Android Studio! 2.3.3 在 32bit 上可以 install, 可以執行, 但有一堆奇怪的 error message

而那台老舊的 CP5141, 雖然號稱可以裝 64bit, 但 Ubuntu 16.04 64bit 光碟總是跑到一半就 Hang, 本想加個RAM 就好, 但, 一時腦熱....

花了近七千在原價屋裝了台不含硬碟的新電腦, G4600 + H110M ECO, 第一次用微星的主機板呢, 沒辦法, 有 D-SUB + HDMI 的主機板, 最便宜就它了

在 pc_shopping 上 G4600 評價很好, H110M ECO 也有人稱讚, 雖然 pc_shopping 讀起來老覺得有人在帶風向, 不過找了外國的文章, 也還都不錯

尤其在 Amazon 上有一則說 H110M ECO is great for Linux !

和 CP5141 相比, 這台機殼還是太高, 要躺下來放,  然後和 CPU 風扇看起來很兩光, 是 G4600 附的? CP5141 的 ASUS 風扇看起來強壯些

拿回來裝硬碟時, 怎麼看都會被 RAM 擋住, 心裏詛咒了原價屋 N 次後, 才發現, 原來機殼有個和光碟機一樣的擋板可拆, 要從外面插進來才對...., 原來是我太蠢, 原價屋的小哥好冤

稍微看了一下影片, 感覺有點改善, 不過, 舊機器其實也夠用了, 就是愛亂花錢啊, 寫什麼 Android app 呢

2016年11月15日 星期二

RPI3's lirc

refer to : http://ozzmaker.com/how-to-control-the-gpio-on-a-raspberry-pi-with-an-ir-remote/

hardward : 1838B 接 GPIO, 3.3V, GND, PIN18

Software :
1. sudo apt-get install lirc liblircclient-dev
2. 在 /etc/modules 裏加兩行
   lirc_dev
   lirc_rpi gpio_in_pin=18
3. 改 /etc/lirc/hardware.conf
   DEVICE="/dev/lirc0"
   MODULES="lirc_rpi"
4.  reboot, 理論上應該 lircd 會自動起來, 但並沒有
5. 用mode2 測試硬體
    sudo /etc/init.d/lirc stop  ( 沒有這個也無妨, 因為 service 沒設好? )
    mode2 -d /dev/lirc0
6. irrecord --disable-namespace -d /dev/lirc0 lircd.conf
    錄試遙控器的 key, 要加 --disable-namespace 才能隨便給名字
    錄好後 copy 到 /etc/lirc/lircd.conf
7. 手動起 lircd -d /dev/lirc0 
    這是試出來的, 沒有手動起這個 irw 會說 connect fail, 
    而沒有用 -d 指定 /dev/lirc0 的話, irw 沒反應
8. 用 irw 試,  它會印 lircd.conf 出按鍵的名字
9. 原文的程式會去讀 /root/lircrc 或 /etc/lirc/lirc/lircrc 
    可以在 readconfig 那裏改 path, 但之後的 irexe 不知怎麼指定 path, 
    所以還是建了 /etc/lirc/lirc/lircrc
    那程式只是做了和 irw 類似的事
10. 設定 lircrc
    begin
        button = power
        prog   = irexec
        repeat = 1
        config = /home/pi/autoplay/starttv1.sh
    end
   起 irexe, 它就會依遙控器的 button, 去執行 config 那行


2016年7月8日 星期五

手染

黃連: 無媒染呈黃色,明礬媒染呈褐黃。染材不需多,煮開後浸十分鐘即可
檳榔:新鮮嫩果搗出汁加水煮,無媒染呈棗紅
地瓜葉:加鹽

簡單自製雲端家電

家附近的全國電子一直在播那個什麼"涼de等"的廣告, 每次去買菜都要被轟一次, 煩得很, 不過因為最近閒閒在家玩 DIY, 所以忍不住會想: 這自己做應該不難吧?

一個很簡單的設想: 1. 在外面寄e-mail回家 2.家裏的PC收到e-mail後照著信件標題的指示送個遙控訊號給冷氣機.

好像很簡單.

所以, 首先要在電腦裏存著各個家電的遙控訊號, 然後能發送它!
還是依照 mobile01 這篇文 http://www.mobile01.com/topicdetail.php?f=383&t=2845603
做出來的, 但是, 我的方法簡單多了

所需硬體 :
0. 電腦一台 (有耳機孔和麥克風孔即可, 老舊電腦應該都夠用)
1. 沒在用的音源線一條
2. 小吃店帶回來的塑膠繩一條 ( 不然縫衣線應該也可以)
3. 紅外線接收器1838B 38Khz 一顆 ( 10~30 元)
4. 5mm紅外線發射管 940nm LED 兩顆 (不到 10 元, 聽說 5mm 比 3mm 夠力, 只是聽說 )



做法 :
1. 把 音源線剪半, 剝成這樣 (紅白皮要剝掉一些, 冒出芯, 才能和 LED 連接)


2. 接收器 : 接收器外側兩支腳分別連上上圖的紅白線,  中間那支腳連上那條裸線
    發射器 : 取發射器的一支長腳和另一個的短腳連上紅線, 白線就連另外的長短腳. (注意:兩顆LED 要盡量肩并肩平行)
    從塑膠繩上撕下幾條細絲綁好,  成品長這樣 :


3. 接收器插上電腦的麥克風接頭, 發射器插進耳機孔, 硬體部份就完成了

軟體部份我寫了一支小程式 , 可以把收錄音訊直接轉為發射器可用的 wav 檔, 所以不需要像 mobile01 上那篇動用到 Audacity, 程式在此, 是個文字檔
https://gist.github.com/xvwang/5b441d1f9360b8ec067a24a04bbc904c

但要執行這個小程式需要安裝 python2.7, pyaudio 和 numpy
python2.7 下載頁 : https://www.python.org/downloads/release/python-2712/
後兩個最簡單的安裝方法是先裝 python package installer, 方法可以參考這篇 :
http://coopermaa2nd.blogspot.tw/2012/12/easyinstall-pip.html
有了pip 之後, 用 pip install pyaudio numpy 就 OK 了

軟體都裝好後, 執行
python recordSendIRWav.py
它會要你輸入按鍵名稱, 輸入一個名字按一個搖控器的鍵, (主要應該是開關鍵吧), 最好用英文, 因為我的程式沒用中文測過. 最後按 q 離開
注意, 我這程式會一直等到有錄到訊號為止, 如果按了搖控器, 它一直不出現再次要你輸入按鍵名稱的提示行, 那, 可能你的接收器失敗了....

之後會得到一堆 wav 檔, 用任一個播放器音量開到最大由耳機放播出來, 看看看被遙控的電器有沒有反應.
這裏有幾點要注意.
1. 音量先調到最大試試, 我在這點上被打敗了近一個月
2. 耳機孔的功率不大, 所以這個發射器的有效距離很有限, 我是接上音源延長線到處試, 最後決定我這個發射器的有效距離是 50~70cm (各電器不同)
3. 我在 Linux 用 mpv 可以指定由耳機孔播放, 但在 Window 上我就不知道該怎麼辦, 只好把外接喇叭 disable 掉, 才試成功的
4. 可能可以用手機播來試試, 因為手機上也有耳機孔, 但我的 Xperia J 行不通, 我看到有網友說他家三支手機只有一支可以用, 而且有效距離還只有 20 cm
5. 所以, 如果你要遙控的電器比較遠, 要嘛像我用音源延長線, 要嘛試著製作使用電池的發射器 :  http://swf.com.tw/?p=359 (有空我也會試, 成功的話再來 update)

最後就簡單了,  我寫了個小程式, 每十分鐘去檢查一下e-mail, 只要標題合規格的, 就播放一下相對的 wav.

例如 :
1. 執行 python sendIRThroughEmail.py keyword_of_today
2. 送 email 到信箱裏, 標題為 "keyword_of_today cooler_power" 開/關冷氣

注意 :
1. 這支程式裏要改成你自己的 mail-server, mail-id 和 password
2. 我用 mpv 指定由耳機播放,  在 window 上可以用 wmplayer (PATH 要設好), 但不知怎麼從耳機播...
mpv --audio-device=help 可以列出所以可用的播放硬體
3. wav 檔記得要放在執行目錄之下

sendIRThroughEmail.py 在這裏 :
https://gist.github.com/xvwang/f9e57b324085d7a3293a193e67b11643

2016年6月28日 星期二

遙控電腦的 python code

========= homeirctl.py =============================

from ctypes import *
from array import array
from struct import pack

import pyaudio
import codeset
import subprocess
import signal, sys

THRESHOLD = 2000
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 38000

ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
  pass

def record():
    """
    Record a word or words from the microphone and
    return the data as an array of signed shorts.

    """
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT, channels=2, rate=RATE,
        input=True, output=True,
        frames_per_buffer=CHUNK_SIZE)

    num_silent = 0
    rcv_started = False

    r = array('h')

    while 1:
        rcv_data = array('h', stream.read(CHUNK_SIZE))
        rcv_data = [ (x>THRESHOLD) for x in rcv_data ]
        silent = (sum(rcv_data) < 10 )

        if silent and rcv_started:
          num_silent += 1
        elif not silent and not rcv_started:
          rcv_started = True

        if rcv_started :
          r.extend(rcv_data)

        if rcv_started and num_silent > 2:
          break

    stream.stop_stream()
    stream.close()
    p.terminate()
    return r

def to_bit(data) :
    sumData = []
    pN = 0
    nN = 0
    started = False
    for j in data :
      if j :
        pN = pN + 1
        if pN > 10 :
          started = True
        if nN < -10 :
          sumData.append(nN)
          nN = 0
      elif started :
        nN = nN - 1
        if pN > 10 :
          sumData.append(pN)
          pN = 0
    if pN > 10 :
      sumData.append(pN)
    if started and (nN < -10) :
      sumData.append(nN)

    result = ''
    started = False

    it =  iter(sumData)
    for x1 in it :
      try:
        x = x1 + next(it)
      except:
        break

      if x1>120 :
        result = ''
      elif x < -300 or len(result)>50:
        break
      elif x < -90:
        result = result + '1'
      else:
        result = result + '0'

    return result

def sigterm_handler(_signo, _stack_frame):
    sys.exit(0)

def main() :

  while True:
    data = record()
    signal = to_bit(data)
    try:
      buttonName = codeset.TVCODE[signal]
      print(buttonName)
    except:
      print(signal,'key not found')
    else:
      if buttonName is 'red' :
        subprocess.call("/home/viola/autoplay/starttv.sh", shell=True)
      elif buttonName is 'green' :
        subprocess.call("/home/viola/autoplay/starttvnews2.sh", shell=True)
      elif buttonName is 'yellow' :
        subprocess.call("/home/viola/autoplay/starttvnews3.sh", shell=True)
      elif buttonName is 'blue' :
        subprocess.call("/home/viola/autoplay/starttvnews1.sh", shell=True)
      elif buttonName is 'stop' :
        subprocess.call("/home/viola/autoplay/stopall.sh", shell=True)
        subprocess.call('xrandr --output VGA1 --mode 1440x900 --output HDMI1 --off', shell=True)
      elif buttonName is 'option' :
        subprocess.call("/home/viola/autoplay/startmusic.sh", shell=True)
      elif buttonName is 'soundtrack' :
        subprocess.call('xdotool search --name " - mpv" key s', shell=True)
      elif buttonName is 'soundpattern' :
        subprocess.call('xdotool search --name " - mpv" key A', shell=True)
      elif buttonName is 'speedup' :
        subprocess.call('xdotool search --name " - mpv" key Right', shell=True)
      elif buttonName is 'speeddown' :
        subprocess.call('xdotool search --name " - mpv" key Left', shell=True)
      elif buttonName is 'pauseplay' :
        subprocess.call('xdotool search --name " - mpv" key space', shell=True)
      elif buttonName is 'stepf' :
        subprocess.call('xdotool search --name " - mpv" key n', shell=True)
      elif buttonName is 'stepb' :
        subprocess.call('xdotool search --name " - mpv" key b', shell=True)
      elif buttonName is 'vup' :
        subprocess.call('xdotool search --name "playing music" key bracketright', shell=True)
      elif buttonName is 'vdown' :
        subprocess.call('xdotool search --name "playing music" key bracketleft', shell=True)
      elif buttonName is 'cursorU' :
        subprocess.call('xdotool search --name "playing music" key N', shell=True)
      elif buttonName is 'cursorD' :
        subprocess.call('xdotool search --name "playing music" key B', shell=True)
      elif buttonName is 'cursorL' :
        subprocess.call('xdotool key XF86AudioLowerVolume', shell=True)
      elif buttonName is 'cursorR' :
        subprocess.call('xdotool key XF86AudioRaiseVolume', shell=True)
      elif buttonName is 'mute' :
        subprocess.call('xdotool key XF86AudioMute', shell=True)
      elif buttonName is 'epg' :
        subprocess.call('chromium-browser --app="http://hichannel.hinet.net/radio/mobile/index.do?id=205#"', shell=True)
      elif buttonName is '3D' :
        subprocess.call("/home/viola/autoplay/startplaying.sh", shell=True)
      elif buttonName is 'information' :
        subprocess.call('xdotool search --name " - mpv" key t', shell=True)
      elif len(buttonName)==1 :
        subprocess.call('xdotool search --name " - mpv" key '+buttonName, shell=True)

if __name__ == '__main__':
  signal.signal(signal.SIGTERM, sigterm_handler)
  signal.signal(signal.SIGINT, sigterm_handler)

  c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
  asound = cdll.LoadLibrary('libasound.so')
  asound.snd_lib_error_set_handler(c_error_handler)

  main()

========== codeset.py ====================
TVCODE = {
'111111110001000000001110':'red',
'111111011101000000100010':'green',
'111111000111000000111000':'yellow',
'111111100111000000011000':'blue',
'111111111010000000000101':'pauseplay',
'111111101110000000010001':'speedup',
'111111010110000000101001':'speeddown',
'111111100011000000011100':'stop',
'101101110010010100001101':'stepf',
'101101010010010100101101':'stepb',
'111111010010000000101101':'option',
'111111011000000000100111':'vup',
'111111111000000000000111':'vdown',
'111111100000000000011111':'power',
'111111000110000000111001':'soundtrack',
'111111100110000000011001':'soundpattern',
'111111101000000000010111':'mute',
'111111110000000000001111':'information',
'111111010111000000101000':'epg',
'111111011001000000100110':'return',
'111111100101000000011010':'OK',
'101101101110010100010001':'3D',
'111111101101000000010010':'cursorR',
'111111001101000000110010':'cursorL',
'111111110101000000001010':'cursorU',
'111111010101000000101010':'cursorD',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111100100000000011011':'3',
'111111010100000000101011':'4',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111010100000000101011':'3',
'111111110100000000001011':'4',
'111111001100000000110011':'5',
'111111101100000000010011':'6',
'111111011100000000100011':'7',
'111111111100000000000011':'8',
'111111000010000000111101':'9',
'111111100010000000011101':'0' }

============= recordWavToFile.py =====================
import pyaudio
import wave
import numpy
from array import array

FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 38000
CHUNK = 1024
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "file.wav"

audio = pyaudio.PyAudio()

# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
                rate=RATE, input=True,
                frames_per_buffer=CHUNK)
print "recording..."
frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)
print "finished recording"


# stop Recording
stream.stop_stream()
stream.close()
audio.terminate()

waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()

================ drawWavPlot.py ====================
from scipy.io import wavfile
from matplotlib import pyplot as plt
import numpy as np

# Load the data and calculate the time of each sample
samplerate, data = wavfile.read('file.wav')
print data
times = np.arange(len(data))/float(samplerate)

# Make the plot
# You can tweak the figsize (width, height) in inches
plt.figure(figsize=(20, 4))
plt.fill_between(times, data[:,0], data[:,1])
plt.xlim(times[0], times[-1])
plt.xlabel('time (s)')
plt.ylabel('amplitude')
#You can set the format by changing the extension
#like .pdf, .svg, .eps
plt.savefig('plot.png', dpi=100)
plt.show()